Differences From Artifact [9d70fd9339035713]:
- File        
polemy/eval.d
- 2010-11-11 02:40:08 - part of checkin [8e6fa743ee] on branch trunk - added layered parameter AST (only AST. no parser and no evaluator). (user: kinaba) [annotate]
 
To Artifact [a16d8d322739557e]:
- File        
polemy/eval.d
- 2010-11-13 02:48:58 - part of checkin [1c01f44f52] on branch trunk - simplepatternmatch (user: kinaba) [annotate]
 
   105    105    Table ctx = createGlobalContext();
   106    106    return typeof(return)(eval(e, ctx, false, "@v"), ctx);
   107    107   }
   108    108   
   109    109   /// Entry point of this module
   110    110   /// If splitCtx = true, then inner variable declaration do not overwrite ctx.
   111    111   /// lay is the layer ID for evaluation (standard value semantics uses "@v").
   112         -
   113         -Value eval(AST _e, Table ctx, bool splitCtx, Layer lay)
          112  +import std.typetuple;
          113  +Value eval(AST e, Table ctx, bool splitCtx, Layer lay)
   114    114   {
   115         - if( auto e = cast(StrLiteral)_e )
   116         - {
   117         -  return new StrValue(e.data);
   118         - }
   119         - else
   120         - if( auto e = cast(IntLiteral)_e )
   121         - {
   122         -  return new IntValue(e.data);
   123         - }
   124         - else
   125         - if( auto e = cast(VarExpression)_e )
   126         - {
   127         -  return ctx.get(e.var, lay, e.pos);
   128         - }
   129         - else
   130         - if( auto e = cast(LayeredExpression)_e )
   131         - {
   132         -  return eval(e.expr, ctx, false, e.lay);
   133         - }
   134         - else
   135         - if( auto e = cast(LetExpression)_e )
   136         - {
   137         -  // for letrec, we need this, but should avoid overwriting????
   138         -  // ctx.set(e.var, "@v", new UndefinedValue, e.pos);
   139         -  Value v = eval(e.init, ctx, true, lay);
   140         -  if(splitCtx)
   141         -   ctx = new Table(ctx, Table.Kind.NotPropagateSet);
   142         -  ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.pos);
   143         -  return eval(e.expr, ctx, false, lay);
   144         - }
   145         - else
   146         - if( auto e = cast(FuncallExpression)_e )
   147         - {
   148         -  Value _f = eval(e.fun, ctx, true, lay);
   149         -  if( auto f = cast(FunValue)_f ) {
   150         -   Value[] args;
   151         -   foreach(a; e.args)
   152         -    args ~= eval(a, ctx, true, lay);
   153         -   return f.call(e.pos, lay, args);
   154         -  } else
          115  + return e.match(
          116  +  (StrLiteral e)
          117  +  {
          118  +   return new StrValue(e.data);
          119  +  },
          120  +  (IntLiteral e)
          121  +  {
          122  +   return new IntValue(e.data);
          123  +  },
          124  +  (VarExpression e)
          125  +  {
          126  +   return ctx.get(e.var, lay, e.pos);
          127  +  },
          128  +  (LayeredExpression e)
          129  +  {
          130  +   return eval(e.expr, ctx, false, e.lay);
          131  +  },
          132  +  (LetExpression e)
          133  +  {
          134  +   // for letrec, we need this, but should avoid overwriting????
          135  +   // ctx.set(e.var, "@v", new UndefinedValue, e.pos);
          136  +   Value v = eval(e.init, ctx, true, lay);
          137  +   if(splitCtx)
          138  +    ctx = new Table(ctx, Table.Kind.NotPropagateSet);
          139  +   ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.pos);
          140  +   return eval(e.expr, ctx, false, lay);
          141  +  },
          142  +  (FuncallExpression e)
          143  +  {
          144  +   Value _f = eval(e.fun, ctx, true, lay);
          145  +   if( auto f = cast(FunValue)_f ) {
          146  +    Value[] args;
          147  +    foreach(a; e.args)
          148  +     args ~= eval(a, ctx, true, lay);
          149  +    return f.call(e.pos, lay, args);
          150  +   }
   155    151      throw genex!RuntimeException(e.pos, "Non-funcion is applied");
   156         - }
   157         - else
   158         - if( auto e = cast(FunLiteral)_e )
   159         - {
   160         -  return new FunValue(delegate Value(immutable LexPosition pos, string lay, Value[] args){
   161         -   if( e.params.length != args.length )
   162         -    throw genex!RuntimeException(e.pos, sprintf!"Argument Number Mismatch (%d required but %d given)"
   163         -     (e.params.length, args.length));
   164         -   Table ctxNeo = new Table(ctx, Table.Kind.NotPropagateSet);
   165         -   foreach(i,p; e.params)
   166         -    ctxNeo.set(p.name, lay, args[i]);
   167         -   return eval(e.funbody, ctxNeo, true, lay);
   168         -  });
   169         - }
   170         - throw genex!RuntimeException(_e.pos, sprintf!"Unknown Kind of Expression %s"(typeid(_e)));
          152  +  },
          153  +  (FunLiteral e)
          154  +  {
          155  +   return new FunValue(delegate Value(immutable LexPosition pos, string lay, Value[] args){
          156  +    if( e.params.length != args.length )
          157  +     throw genex!RuntimeException(e.pos, sprintf!"Argument Number Mismatch (%d required but %d given)"
          158  +      (e.params.length, args.length));
          159  +    Table ctxNeo = new Table(ctx, Table.Kind.NotPropagateSet);
          160  +    foreach(i,p; e.params)
          161  +     ctxNeo.set(p.name, lay, args[i]);
          162  +    return eval(e.funbody, ctxNeo, true, lay);
          163  +   });
          164  +  },
          165  +  delegate Value (AST e)
          166  +  {
          167  +   throw genex!RuntimeException(e.pos, sprintf!"Unknown Kind of Expression %s"(typeid(e)));
          168  +  }
          169  + );
   171    170   }
   172    171   
   173    172   unittest
   174    173   {
   175    174    auto r = assert_nothrow( evalString(`var x = 21; x + x*x;`) );
   176    175    assert_eq( r.val, new IntValue(BigInt(21+21*21)) );
   177    176    assert_eq( r.ctx.get("x","@v"), new IntValue(BigInt(21)) );