source: src/Common/Eval.cc@ e6cf857f

ADT ast-experimental pthread-emulation qualifiedEnum
Last change on this file since e6cf857f was f135b50, checked in by JiadaL <j82liang@…>, 4 years ago

The compiler is now trying to pass the value of enum const to code gen; but it won't work cause we must be able to evaluate the const_expr in compiler time. It is not currently passed as a Expression but won't be able to evaluate at compile time

  • Property mode set to 100644
File size: 5.3 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 : Wed Jul 24 15:09:06 2019
13// Update Count : 64
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( const BaseSyntaxNode * ) { visit_children = false; }
30 void postvisit( const BaseSyntaxNode * ) { valid = false; }
31
32 void postvisit( const SizeofExpr * ) {
33 }
34
35 void postvisit( const ConstantExpr * expr ) {
36 value = expr->intValue();
37 }
38
39 void postvisit( const CastExpr * expr ) {
40 auto arg = eval(expr->arg);
41 valid = arg.second;
42 value = arg.first;
43 // TODO: perform type conversion on value if valid
44 }
45
46 void postvisit( const VariableExpr * const expr ) {
47 if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
48 if ( EnumDecl * decl = inst->baseEnum ) {
49 if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
50 return;
51 }
52 }
53 }
54 valid = false;
55 }
56
57 void postvisit( const ApplicationExpr * expr ) {
58 DeclarationWithType * function = InitTweak::getFunction(const_cast<ApplicationExpr *>(expr));
59 if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
60 const std::string & fname = function->name;
61 assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
62 std::pair<long long int, bool> arg1, arg2;
63 arg1 = eval(expr->args.front());
64 valid = valid && arg1.second;
65 if ( ! valid ) return;
66 if ( expr->args.size() == 2 ) {
67 arg2 = eval(expr->args.back());
68 valid = valid && arg2.second;
69 if ( ! valid ) return;
70 }
71 if (fname == "?+?") {
72 value = arg1.first + arg2.first;
73 } else if (fname == "?-?") {
74 value = arg1.first - arg2.first;
75 } else if (fname == "?*?") {
76 value = arg1.first * arg2.first;
77 } else if (fname == "?/?") {
78 value = arg1.first / arg2.first;
79 } else if (fname == "?%?") {
80 value = arg1.first % arg2.first;
81 } else {
82 valid = false;
83 }
84 // TODO: implement other intrinsic functions
85 }
86};
87
88//-------------------------------------------------------------
89// New AST
90struct EvalNew : public ast::WithShortCircuiting {
91 long long int value = 0;
92 bool valid = true;
93
94 void previsit( const ast::Node * ) { visit_children = false; }
95 void postvisit( const ast::Node * ) { valid = false; }
96
97 void postvisit( const ast::ConstantExpr * expr ) {
98 value = expr->intValue();
99 }
100
101 void postvisit( const ast::SizeofExpr * expr ) {
102 if ( expr->expr ) value = eval(expr->expr).first;
103 else if ( expr->type ) value = eval(expr->expr).first;
104 else SemanticError( expr->location, ::toString( "Internal error: SizeofExpr has no expression or type value" ) );
105 }
106
107 void postvisit( const ast::CastExpr * expr ) {
108 auto arg = eval(expr->arg);
109 valid = arg.second;
110 value = arg.first;
111 // TODO: perform type conversion on value if valid
112 }
113
114 void postvisit( const ast::VariableExpr * expr ) { // No hit
115 if ( const ast::EnumInstType * inst = dynamic_cast<const ast::EnumInstType *>(expr->result.get()) ) {
116 if ( const ast::EnumDecl * decl = inst->base ) {
117 if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
118 return;
119 }
120 }
121 }
122 valid = false;
123 }
124
125 void postvisit( const ast::ApplicationExpr * expr ) {
126 const ast::DeclWithType * function = InitTweak::getFunction(expr);
127 if ( ! function || function->linkage != ast::Linkage::Intrinsic ) { valid = false; return; }
128 const std::string & fname = function->name;
129 assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
130 std::pair<long long int, bool> arg1, arg2;
131 arg1 = eval(expr->args.front());
132 valid = valid && arg1.second;
133 if ( ! valid ) return;
134 if ( expr->args.size() == 2 ) {
135 arg2 = eval(expr->args.back());
136 valid = valid && arg2.second;
137 if ( ! valid ) return;
138 }
139 if (fname == "?+?") {
140 value = arg1.first + arg2.first;
141 } else if (fname == "?-?") {
142 value = arg1.first - arg2.first;
143 } else if (fname == "?*?") {
144 value = arg1.first * arg2.first;
145 } else if (fname == "?/?") {
146 value = arg1.first / arg2.first;
147 } else if (fname == "?%?") {
148 value = arg1.first % arg2.first;
149 } else {
150 valid = false;
151 }
152 // TODO: implement other intrinsic functions
153 }
154};
155
156std::pair<long long int, bool> eval( const Expression * expr) {
157 PassVisitor<EvalOld> ev;
158 if (expr) {
159 expr->accept(ev);
160 return std::make_pair(ev.pass.value, ev.pass.valid);
161 } else {
162 return std::make_pair(0, false);
163 }
164}
165
166std::pair<long long int, bool> eval(const ast::Expr * expr) {
167 ast::Pass<EvalNew> ev;
168 if (expr) {
169 expr->accept(ev);
170 return std::make_pair(ev.core.value, ev.core.valid);
171 } else {
172 return std::make_pair(0, false);
173 }
174}
175
176// Local Variables: //
177// tab-width: 4 //
178// mode: c++ //
179// compile-command: "make install" //
180// End: //
Note: See TracBrowser for help on using the repository browser.