Changes in src/Common/Eval.cc [d7aa12c:5cbacf1]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/Eval.cc
rd7aa12c r5cbacf1 17 17 18 18 #include "Common/PassVisitor.h" 19 #include "AST/Pass.hpp"20 19 #include "InitTweak/InitTweak.h" 21 20 #include "SynTree/Expression.h" 22 21 23 //------------------------------------------------------------- 24 // Old AST 25 struct EvalOld : public WithShortCircuiting { 22 struct Eval : public WithShortCircuiting { 26 23 long long int value = 0; 27 24 bool valid = true; … … 83 80 }; 84 81 85 //-------------------------------------------------------------86 // New AST87 struct EvalNew : public ast::WithShortCircuiting {88 long long int value = 0;89 bool valid = true;90 91 void previsit( const ast::Node * ) { visit_children = false; }92 void postvisit( const ast::Node * ) { valid = false; }93 94 void postvisit( const ast::ConstantExpr * expr ) {95 value = expr->intValue();96 }97 98 void postvisit( const ast::CastExpr * expr ) {99 auto arg = eval(expr->arg);100 valid = arg.second;101 value = arg.first;102 // TODO: perform type conversion on value if valid103 }104 105 void postvisit( const ast::VariableExpr * expr ) {106 if ( const ast::EnumInstType * inst = dynamic_cast<const ast::EnumInstType *>(expr->result.get()) ) {107 if ( const ast::EnumDecl * decl = inst->base ) {108 if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf109 return;110 }111 }112 }113 valid = false;114 }115 116 void postvisit( const ast::ApplicationExpr * expr ) {117 const ast::DeclWithType * function = InitTweak::getFunction(expr);118 if ( ! function || function->linkage != ast::Linkage::Intrinsic ) { valid = false; return; }119 const std::string & fname = function->name;120 assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );121 std::pair<long long int, bool> arg1, arg2;122 arg1 = eval(expr->args.front());123 valid = valid && arg1.second;124 if ( ! valid ) return;125 if ( expr->args.size() == 2 ) {126 arg2 = eval(expr->args.back());127 valid = valid && arg2.second;128 if ( ! valid ) return;129 }130 if (fname == "?+?") {131 value = arg1.first + arg2.first;132 } else if (fname == "?-?") {133 value = arg1.first - arg2.first;134 } else if (fname == "?*?") {135 value = arg1.first * arg2.first;136 } else if (fname == "?/?") {137 value = arg1.first / arg2.first;138 } else if (fname == "?%?") {139 value = arg1.first % arg2.first;140 } else {141 valid = false;142 }143 // TODO: implement other intrinsic functions144 }145 };146 147 82 std::pair<long long int, bool> eval(Expression * expr) { 148 PassVisitor<EvalOld> ev; 149 if (expr) { 150 expr->accept(ev); 151 return std::make_pair(ev.pass.value, ev.pass.valid); 152 } else { 153 return std::make_pair(0, false); 154 } 155 } 156 157 std::pair<long long int, bool> eval(const ast::Expr * expr) { 158 ast::Pass<EvalNew> ev; 83 PassVisitor<Eval> ev; 159 84 if (expr) { 160 85 expr->accept(ev);
Note:
See TracChangeset
for help on using the changeset viewer.