source: src/Common/Eval.cc@ 2890212

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 2890212 was d7aa12c, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Implemented eval for new AST

  • Property mode set to 100644
File size: 4.9 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 "AST/Pass.hpp"
20#include "InitTweak/InitTweak.h"
21#include "SynTree/Expression.h"
22
23//-------------------------------------------------------------
24// Old AST
25struct EvalOld : public WithShortCircuiting {
26 long long int value = 0;
27 bool valid = true;
28
29 void previsit( BaseSyntaxNode * ) { visit_children = false; }
30 void postvisit( BaseSyntaxNode * ) { valid = false; }
31
32 void postvisit( ConstantExpr * expr ) {
33 value = expr->intValue();
34 }
35
36 void postvisit( CastExpr * expr ) {
37 auto arg = eval(expr->arg);
38 valid = arg.second;
39 value = arg.first;
40 // TODO: perform type conversion on value if valid
41 }
42
43 void postvisit( VariableExpr * expr ) {
44 if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
45 if ( EnumDecl * decl = inst->baseEnum ) {
46 if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
47 return;
48 }
49 }
50 }
51 valid = false;
52 }
53
54 void postvisit( ApplicationExpr * expr ) {
55 DeclarationWithType * function = InitTweak::getFunction(expr);
56 if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
57 const std::string & fname = function->name;
58 assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
59 std::pair<long long int, bool> arg1, arg2;
60 arg1 = eval(expr->args.front());
61 valid = valid && arg1.second;
62 if ( ! valid ) return;
63 if ( expr->args.size() == 2 ) {
64 arg2 = eval(expr->args.back());
65 valid = valid && arg2.second;
66 if ( ! valid ) return;
67 }
68 if (fname == "?+?") {
69 value = arg1.first + arg2.first;
70 } else if (fname == "?-?") {
71 value = arg1.first - arg2.first;
72 } else if (fname == "?*?") {
73 value = arg1.first * arg2.first;
74 } else if (fname == "?/?") {
75 value = arg1.first / arg2.first;
76 } else if (fname == "?%?") {
77 value = arg1.first % arg2.first;
78 } else {
79 valid = false;
80 }
81 // TODO: implement other intrinsic functions
82 }
83};
84
85//-------------------------------------------------------------
86// New AST
87struct 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
147std::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
157std::pair<long long int, bool> eval(const ast::Expr * expr) {
158 ast::Pass<EvalNew> ev;
159 if (expr) {
160 expr->accept(ev);
161 return std::make_pair(ev.pass.value, ev.pass.valid);
162 } else {
163 return std::make_pair(0, false);
164 }
165}
166
167// Local Variables: //
168// tab-width: 4 //
169// mode: c++ //
170// compile-command: "make install" //
171// End: //
Note: See TracBrowser for help on using the repository browser.