Hex Artifact Content
Not logged in

Artifact c82fe33ef6c72ef2d8fd482f0ba0d40abbd4e77f:


0000: ef bb bf 2f 2a 2a 0d 0a 20 2a 20 41 75 74 68 6f  .../**.. * Autho
0010: 72 73 3a 20 6b 2e 69 6e 61 62 61 0d 0a 20 2a 20  rs: k.inaba.. * 
0020: 4c 69 63 65 6e 73 65 3a 20 4e 59 53 4c 20 30 2e  License: NYSL 0.
0030: 39 39 38 32 20 68 74 74 70 3a 2f 2f 77 77 77 2e  9982 http://www.
0040: 6b 6d 6f 6e 6f 73 2e 6e 65 74 2f 6e 79 73 6c 2f  kmonos.net/nysl/
0050: 0d 0a 20 2a 0d 0a 20 2a 20 45 76 61 6c 75 61 74  .. *.. * Evaluat
0060: 6f 72 20 66 6f 72 20 50 6f 6c 65 6d 79 20 70 72  or for Polemy pr
0070: 6f 67 72 61 6d 6d 69 6e 67 20 6c 61 6e 67 75 61  ogramming langua
0080: 67 65 2e 0d 0a 20 2a 2f 0d 0a 6d 6f 64 75 6c 65  ge... */..module
0090: 20 70 6f 6c 65 6d 79 2e 65 76 61 6c 3b 0d 0a 69   polemy.eval;..i
00a0: 6d 70 6f 72 74 20 70 6f 6c 65 6d 79 2e 5f 63 6f  mport polemy._co
00b0: 6d 6d 6f 6e 3b 0d 0a 69 6d 70 6f 72 74 20 70 6f  mmon;..import po
00c0: 6c 65 6d 79 2e 61 73 74 3b 0d 0a 69 6d 70 6f 72  lemy.ast;..impor
00d0: 74 20 70 6f 6c 65 6d 79 2e 72 75 6e 74 69 6d 65  t polemy.runtime
00e0: 3b 0d 0a 0d 0a 43 6f 6e 74 65 78 74 20 65 76 61  ;....Context eva
00f0: 6c 28 50 72 6f 67 72 61 6d 20 70 72 6f 67 29 0d  l(Program prog).
0100: 0a 7b 0d 0a 09 72 65 74 75 72 6e 20 65 76 61 6c  .{...return eval
0110: 28 70 72 6f 67 2c 20 6e 65 77 20 43 6f 6e 74 65  (prog, new Conte
0120: 78 74 29 3b 0d 0a 7d 0d 0a 0d 0a 43 6f 6e 74 65  xt);..}....Conte
0130: 78 74 20 65 76 61 6c 28 50 72 6f 67 72 61 6d 20  xt eval(Program 
0140: 70 72 6f 67 2c 20 43 6f 6e 74 65 78 74 20 63 74  prog, Context ct
0150: 78 29 0d 0a 7b 0d 0a 09 66 6f 72 65 61 63 68 28  x)..{...foreach(
0160: 73 3b 20 70 72 6f 67 29 0d 0a 09 09 63 74 78 20  s; prog)....ctx 
0170: 3d 20 65 76 61 6c 28 73 2c 20 63 74 78 29 3b 0d  = eval(s, ctx);.
0180: 0a 09 72 65 74 75 72 6e 20 63 74 78 3b 0d 0a 7d  ..return ctx;..}
0190: 0d 0a 0d 0a 43 6f 6e 74 65 78 74 20 65 76 61 6c  ....Context eval
01a0: 28 53 74 61 74 65 6d 65 6e 74 20 5f 73 2c 20 43  (Statement _s, C
01b0: 6f 6e 74 65 78 74 20 63 74 78 29 0d 0a 7b 0d 0a  ontext ctx)..{..
01c0: 09 69 66 28 20 61 75 74 6f 20 73 20 3d 20 63 61  .if( auto s = ca
01d0: 73 74 28 44 65 63 6c 53 74 61 74 65 6d 65 6e 74  st(DeclStatement
01e0: 29 5f 73 20 29 0d 0a 09 7b 0d 0a 09 09 61 75 74  )_s )...{....aut
01f0: 6f 20 76 20 3d 20 65 76 61 6c 28 73 2e 65 78 70  o v = eval(s.exp
0200: 72 2c 20 63 74 78 29 3b 0d 0a 09 09 63 74 78 2e  r, ctx);....ctx.
0210: 61 64 64 28 73 2e 76 61 72 2c 20 76 29 3b 0d 0a  add(s.var, v);..
0220: 09 09 72 65 74 75 72 6e 20 63 74 78 3b 0d 0a 09  ..return ctx;...
0230: 7d 0d 0a 09 65 6c 73 65 0d 0a 09 69 66 28 20 61  }...else...if( a
0240: 75 74 6f 20 73 20 3d 20 63 61 73 74 28 45 78 70  uto s = cast(Exp
0250: 72 53 74 61 74 65 6d 65 6e 74 29 5f 73 20 29 0d  rStatement)_s ).
0260: 0a 09 7b 0d 0a 09 09 65 76 61 6c 28 73 2e 65 78  ..{....eval(s.ex
0270: 70 72 2c 20 63 74 78 29 3b 0d 0a 09 09 72 65 74  pr, ctx);....ret
0280: 75 72 6e 20 63 74 78 3b 0d 0a 09 7d 0d 0a 09 74  urn ctx;...}...t
0290: 68 72 6f 77 20 6e 65 77 20 50 6f 6c 65 6d 79 52  hrow new PolemyR
02a0: 75 6e 74 69 6d 65 45 78 63 65 70 74 69 6f 6e 28  untimeException(
02b0: 73 70 72 69 6e 74 66 21 22 55 6e 6b 6e 6f 77 6e  sprintf!"Unknown
02c0: 20 4b 69 6e 64 20 6f 66 20 53 74 61 74 65 6d 65   Kind of Stateme
02d0: 6e 74 20 25 73 20 61 74 20 5b 25 73 5d 22 28 74  nt %s at [%s]"(t
02e0: 79 70 65 69 64 28 5f 73 29 2c 20 5f 73 2e 70 6f  ypeid(_s), _s.po
02f0: 73 29 29 3b 0d 0a 7d 0d 0a 0d 0a 56 61 6c 75 65  s));..}....Value
0300: 20 65 76 61 6c 28 45 78 70 72 65 73 73 69 6f 6e   eval(Expression
0310: 20 5f 65 2c 20 43 6f 6e 74 65 78 74 20 63 74 78   _e, Context ctx
0320: 29 0d 0a 7b 0d 0a 09 69 66 28 20 61 75 74 6f 20  )..{...if( auto 
0330: 65 20 3d 20 63 61 73 74 28 53 74 72 4c 69 74 65  e = cast(StrLite
0340: 72 61 6c 45 78 70 72 65 73 73 69 6f 6e 29 5f 65  ralExpression)_e
0350: 20 29 0d 0a 09 7b 0d 0a 09 09 72 65 74 75 72 6e   )...{....return
0360: 20 6e 65 77 20 53 74 72 56 61 6c 75 65 28 65 2e   new StrValue(e.
0370: 64 61 74 61 29 3b 0d 0a 09 7d 0d 0a 09 65 6c 73  data);...}...els
0380: 65 0d 0a 09 69 66 28 20 61 75 74 6f 20 65 20 3d  e...if( auto e =
0390: 20 63 61 73 74 28 49 6e 74 4c 69 74 65 72 61 6c   cast(IntLiteral
03a0: 45 78 70 72 65 73 73 69 6f 6e 29 5f 65 20 29 0d  Expression)_e ).
03b0: 0a 09 7b 0d 0a 09 09 72 65 74 75 72 6e 20 6e 65  ..{....return ne
03c0: 77 20 49 6e 74 56 61 6c 75 65 28 65 2e 64 61 74  w IntValue(e.dat
03d0: 61 29 3b 0d 0a 09 7d 0d 0a 09 65 6c 73 65 0d 0a  a);...}...else..
03e0: 09 69 66 28 20 61 75 74 6f 20 65 20 3d 20 63 61  .if( auto e = ca
03f0: 73 74 28 56 61 72 45 78 70 72 65 73 73 69 6f 6e  st(VarExpression
0400: 29 5f 65 20 29 0d 0a 09 7b 0d 0a 09 09 72 65 74  )_e )...{....ret
0410: 75 72 6e 20 63 74 78 5b 65 2e 76 61 72 5d 3b 0d  urn ctx[e.var];.
0420: 0a 09 7d 0d 0a 09 65 6c 73 65 0d 0a 09 69 66 28  ..}...else...if(
0430: 20 61 75 74 6f 20 65 20 3d 20 63 61 73 74 28 42   auto e = cast(B
0440: 69 6e 4f 70 45 78 70 72 65 73 73 69 6f 6e 29 5f  inOpExpression)_
0450: 65 20 29 0d 0a 09 7b 0d 0a 09 09 69 66 28 20 65  e )...{....if( e
0460: 2e 6f 70 20 3d 3d 20 22 3d 22 20 29 0d 0a 09 09  .op == "=" )....
0470: 7b 0d 0a 09 09 09 69 66 28 20 61 75 74 6f 20 65  {.....if( auto e
0480: 76 20 3d 20 63 61 73 74 28 56 61 72 45 78 70 72  v = cast(VarExpr
0490: 65 73 73 69 6f 6e 29 65 2e 6c 68 73 20 29 0d 0a  ession)e.lhs )..
04a0: 09 09 09 7b 0d 0a 09 09 09 09 56 61 6c 75 65 20  ...{......Value 
04b0: 72 20 3d 20 65 76 61 6c 28 65 2e 72 68 73 2c 20  r = eval(e.rhs, 
04c0: 63 74 78 29 3b 0d 0a 09 09 09 09 63 74 78 5b 65  ctx);......ctx[e
04d0: 76 2e 76 61 72 5d 20 3d 20 72 3b 0d 0a 09 09 09  v.var] = r;.....
04e0: 09 72 65 74 75 72 6e 20 72 3b 0d 0a 09 09 09 7d  .return r;.....}
04f0: 0d 0a 09 09 09 74 68 72 6f 77 20 6e 65 77 20 50  .....throw new P
0500: 6f 6c 65 6d 79 52 75 6e 74 69 6d 65 45 78 63 65  olemyRuntimeExce
0510: 70 74 69 6f 6e 28 73 70 72 69 6e 74 66 21 22 4c  ption(sprintf!"L
0520: 68 73 20 6f 66 20 61 73 73 69 67 6e 6d 65 6e 74  hs of assignment
0530: 20 6d 75 73 74 20 62 65 20 61 20 76 61 72 69 61   must be a varia
0540: 62 6c 65 3a 20 25 73 22 28 65 2e 70 6f 73 29 29  ble: %s"(e.pos))
0550: 3b 0d 0a 09 09 7d 0d 0a 0d 0a 09 09 56 61 6c 75  ;....}......Valu
0560: 65 20 6c 20 3d 20 65 76 61 6c 28 65 2e 6c 68 73  e l = eval(e.lhs
0570: 2c 20 63 74 78 29 3b 0d 0a 09 09 56 61 6c 75 65  , ctx);....Value
0580: 20 72 20 3d 20 65 76 61 6c 28 65 2e 72 68 73 2c   r = eval(e.rhs,
0590: 20 63 74 78 29 3b 0d 0a 09 09 69 66 28 20 61 75   ctx);....if( au
05a0: 74 6f 20 6c 76 20 3d 20 63 61 73 74 28 49 6e 74  to lv = cast(Int
05b0: 56 61 6c 75 65 29 6c 20 29 0d 0a 09 09 09 69 66  Value)l ).....if
05c0: 28 20 61 75 74 6f 20 72 76 20 3d 20 63 61 73 74  ( auto rv = cast
05d0: 28 49 6e 74 56 61 6c 75 65 29 72 20 29 0d 0a 09  (IntValue)r )...
05e0: 09 09 09 66 69 6e 61 6c 20 73 77 69 74 63 68 28  ...final switch(
05f0: 65 2e 6f 70 29 0d 0a 09 09 09 09 7b 0d 0a 09 09  e.op)......{....
0600: 09 09 63 61 73 65 20 22 2b 22 3a 20 72 65 74 75  ..case "+": retu
0610: 72 6e 20 6e 65 77 20 49 6e 74 56 61 6c 75 65 28  rn new IntValue(
0620: 6c 76 2e 64 61 74 61 2b 72 76 2e 64 61 74 61 29  lv.data+rv.data)
0630: 3b 0d 0a 09 09 09 09 63 61 73 65 20 22 2d 22 3a  ;......case "-":
0640: 20 72 65 74 75 72 6e 20 6e 65 77 20 49 6e 74 56   return new IntV
0650: 61 6c 75 65 28 6c 76 2e 64 61 74 61 2d 72 76 2e  alue(lv.data-rv.
0660: 64 61 74 61 29 3b 0d 0a 09 09 09 09 63 61 73 65  data);......case
0670: 20 22 2a 22 3a 20 72 65 74 75 72 6e 20 6e 65 77   "*": return new
0680: 20 49 6e 74 56 61 6c 75 65 28 6c 76 2e 64 61 74   IntValue(lv.dat
0690: 61 2a 72 76 2e 64 61 74 61 29 3b 0d 0a 09 09 09  a*rv.data);.....
06a0: 09 63 61 73 65 20 22 2f 22 3a 20 72 65 74 75 72  .case "/": retur
06b0: 6e 20 6e 65 77 20 49 6e 74 56 61 6c 75 65 28 6c  n new IntValue(l
06c0: 76 2e 64 61 74 61 2f 72 76 2e 64 61 74 61 29 3b  v.data/rv.data);
06d0: 0d 0a 09 09 09 09 7d 0d 0a 09 09 09 65 6c 73 65  ......}.....else
06e0: 0d 0a 09 09 09 09 74 68 72 6f 77 20 6e 65 77 20  ......throw new 
06f0: 50 6f 6c 65 6d 79 52 75 6e 74 69 6d 65 45 78 63  PolemyRuntimeExc
0700: 65 70 74 69 6f 6e 28 73 70 72 69 6e 74 66 21 22  eption(sprintf!"
0710: 72 68 73 20 6f 66 20 25 73 20 6d 75 73 74 20 62  rhs of %s must b
0720: 65 20 61 6e 20 69 6e 74 65 67 65 72 20 62 75 74  e an integer but
0730: 20 77 61 73 20 25 73 20 61 74 20 5b 25 73 5d 22   was %s at [%s]"
0740: 28 65 2e 6f 70 2c 20 74 79 70 65 69 64 28 72 29  (e.op, typeid(r)
0750: 2c 20 65 2e 72 68 73 2e 70 6f 73 29 29 3b 0d 0a  , e.rhs.pos));..
0760: 09 09 65 6c 73 65 0d 0a 09 09 09 74 68 72 6f 77  ..else.....throw
0770: 20 6e 65 77 20 50 6f 6c 65 6d 79 52 75 6e 74 69   new PolemyRunti
0780: 6d 65 45 78 63 65 70 74 69 6f 6e 28 73 70 72 69  meException(spri
0790: 6e 74 66 21 22 6c 68 73 20 6f 66 20 25 73 20 6d  ntf!"lhs of %s m
07a0: 75 73 74 20 62 65 20 61 6e 20 69 6e 74 65 67 65  ust be an intege
07b0: 72 20 62 75 74 20 77 61 73 20 25 73 20 61 74 20  r but was %s at 
07c0: 5b 25 73 5d 22 28 65 2e 6f 70 2c 20 74 79 70 65  [%s]"(e.op, type
07d0: 69 64 28 6c 29 2c 20 65 2e 6c 68 73 2e 70 6f 73  id(l), e.lhs.pos
07e0: 29 29 3b 0d 0a 09 7d 0d 0a 09 74 68 72 6f 77 20  ));...}...throw 
07f0: 6e 65 77 20 50 6f 6c 65 6d 79 52 75 6e 74 69 6d  new PolemyRuntim
0800: 65 45 78 63 65 70 74 69 6f 6e 28 73 70 72 69 6e  eException(sprin
0810: 74 66 21 22 55 6e 6b 6e 6f 77 6e 20 4b 69 6e 64  tf!"Unknown Kind
0820: 20 6f 66 20 45 78 70 72 65 73 73 69 6f 6e 20 25   of Expression %
0830: 73 20 61 74 20 5b 25 73 5d 22 28 74 79 70 65 69  s at [%s]"(typei
0840: 64 28 5f 65 29 2c 20 5f 65 2e 70 6f 73 29 29 3b  d(_e), _e.pos));
0850: 0d 0a 7d 0d 0a 0d 0a 0d 0a 76 65 72 73 69 6f 6e  ..}......version
0860: 28 75 6e 69 74 74 65 73 74 29 20 69 6d 70 6f 72  (unittest) impor
0870: 74 20 70 6f 6c 65 6d 79 2e 70 61 72 73 65 3b 0d  t polemy.parse;.
0880: 0a 76 65 72 73 69 6f 6e 28 75 6e 69 74 74 65 73  .version(unittes
0890: 74 29 20 69 6d 70 6f 72 74 20 73 74 64 2e 73 74  t) import std.st
08a0: 64 69 6f 3b 0d 0a 76 65 72 73 69 6f 6e 28 75 6e  dio;..version(un
08b0: 69 74 74 65 73 74 29 20 69 6d 70 6f 72 74 20 73  ittest) import s
08c0: 74 64 2e 65 78 63 65 70 74 69 6f 6e 3b 0d 0a 75  td.exception;..u
08d0: 6e 69 74 74 65 73 74 0d 0a 7b 0d 0a 09 61 75 74  nittest..{...aut
08e0: 6f 20 70 61 72 73 65 72 20 3d 20 70 61 72 73 65  o parser = parse
08f0: 72 46 72 6f 6d 53 74 72 69 6e 67 28 60 76 61 72  rFromString(`var
0900: 20 78 20 3d 20 32 31 3b 20 78 20 3d 20 78 20 2b   x = 21; x = x +
0910: 20 78 2a 78 3b 60 29 3b 0d 0a 09 61 75 74 6f 20   x*x;`);...auto 
0920: 70 72 6f 67 20 3d 20 70 61 72 73 65 72 2e 70 61  prog = parser.pa
0930: 72 73 65 50 72 6f 67 72 61 6d 28 29 3b 0d 0a 09  rseProgram();...
0940: 61 75 74 6f 20 63 74 78 20 3d 20 65 76 61 6c 28  auto ctx = eval(
0950: 70 72 6f 67 29 3b 0d 0a 09 61 73 73 65 72 74 28  prog);...assert(
0960: 20 63 74 78 5b 22 78 22 5d 20 3d 3d 20 6e 65 77   ctx["x"] == new
0970: 20 49 6e 74 56 61 6c 75 65 28 42 69 67 49 6e 74   IntValue(BigInt
0980: 28 32 31 2b 32 31 2a 32 31 29 29 20 29 3b 0d 0a  (21+21*21)) );..
0990: 09 61 73 73 65 72 74 28 20 21 63 6f 6c 6c 65 63  .assert( !collec
09a0: 74 45 78 63 65 70 74 69 6f 6e 28 63 74 78 5b 22  tException(ctx["
09b0: 78 22 5d 29 20 29 3b 0d 0a 09 61 73 73 65 72 74  x"]) );...assert
09c0: 28 20 63 6f 6c 6c 65 63 74 45 78 63 65 70 74 69  ( collectExcepti
09d0: 6f 6e 28 63 74 78 5b 22 79 22 5d 29 20 29 3b 0d  on(ctx["y"]) );.
09e0: 0a 7d 0d 0a 75 6e 69 74 74 65 73 74 0d 0a 7b 0d  .}..unittest..{.
09f0: 0a 09 61 75 74 6f 20 70 61 72 73 65 72 20 3d 20  ..auto parser = 
0a00: 70 61 72 73 65 72 46 72 6f 6d 53 74 72 69 6e 67  parserFromString
0a10: 28 60 76 61 72 20 78 20 3d 20 32 31 3b 20 78 20  (`var x = 21; x 
0a20: 3d 20 78 20 2b 20 78 2a 79 3b 60 29 3b 0d 0a 09  = x + x*y;`);...
0a30: 61 75 74 6f 20 70 72 6f 67 20 3d 20 70 61 72 73  auto prog = pars
0a40: 65 72 2e 70 61 72 73 65 50 72 6f 67 72 61 6d 28  er.parseProgram(
0a50: 29 3b 0d 0a 09 61 73 73 65 72 74 28 20 63 6f 6c  );...assert( col
0a60: 6c 65 63 74 45 78 63 65 70 74 69 6f 6e 28 65 76  lectException(ev
0a70: 61 6c 28 70 72 6f 67 29 29 20 29 3b 0d 0a 7d 0d  al(prog)) );..}.
0a80: 0a 75 6e 69 74 74 65 73 74 0d 0a 7b 0d 0a 09 61  .unittest..{...a
0a90: 75 74 6f 20 70 61 72 73 65 72 20 3d 20 70 61 72  uto parser = par
0aa0: 73 65 72 46 72 6f 6d 53 74 72 69 6e 67 28 60 76  serFromString(`v
0ab0: 61 72 20 78 20 3d 20 32 31 3b 20 79 20 3d 20 78  ar x = 21; y = x
0ac0: 20 2b 20 78 2a 78 3b 60 29 3b 0d 0a 09 61 75 74   + x*x;`);...aut
0ad0: 6f 20 70 72 6f 67 20 3d 20 70 61 72 73 65 72 2e  o prog = parser.
0ae0: 70 61 72 73 65 50 72 6f 67 72 61 6d 28 29 3b 0d  parseProgram();.
0af0: 0a 09 61 73 73 65 72 74 28 20 63 6f 6c 6c 65 63  ..assert( collec
0b00: 74 45 78 63 65 70 74 69 6f 6e 28 65 76 61 6c 28  tException(eval(
0b10: 70 72 6f 67 29 29 20 29 3b 0d 0a 7d 0d 0a        prog)) );..}..