Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Common/Eval.cc

    rc6b4432 r8f557161  
    1919
    2020#include "AST/Inspect.hpp"
     21#include "Common/PassVisitor.h"
    2122#include "CodeGen/OperatorTable.h"                                              // access: OperatorInfo
    2223#include "AST/Pass.hpp"
    2324#include "InitTweak/InitTweak.h"
    24 
     25#include "SynTree/Expression.h"
     26
     27//-------------------------------------------------------------
     28// Old AST
     29struct EvalOld : public WithShortCircuiting {
     30        long long int value = 0;                                                        // compose the result of the constant expression
     31        bool valid = true;                                                                      // true => constant expression and value is the result
     32                                                                                                                // false => not constant expression, e.g., ++i
     33        bool cfavalid = true;                                                           // true => constant expression and value computable
     34                                                                                                                // false => constant expression but value not computable, e.g., sizeof(int)
     35
     36        void previsit( const BaseSyntaxNode * ) { visit_children = false; }
     37        void postvisit( const BaseSyntaxNode * ) { valid = false; }
     38
     39        void postvisit( const SizeofExpr * ) {
     40        }
     41
     42        void postvisit( const ConstantExpr * expr ) {
     43                value = expr->intValue();
     44        }
     45
     46        void postvisit( const CastExpr * expr ) {
     47                auto arg = eval(expr->arg);
     48                valid = arg.second;
     49                value = arg.first;
     50                // TODO: perform type conversion on value if valid
     51        }
     52
     53        void postvisit( const VariableExpr * const expr ) {
     54                if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
     55                        if ( EnumDecl * decl = inst->baseEnum ) {
     56                                if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
     57                                        return;
     58                                }
     59                        }
     60                }
     61                valid = false;
     62        }
     63
     64        void postvisit( const ApplicationExpr * expr ) {
     65                DeclarationWithType * function = InitTweak::getFunction(const_cast<ApplicationExpr *>(expr));
     66                if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
     67                const std::string & fname = function->name;
     68                assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
     69                std::pair<long long int, bool> arg1, arg2;
     70                arg1 = eval(expr->args.front());
     71                valid = valid && arg1.second;
     72                if ( ! valid ) return;
     73                if ( expr->args.size() == 2 ) {
     74                        arg2 = eval(expr->args.back());
     75                        valid = valid && arg2.second;
     76                        if ( ! valid ) return;
     77                }
     78                if (fname == "?+?") {
     79                        value = arg1.first + arg2.first;
     80                } else if (fname == "?-?") {
     81                        value = arg1.first - arg2.first;
     82                } else if (fname == "?*?") {
     83                        value = arg1.first * arg2.first;
     84                } else if (fname == "?/?") {
     85                        value = arg1.first / arg2.first;
     86                } else if (fname == "?%?") {
     87                        value = arg1.first % arg2.first;
     88                } else {
     89                        valid = false;
     90                }
     91                // TODO: implement other intrinsic functions
     92        }
     93};
     94
     95//-------------------------------------------------------------
     96// New AST
    2597struct EvalNew : public ast::WithShortCircuiting {
    2698        Evaluation result = { 0, true, true };
     
    198270};
    199271
     272std::pair<long long int, bool> eval( const Expression * expr ) {
     273        PassVisitor<EvalOld> ev;
     274        if ( expr ) {
     275                expr->accept( ev );
     276                return std::make_pair( ev.pass.value, ev.pass.valid );
     277        } else {
     278                return std::make_pair( 0, false );
     279        }
     280}
     281
    200282Evaluation eval( const ast::Expr * expr ) {
    201283        if ( expr ) {
Note: See TracChangeset for help on using the changeset viewer.