Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Common/Eval.cc

    rd7aa12c r5cbacf1  
    1717
    1818#include "Common/PassVisitor.h"
    19 #include "AST/Pass.hpp"
    2019#include "InitTweak/InitTweak.h"
    2120#include "SynTree/Expression.h"
    2221
    23 //-------------------------------------------------------------
    24 // Old AST
    25 struct EvalOld : public WithShortCircuiting {
     22struct Eval : public WithShortCircuiting {
    2623        long long int value = 0;
    2724        bool valid = true;
     
    8380};
    8481
    85 //-------------------------------------------------------------
    86 // New AST
    87 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 valid
    103         }
    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 valueOf
    109                                         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 functions
    144         }
    145 };
    146 
    14782std::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;
    15984        if (expr) {
    16085                expr->accept(ev);
Note: See TracChangeset for help on using the changeset viewer.