source: src/Common/Eval.cc@ 292d599b

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 292d599b was 5cbacf1, checked in by Rob Schluntz <rschlunt@…>, 7 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.