// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // utility.h -- // // Author : Richard C. Bilson // Created On : Mon May 18 07:44:20 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Sun May 6 22:24:16 2018 // Update Count : 40 // #include // for pair #include "Common/PassVisitor.h" #include "InitTweak/InitTweak.h" #include "SynTree/Expression.h" struct Eval : public WithShortCircuiting { long long int value = 0; bool valid = true; void previsit( BaseSyntaxNode * ) { visit_children = false; } void postvisit( BaseSyntaxNode * ) { valid = false; } void postvisit( ConstantExpr * expr ) { value = expr->intValue(); } void postvisit( CastExpr * expr ) { auto arg = eval(expr->arg); valid = arg.second; value = arg.first; // TODO: perform type conversion on value if valid } void postvisit( VariableExpr * expr ) { if ( EnumInstType * inst = dynamic_cast(expr->result) ) { if ( EnumDecl * decl = inst->baseEnum ) { if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf return; } } } valid = false; } void postvisit( ApplicationExpr * expr ) { DeclarationWithType * function = InitTweak::getFunction(expr); if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; } const std::string & fname = function->name; assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() ); std::pair arg1, arg2; arg1 = eval(expr->args.front()); valid = valid && arg1.second; if ( ! valid ) return; if ( expr->args.size() == 2 ) { arg2 = eval(expr->args.back()); valid = valid && arg2.second; if ( ! valid ) return; } if (fname == "?+?") { value = arg1.first + arg2.first; } else if (fname == "?-?") { value = arg1.first - arg2.first; } else if (fname == "?*?") { value = arg1.first * arg2.first; } else if (fname == "?/?") { value = arg1.first / arg2.first; } else if (fname == "?%?") { value = arg1.first % arg2.first; } else { valid = false; } // TODO: implement other intrinsic functions } }; std::pair eval(Expression * expr) { PassVisitor ev; if (expr) { expr->accept(ev); return std::make_pair(ev.pass.value, ev.pass.valid); } else { return std::make_pair(0, false); } } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //