00001 /* -*- coding:utf-8 -*- 00002 Copyright (c) 2009, Fixstars Corporation 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, 00006 are permitted provided that the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, 00009 this list of conditions and the following disclaimer. 00010 00011 * Redistributions in binary form must reproduce the above copyright notice, 00012 this list of conditions and the following disclaimer in the documentation 00013 and/or other materials provided with the distribution. 00014 00015 * Neither the name of Fixstars Corporation nor the names of its contributors 00016 may be used to endorse or promote products derived from this software 00017 without specific prior written permission. 00018 00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00022 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00023 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00026 AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 00028 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 00036 #include "ctrump/ast/ast.h" 00037 #include <stdlib.h> 00038 00045 int 00046 ctrump_ast_fold_const_sint(const struct ctrump_expr *expr, int *is_const) 00047 { 00048 tailcall: 00049 switch (expr->code) { 00050 case CTRUMP_EXPR_SINT_LITERAL: 00051 *is_const = 1; 00052 return expr->u.sint_literal.value; 00053 00054 case CTRUMP_EXPR_PAREN: 00055 expr = expr->u.paren.expr; 00056 goto tailcall; 00057 00058 default: 00059 /* unimplemented */ 00060 *is_const = 0; 00061 break; 00062 } 00063 00064 return 0; 00065 } 00066 00074 void 00075 ctrump_ast_fold_const_offset_sint(int *ret_offset, struct ctrump_expr **ret_expr, 00076 struct ctrump_expr *e) 00077 { 00078 int is_const; 00079 int val; 00080 struct ctrump_expr *lhs, *rhs; 00081 00082 *ret_offset = 0; 00083 00084 tailcall: 00085 switch (e->code) { 00086 case CTRUMP_EXPR_SINT_LITERAL: 00087 *ret_expr = NULL; 00088 *ret_offset = e->u.sint_literal.value; 00089 return; 00090 00091 case CTRUMP_EXPR_BIN_ADD: 00092 case CTRUMP_EXPR_BIN_SUB: 00093 lhs = e->u.binary.lhs; 00094 rhs = e->u.binary.rhs; 00095 00096 val = ctrump_ast_fold_const_sint(lhs, &is_const); 00097 if (is_const) { 00098 if (e->code == CTRUMP_EXPR_BIN_ADD) { 00099 *ret_offset += val; 00100 } else { 00101 *ret_offset -= val; 00102 } 00103 e = rhs; 00104 goto tailcall; 00105 } else { 00106 val = ctrump_ast_fold_const_sint(rhs, &is_const); 00107 if (is_const) { 00108 if (e->code == CTRUMP_EXPR_BIN_ADD) { 00109 *ret_offset += val; 00110 } else { 00111 *ret_offset -= val; 00112 } 00113 e = lhs; 00114 goto tailcall; 00115 } else { 00116 *ret_expr = e; 00117 return; 00118 } 00119 } 00120 break; 00121 00122 case CTRUMP_EXPR_PAREN: 00123 e = e->u.paren.expr; 00124 goto tailcall; 00125 00126 default: 00127 break; 00128 } 00129 00130 *ret_expr = e; 00131 }