Ignore:
Timestamp:
Jul 30, 2018, 4:43:48 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
Children:
ba4a1d8
Parents:
05e6eb5
git-author:
Rob Schluntz <rschlunt@…> (07/30/18 16:30:06)
git-committer:
Rob Schluntz <rschlunt@…> (07/30/18 16:43:48)
Message:

Refactor eval into Common

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/HandleAttributes.cc

    r05e6eb5 r5cbacf1  
    1616#include "HandleAttributes.h"
    1717
    18 #include <utility> // for pair
    19 
    2018#include "CompilationState.h"
    2119#include "Common/PassVisitor.h"
    2220#include "Common/SemanticError.h"
    23 #include "InitTweak/InitTweak.h"
    2421#include "ResolvExpr/Resolver.h"
    2522#include "SynTree/Attribute.h"
     
    2926namespace Validate {
    3027        namespace {
    31                 std::pair<long long int, bool> eval(Expression * expr);
    32 
    33                 struct Eval : public WithShortCircuiting {
    34                         long long int value = 0;
    35                         bool valid = true;
    36 
    37                         void previsit( BaseSyntaxNode * ) { visit_children = false; }
    38                         void postvisit( BaseSyntaxNode * ) { valid = false; }
    39 
    40                         void postvisit( ConstantExpr * expr ) {
    41                                 value = expr->intValue();
    42                         }
    43 
    44                         void postvisit( CastExpr * expr ) {
    45                                 auto arg = eval(expr->arg);
    46                                 valid = arg.second;
    47                                 value = arg.first;
    48                                 // TODO: perform type conversion on value if valid
    49                         }
    50 
    51                         void postvisit( VariableExpr * expr ) {
    52                                 if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
    53                                         if ( EnumDecl * decl = inst->baseEnum ) {
    54                                                 if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
    55                                                         return;
    56                                                 }
    57                                         }
    58                                 }
    59                                 valid = false;
    60                         }
    61 
    62                         void postvisit( ApplicationExpr * expr ) {
    63                                 DeclarationWithType * function = InitTweak::getFunction(expr);
    64                                 if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
    65                                 const std::string & fname = function->name;
    66                                 assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
    67                                 std::pair<long long int, bool> arg1, arg2;
    68                                 arg1 = eval(expr->args.front());
    69                                 valid = valid && arg1.second;
    70                                 if ( ! valid ) return;
    71                                 if ( expr->args.size() == 2 ) {
    72                                         arg2 = eval(expr->args.back());
    73                                         valid = valid && arg2.second;
    74                                         if ( ! valid ) return;
    75                                 }
    76                                 if (fname == "?+?") {
    77                                         value = arg1.first + arg2.first;
    78                                 } else 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 {
    87                                         valid = false;
    88                                 }
    89                                 // TODO: implement other intrinsic functions
    90                         }
    91                 };
    92 
    93                 std::pair<long long int, bool> eval(Expression * expr) {
    94                         PassVisitor<Eval> ev;
    95                         if (expr) {
    96                                 expr->accept(ev);
    97                                 return std::make_pair(ev.pass.value, ev.pass.valid);
    98                         } else {
    99                                 return std::make_pair(0, false);
    100                         }
    101                 }
    102 
    10328                struct HandleAttributes : public WithIndexer {
    10429                        void previsit( ObjectDecl * decl );
Note: See TracChangeset for help on using the changeset viewer.