source: src/Common/Eval.cc @ 341bb80

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resnenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since 341bb80 was 5cbacf1, checked in by Rob Schluntz <rschlunt@…>, 6 years ago

Refactor eval into Common

  • Property mode set to 100644
File size: 2.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// utility.h --
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sun May  6 22:24:16 2018
13// Update Count     : 40
14//
15
16#include <utility> // for pair
17
18#include "Common/PassVisitor.h"
19#include "InitTweak/InitTweak.h"
20#include "SynTree/Expression.h"
21
22struct Eval : public WithShortCircuiting {
23        long long int value = 0;
24        bool valid = true;
25
26        void previsit( BaseSyntaxNode * ) { visit_children = false; }
27        void postvisit( BaseSyntaxNode * ) { valid = false; }
28
29        void postvisit( ConstantExpr * expr ) {
30                value = expr->intValue();
31        }
32
33        void postvisit( CastExpr * expr ) {
34                auto arg = eval(expr->arg);
35                valid = arg.second;
36                value = arg.first;
37                // TODO: perform type conversion on value if valid
38        }
39
40        void postvisit( VariableExpr * expr ) {
41                if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
42                        if ( EnumDecl * decl = inst->baseEnum ) {
43                                if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
44                                        return;
45                                }
46                        }
47                }
48                valid = false;
49        }
50
51        void postvisit( ApplicationExpr * expr ) {
52                DeclarationWithType * function = InitTweak::getFunction(expr);
53                if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
54                const std::string & fname = function->name;
55                assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
56                std::pair<long long int, bool> arg1, arg2;
57                arg1 = eval(expr->args.front());
58                valid = valid && arg1.second;
59                if ( ! valid ) return;
60                if ( expr->args.size() == 2 ) {
61                        arg2 = eval(expr->args.back());
62                        valid = valid && arg2.second;
63                        if ( ! valid ) return;
64                }
65                if (fname == "?+?") {
66                        value = arg1.first + arg2.first;
67                } else if (fname == "?-?") {
68                        value = arg1.first - arg2.first;
69                } else if (fname == "?*?") {
70                        value = arg1.first * arg2.first;
71                } else if (fname == "?/?") {
72                        value = arg1.first / arg2.first;
73                } else if (fname == "?%?") {
74                        value = arg1.first % arg2.first;
75                } else {
76                        valid = false;
77                }
78                // TODO: implement other intrinsic functions
79        }
80};
81
82std::pair<long long int, bool> eval(Expression * expr) {
83        PassVisitor<Eval> ev;
84        if (expr) {
85                expr->accept(ev);
86                return std::make_pair(ev.pass.value, ev.pass.valid);
87        } else {
88                return std::make_pair(0, false);
89        }
90}
91
92// Local Variables: //
93// tab-width: 4 //
94// mode: c++ //
95// compile-command: "make install" //
96// End: //
Note: See TracBrowser for help on using the repository browser.