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          Table ctx = createGlobalContext();                                           105          Table ctx = createGlobalContext();
  106          return typeof(return)(eval(e, ctx, false, "@v"), ctx);                       106          return typeof(return)(eval(e, ctx, false, "@v"), ctx);
  107  }                                                                                    107  }
  108                                                                                       108  
  109  /// Entry point of this module                                                       109  /// Entry point of this module
  110  /// If splitCtx = true, then inner variable declaration do not overwrite ctx.        110  /// If splitCtx = true, then inner variable declaration do not overwrite ctx.
  111  /// lay is the layer ID for evaluation (standard value semantics uses "@v").         111  /// lay is the layer ID for evaluation (standard value semantics uses "@v").
  112                                                                                   <
                                                                                        >   112  import std.typetuple;
  113  Value eval(AST _e, Table ctx, bool splitCtx, Layer lay)                          |   113  Value eval(AST e, Table ctx, bool splitCtx, Layer lay)
  114  {                                                                                    114  {
                                                                                        >   115          return e.match(
  115          if( auto e = cast(StrLiteral)_e )                                        |   116                  (StrLiteral e)
  116          {                                                                        |   117                  {
  117                  return new StrValue(e.data);                                     |   118                          return new StrValue(e.data);
  118          }                                                                        |   119                  },
  119          else                                                                     <
  120          if( auto e = cast(IntLiteral)_e )                                        |   120                  (IntLiteral e)
  121          {                                                                        |   121                  {
  122                  return new IntValue(e.data);                                     |   122                          return new IntValue(e.data);
  123          }                                                                        |   123                  },
  124          else                                                                     <
  125          if( auto e = cast(VarExpression)_e )                                     |   124                  (VarExpression e)
  126          {                                                                        |   125                  {
  127                  return ctx.get(e.var, lay, e.pos);                               |   126                          return ctx.get(e.var, lay, e.pos);
  128          }                                                                        |   127                  },
  129          else                                                                     <
  130          if( auto e = cast(LayeredExpression)_e )                                 |   128                  (LayeredExpression e)
  131          {                                                                        |   129                  {
  132                  return eval(e.expr, ctx, false, e.lay);                          |   130                          return eval(e.expr, ctx, false, e.lay);
  133          }                                                                        |   131                  },
  134          else                                                                     <
  135          if( auto e = cast(LetExpression)_e )                                     |   132                  (LetExpression e)
  136          {                                                                        |   133                  {
  137                  // for letrec, we need this, but should avoid overwriting????    |   134                          // for letrec, we need this, but should avoid overwritin
  138                  // ctx.set(e.var, "@v", new UndefinedValue, e.pos);              |   135                          // ctx.set(e.var, "@v", new UndefinedValue, e.pos);
  139                  Value v = eval(e.init, ctx, true, lay);                          |   136                          Value v = eval(e.init, ctx, true, lay);
  140                  if(splitCtx)                                                     |   137                          if(splitCtx)
  141                          ctx = new Table(ctx, Table.Kind.NotPropagateSet);        |   138                                  ctx = new Table(ctx, Table.Kind.NotPropagateSet)
  142                  ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.pos);      |   139                          ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.po
  143                  return eval(e.expr, ctx, false, lay);                            |   140                          return eval(e.expr, ctx, false, lay);
  144          }                                                                        |   141                  },
  145          else                                                                     <
  146          if( auto e = cast(FuncallExpression)_e )                                 |   142                  (FuncallExpression e)
  147          {                                                                        |   143                  {
  148                  Value _f = eval(e.fun, ctx, true, lay);                          |   144                          Value _f = eval(e.fun, ctx, true, lay);
  149                  if( auto f = cast(FunValue)_f ) {                                |   145                          if( auto f = cast(FunValue)_f ) {
  150                          Value[] args;                                            |   146                                  Value[] args;
  151                          foreach(a; e.args)                                       |   147                                  foreach(a; e.args)
  152                                  args ~= eval(a, ctx, true, lay);                 |   148                                          args ~= eval(a, ctx, true, lay);
  153                          return f.call(e.pos, lay, args);                         |   149                                  return f.call(e.pos, lay, args);
  154                  } else                                                           <
                                                                                        >   150                          }
  155                          throw genex!RuntimeException(e.pos, "Non-funcion is appl     151                          throw genex!RuntimeException(e.pos, "Non-funcion is appl
  156          }                                                                        |   152                  },
  157          else                                                                     <
  158          if( auto e = cast(FunLiteral)_e )                                        |   153                  (FunLiteral e)
  159          {                                                                        |   154                  {
  160                  return new FunValue(delegate Value(immutable LexPosition pos, st |   155                          return new FunValue(delegate Value(immutable LexPosition
  161                          if( e.params.length != args.length )                     |   156                                  if( e.params.length != args.length )
  162                                  throw genex!RuntimeException(e.pos, sprintf!"Arg |   157                                          throw genex!RuntimeException(e.pos, spri
  163                                          (e.params.length, args.length));         |   158                                                  (e.params.length, args.length));
  164                          Table ctxNeo = new Table(ctx, Table.Kind.NotPropagateSet |   159                                  Table ctxNeo = new Table(ctx, Table.Kind.NotProp
  165                          foreach(i,p; e.params)                                   |   160                                  foreach(i,p; e.params)
  166                                  ctxNeo.set(p.name, lay, args[i]);                |   161                                          ctxNeo.set(p.name, lay, args[i]);
  167                          return eval(e.funbody, ctxNeo, true, lay);               |   162                                  return eval(e.funbody, ctxNeo, true, lay);
  168                  });                                                              |   163                          });
  169          }                                                                        |   164                  },
                                                                                        >   165                  delegate Value (AST e)
                                                                                        >   166                  {
  170          throw genex!RuntimeException(_e.pos, sprintf!"Unknown Kind of Expression |   167                          throw genex!RuntimeException(e.pos, sprintf!"Unknown Kin
                                                                                        >   168                  }
                                                                                        >   169          );
  171  }                                                                                    170  }
  172                                                                                       171  
  173  unittest                                                                             172  unittest
  174  {                                                                                    173  {
  175          auto r = assert_nothrow( evalString(`var x = 21; x + x*x;`) );               174          auto r = assert_nothrow( evalString(`var x = 21; x + x*x;`) );
  176          assert_eq( r.val, new IntValue(BigInt(21+21*21)) );                          175          assert_eq( r.val, new IntValue(BigInt(21+21*21)) );
  177          assert_eq( r.ctx.get("x","@v"), new IntValue(BigInt(21)) );                  176          assert_eq( r.ctx.get("x","@v"), new IntValue(BigInt(21)) );