Hex Artifact Content
Not logged in

Artifact bedecb22284cfae99f749134b33261f03f7ca92b:


0000: ef bb bf 6d 6f 64 75 6c 65 20 70 6f 6c 65 6d 79  ...module polemy
0010: 2e 65 76 61 6c 3b 0d 0a 69 6d 70 6f 72 74 20 70  .eval;..import p
0020: 6f 6c 65 6d 79 2e 5f 63 6f 6d 6d 6f 6e 3b 0d 0a  olemy._common;..
0030: 2f 2a 0d 0a 20 2a 20 41 75 74 68 6f 72 3a 20 20  /*.. * Author:  
0040: 6b 2e 69 6e 61 62 61 0d 0a 20 2a 20 4c 69 63 65  k.inaba.. * Lice
0050: 6e 73 65 3a 20 4e 59 53 4c 20 30 2e 39 39 38 32  nse: NYSL 0.9982
0060: 20 28 68 74 74 70 3a 2f 2f 77 77 77 2e 6b 6d 6f   (http://www.kmo
0070: 6e 6f 73 2e 6e 65 74 2f 6e 79 73 6c 2f 0d 0a 20  nos.net/nysl/.. 
0080: 2a 20 20 20 45 76 61 6c 75 61 74 6f 72 20 66 6f  *   Evaluator fo
0090: 72 20 74 68 65 20 70 6f 6c 65 6d 79 20 70 72 6f  r the polemy pro
00a0: 67 72 61 6d 6d 69 6e 67 20 6c 61 6e 67 75 61 67  gramming languag
00b0: 65 0d 0a 20 2a 2f 0d 0a 69 6d 70 6f 72 74 20 70  e.. */..import p
00c0: 6f 6c 65 6d 79 2e 61 73 74 3b 0d 0a 69 6d 70 6f  olemy.ast;..impo
00d0: 72 74 20 70 6f 6c 65 6d 79 2e 72 75 6e 74 69 6d  rt polemy.runtim
00e0: 65 3b 0d 0a 0d 0a 43 6f 6e 74 65 78 74 20 65 76  e;....Context ev
00f0: 61 6c 28 50 72 6f 67 72 61 6d 20 70 72 6f 67 29  al(Program prog)
0100: 0d 0a 7b 0d 0a 09 72 65 74 75 72 6e 20 65 76 61  ..{...return eva
0110: 6c 28 70 72 6f 67 2c 20 6e 65 77 20 43 6f 6e 74  l(prog, new Cont
0120: 65 78 74 29 3b 0d 0a 7d 0d 0a 0d 0a 43 6f 6e 74  ext);..}....Cont
0130: 65 78 74 20 65 76 61 6c 28 50 72 6f 67 72 61 6d  ext eval(Program
0140: 20 70 72 6f 67 2c 20 43 6f 6e 74 65 78 74 20 63   prog, Context c
0150: 74 78 29 0d 0a 7b 0d 0a 09 66 6f 72 65 61 63 68  tx)..{...foreach
0160: 28 73 3b 20 70 72 6f 67 29 0d 0a 09 09 63 74 78  (s; prog)....ctx
0170: 20 3d 20 65 76 61 6c 28 73 2c 20 63 74 78 29 3b   = eval(s, ctx);
0180: 0d 0a 09 72 65 74 75 72 6e 20 63 74 78 3b 0d 0a  ...return ctx;..
0190: 7d 0d 0a 0d 0a 43 6f 6e 74 65 78 74 20 65 76 61  }....Context eva
01a0: 6c 28 53 74 61 74 65 6d 65 6e 74 20 5f 73 2c 20  l(Statement _s, 
01b0: 43 6f 6e 74 65 78 74 20 63 74 78 29 0d 0a 7b 0d  Context ctx)..{.
01c0: 0a 09 69 66 28 20 61 75 74 6f 20 73 20 3d 20 63  ..if( auto s = c
01d0: 61 73 74 28 44 65 63 6c 53 74 61 74 65 6d 65 6e  ast(DeclStatemen
01e0: 74 29 5f 73 20 29 0d 0a 09 7b 0d 0a 09 09 61 75  t)_s )...{....au
01f0: 74 6f 20 76 20 3d 20 65 76 61 6c 28 73 2e 65 78  to v = eval(s.ex
0200: 70 72 2c 20 63 74 78 29 3b 0d 0a 09 09 63 74 78  pr, ctx);....ctx
0210: 2e 61 64 64 28 73 2e 76 61 72 2c 20 76 29 3b 0d  .add(s.var, v);.
0220: 0a 09 09 72 65 74 75 72 6e 20 63 74 78 3b 0d 0a  ...return ctx;..
0230: 09 7d 0d 0a 09 65 6c 73 65 0d 0a 09 69 66 28 20  .}...else...if( 
0240: 61 75 74 6f 20 73 20 3d 20 63 61 73 74 28 45 78  auto s = cast(Ex
0250: 70 72 53 74 61 74 65 6d 65 6e 74 29 5f 73 20 29  prStatement)_s )
0260: 0d 0a 09 7b 0d 0a 09 09 65 76 61 6c 28 73 2e 65  ...{....eval(s.e
0270: 78 70 72 2c 20 63 74 78 29 3b 0d 0a 09 09 72 65  xpr, ctx);....re
0280: 74 75 72 6e 20 63 74 78 3b 0d 0a 09 7d 0d 0a 09  turn ctx;...}...
0290: 74 68 72 6f 77 20 6e 65 77 20 50 6f 6c 65 6d 79  throw new Polemy
02a0: 52 75 6e 74 69 6d 65 45 78 63 65 70 74 69 6f 6e  RuntimeException
02b0: 28 73 70 72 69 6e 74 66 21 22 55 6e 6b 6e 6f 77  (sprintf!"Unknow
02c0: 6e 20 4b 69 6e 64 20 6f 66 20 53 74 61 74 65 6d  n Kind of Statem
02d0: 65 6e 74 20 25 73 20 61 74 20 5b 25 73 5d 22 28  ent %s at [%s]"(
02e0: 74 79 70 65 69 64 28 5f 73 29 2c 20 5f 73 2e 70  typeid(_s), _s.p
02f0: 6f 73 29 29 3b 0d 0a 7d 0d 0a 0d 0a 56 61 6c 75  os));..}....Valu
0300: 65 20 65 76 61 6c 28 45 78 70 72 65 73 73 69 6f  e eval(Expressio
0310: 6e 20 5f 65 2c 20 43 6f 6e 74 65 78 74 20 63 74  n _e, Context ct
0320: 78 29 0d 0a 7b 0d 0a 09 69 66 28 20 61 75 74 6f  x)..{...if( auto
0330: 20 65 20 3d 20 63 61 73 74 28 53 74 72 4c 69 74   e = cast(StrLit
0340: 65 72 61 6c 45 78 70 72 65 73 73 69 6f 6e 29 5f  eralExpression)_
0350: 65 20 29 0d 0a 09 7b 0d 0a 09 09 72 65 74 75 72  e )...{....retur
0360: 6e 20 6e 65 77 20 53 74 72 56 61 6c 75 65 28 65  n new StrValue(e
0370: 2e 64 61 74 61 29 3b 0d 0a 09 7d 0d 0a 09 65 6c  .data);...}...el
0380: 73 65 0d 0a 09 69 66 28 20 61 75 74 6f 20 65 20  se...if( auto e 
0390: 3d 20 63 61 73 74 28 49 6e 74 4c 69 74 65 72 61  = cast(IntLitera
03a0: 6c 45 78 70 72 65 73 73 69 6f 6e 29 5f 65 20 29  lExpression)_e )
03b0: 0d 0a 09 7b 0d 0a 09 09 72 65 74 75 72 6e 20 6e  ...{....return n
03c0: 65 77 20 49 6e 74 56 61 6c 75 65 28 65 2e 64 61  ew IntValue(e.da
03d0: 74 61 29 3b 0d 0a 09 7d 0d 0a 09 65 6c 73 65 0d  ta);...}...else.
03e0: 0a 09 69 66 28 20 61 75 74 6f 20 65 20 3d 20 63  ..if( auto e = c
03f0: 61 73 74 28 56 61 72 45 78 70 72 65 73 73 69 6f  ast(VarExpressio
0400: 6e 29 5f 65 20 29 0d 0a 09 7b 0d 0a 09 09 72 65  n)_e )...{....re
0410: 74 75 72 6e 20 63 74 78 5b 65 2e 76 61 72 5d 3b  turn ctx[e.var];
0420: 0d 0a 09 7d 0d 0a 09 65 6c 73 65 0d 0a 09 69 66  ...}...else...if
0430: 28 20 61 75 74 6f 20 65 20 3d 20 63 61 73 74 28  ( auto e = cast(
0440: 42 69 6e 4f 70 45 78 70 72 65 73 73 69 6f 6e 29  BinOpExpression)
0450: 5f 65 20 29 0d 0a 09 7b 0d 0a 09 09 69 66 28 20  _e )...{....if( 
0460: 65 2e 6f 70 20 3d 3d 20 22 3d 22 20 29 0d 0a 09  e.op == "=" )...
0470: 09 7b 0d 0a 09 09 09 69 66 28 20 61 75 74 6f 20  .{.....if( auto 
0480: 65 76 20 3d 20 63 61 73 74 28 56 61 72 45 78 70  ev = cast(VarExp
0490: 72 65 73 73 69 6f 6e 29 65 2e 6c 68 73 20 29 0d  ression)e.lhs ).
04a0: 0a 09 09 09 7b 0d 0a 09 09 09 09 56 61 6c 75 65  ....{......Value
04b0: 20 72 20 3d 20 65 76 61 6c 28 65 2e 72 68 73 2c   r = eval(e.rhs,
04c0: 20 63 74 78 29 3b 0d 0a 09 09 09 09 63 74 78 5b   ctx);......ctx[
04d0: 65 76 2e 76 61 72 5d 20 3d 20 72 3b 0d 0a 09 09  ev.var] = r;....
04e0: 09 09 72 65 74 75 72 6e 20 72 3b 0d 0a 09 09 09  ..return r;.....
04f0: 7d 0d 0a 09 09 09 74 68 72 6f 77 20 6e 65 77 20  }.....throw new 
0500: 50 6f 6c 65 6d 79 52 75 6e 74 69 6d 65 45 78 63  PolemyRuntimeExc
0510: 65 70 74 69 6f 6e 28 73 70 72 69 6e 74 66 21 22  eption(sprintf!"
0520: 4c 68 73 20 6f 66 20 61 73 73 69 67 6e 6d 65 6e  Lhs of assignmen
0530: 74 20 6d 75 73 74 20 62 65 20 61 20 76 61 72 69  t must be a vari
0540: 61 62 6c 65 3a 20 25 73 22 28 65 2e 70 6f 73 29  able: %s"(e.pos)
0550: 29 3b 0d 0a 09 09 7d 0d 0a 0d 0a 09 09 56 61 6c  );....}......Val
0560: 75 65 20 6c 20 3d 20 65 76 61 6c 28 65 2e 6c 68  ue l = eval(e.lh
0570: 73 2c 20 63 74 78 29 3b 0d 0a 09 09 56 61 6c 75  s, ctx);....Valu
0580: 65 20 72 20 3d 20 65 76 61 6c 28 65 2e 72 68 73  e r = eval(e.rhs
0590: 2c 20 63 74 78 29 3b 0d 0a 09 09 69 66 28 20 61  , ctx);....if( a
05a0: 75 74 6f 20 6c 76 20 3d 20 63 61 73 74 28 49 6e  uto lv = cast(In
05b0: 74 56 61 6c 75 65 29 6c 20 29 0d 0a 09 09 09 69  tValue)l ).....i
05c0: 66 28 20 61 75 74 6f 20 72 76 20 3d 20 63 61 73  f( auto rv = cas
05d0: 74 28 49 6e 74 56 61 6c 75 65 29 72 20 29 0d 0a  t(IntValue)r )..
05e0: 09 09 09 09 66 69 6e 61 6c 20 73 77 69 74 63 68  ....final switch
05f0: 28 65 2e 6f 70 29 0d 0a 09 09 09 09 7b 0d 0a 09  (e.op)......{...
0600: 09 09 09 63 61 73 65 20 22 2b 22 3a 20 72 65 74  ...case "+": ret
0610: 75 72 6e 20 6e 65 77 20 49 6e 74 56 61 6c 75 65  urn new IntValue
0620: 28 6c 76 2e 64 61 74 61 2b 72 76 2e 64 61 74 61  (lv.data+rv.data
0630: 29 3b 0d 0a 09 09 09 09 63 61 73 65 20 22 2d 22  );......case "-"
0640: 3a 20 72 65 74 75 72 6e 20 6e 65 77 20 49 6e 74  : return new Int
0650: 56 61 6c 75 65 28 6c 76 2e 64 61 74 61 2d 72 76  Value(lv.data-rv
0660: 2e 64 61 74 61 29 3b 0d 0a 09 09 09 09 63 61 73  .data);......cas
0670: 65 20 22 2a 22 3a 20 72 65 74 75 72 6e 20 6e 65  e "*": return ne
0680: 77 20 49 6e 74 56 61 6c 75 65 28 6c 76 2e 64 61  w IntValue(lv.da
0690: 74 61 2a 72 76 2e 64 61 74 61 29 3b 0d 0a 09 09  ta*rv.data);....
06a0: 09 09 63 61 73 65 20 22 2f 22 3a 20 72 65 74 75  ..case "/": retu
06b0: 72 6e 20 6e 65 77 20 49 6e 74 56 61 6c 75 65 28  rn new IntValue(
06c0: 6c 76 2e 64 61 74 61 2f 72 76 2e 64 61 74 61 29  lv.data/rv.data)
06d0: 3b 0d 0a 09 09 09 09 7d 0d 0a 09 09 09 65 6c 73  ;......}.....els
06e0: 65 0d 0a 09 09 09 09 74 68 72 6f 77 20 6e 65 77  e......throw new
06f0: 20 50 6f 6c 65 6d 79 52 75 6e 74 69 6d 65 45 78   PolemyRuntimeEx
0700: 63 65 70 74 69 6f 6e 28 73 70 72 69 6e 74 66 21  ception(sprintf!
0710: 22 72 68 73 20 6f 66 20 25 73 20 6d 75 73 74 20  "rhs of %s must 
0720: 62 65 20 61 6e 20 69 6e 74 65 67 65 72 20 62 75  be an integer bu
0730: 74 20 77 61 73 20 25 73 20 61 74 20 5b 25 73 5d  t was %s at [%s]
0740: 22 28 65 2e 6f 70 2c 20 74 79 70 65 69 64 28 72  "(e.op, typeid(r
0750: 29 2c 20 65 2e 72 68 73 2e 70 6f 73 29 29 3b 0d  ), e.rhs.pos));.
0760: 0a 09 09 65 6c 73 65 0d 0a 09 09 09 74 68 72 6f  ...else.....thro
0770: 77 20 6e 65 77 20 50 6f 6c 65 6d 79 52 75 6e 74  w new PolemyRunt
0780: 69 6d 65 45 78 63 65 70 74 69 6f 6e 28 73 70 72  imeException(spr
0790: 69 6e 74 66 21 22 6c 68 73 20 6f 66 20 25 73 20  intf!"lhs of %s 
07a0: 6d 75 73 74 20 62 65 20 61 6e 20 69 6e 74 65 67  must be an integ
07b0: 65 72 20 62 75 74 20 77 61 73 20 25 73 20 61 74  er but was %s at
07c0: 20 5b 25 73 5d 22 28 65 2e 6f 70 2c 20 74 79 70   [%s]"(e.op, typ
07d0: 65 69 64 28 6c 29 2c 20 65 2e 6c 68 73 2e 70 6f  eid(l), e.lhs.po
07e0: 73 29 29 3b 0d 0a 09 7d 0d 0a 09 74 68 72 6f 77  s));...}...throw
07f0: 20 6e 65 77 20 50 6f 6c 65 6d 79 52 75 6e 74 69   new PolemyRunti
0800: 6d 65 45 78 63 65 70 74 69 6f 6e 28 73 70 72 69  meException(spri
0810: 6e 74 66 21 22 55 6e 6b 6e 6f 77 6e 20 4b 69 6e  ntf!"Unknown Kin
0820: 64 20 6f 66 20 45 78 70 72 65 73 73 69 6f 6e 20  d of Expression 
0830: 25 73 20 61 74 20 5b 25 73 5d 22 28 74 79 70 65  %s at [%s]"(type
0840: 69 64 28 5f 65 29 2c 20 5f 65 2e 70 6f 73 29 29  id(_e), _e.pos))
0850: 3b 0d 0a 7d 0d 0a 0d 0a 0d 0a 76 65 72 73 69 6f  ;..}......versio
0860: 6e 28 75 6e 69 74 74 65 73 74 29 20 69 6d 70 6f  n(unittest) impo
0870: 72 74 20 70 6f 6c 65 6d 79 2e 70 61 72 73 65 3b  rt polemy.parse;
0880: 0d 0a 76 65 72 73 69 6f 6e 28 75 6e 69 74 74 65  ..version(unitte
0890: 73 74 29 20 69 6d 70 6f 72 74 20 73 74 64 2e 73  st) import std.s
08a0: 74 64 69 6f 3b 0d 0a 76 65 72 73 69 6f 6e 28 75  tdio;..version(u
08b0: 6e 69 74 74 65 73 74 29 20 69 6d 70 6f 72 74 20  nittest) import 
08c0: 73 74 64 2e 65 78 63 65 70 74 69 6f 6e 3b 0d 0a  std.exception;..
08d0: 75 6e 69 74 74 65 73 74 0d 0a 7b 0d 0a 09 61 75  unittest..{...au
08e0: 74 6f 20 70 61 72 73 65 72 20 3d 20 70 61 72 73  to parser = pars
08f0: 65 72 46 72 6f 6d 53 74 72 69 6e 67 28 60 76 61  erFromString(`va
0900: 72 20 78 20 3d 20 32 31 3b 20 78 20 3d 20 78 20  r x = 21; x = x 
0910: 2b 20 78 2a 78 3b 60 29 3b 0d 0a 09 61 75 74 6f  + x*x;`);...auto
0920: 20 70 72 6f 67 20 3d 20 70 61 72 73 65 72 2e 70   prog = parser.p
0930: 61 72 73 65 50 72 6f 67 72 61 6d 28 29 3b 0d 0a  arseProgram();..
0940: 09 61 75 74 6f 20 63 74 78 20 3d 20 65 76 61 6c  .auto ctx = eval
0950: 28 70 72 6f 67 29 3b 0d 0a 09 61 73 73 65 72 74  (prog);...assert
0960: 28 20 63 74 78 5b 22 78 22 5d 20 3d 3d 20 6e 65  ( ctx["x"] == ne
0970: 77 20 49 6e 74 56 61 6c 75 65 28 42 69 67 49 6e  w IntValue(BigIn
0980: 74 28 32 31 2b 32 31 2a 32 31 29 29 20 29 3b 0d  t(21+21*21)) );.
0990: 0a 09 61 73 73 65 72 74 28 20 21 63 6f 6c 6c 65  ..assert( !colle
09a0: 63 74 45 78 63 65 70 74 69 6f 6e 28 63 74 78 5b  ctException(ctx[
09b0: 22 78 22 5d 29 20 29 3b 0d 0a 09 61 73 73 65 72  "x"]) );...asser
09c0: 74 28 20 63 6f 6c 6c 65 63 74 45 78 63 65 70 74  t( collectExcept
09d0: 69 6f 6e 28 63 74 78 5b 22 79 22 5d 29 20 29 3b  ion(ctx["y"]) );
09e0: 0d 0a 7d 0d 0a 75 6e 69 74 74 65 73 74 0d 0a 7b  ..}..unittest..{
09f0: 0d 0a 09 61 75 74 6f 20 70 61 72 73 65 72 20 3d  ...auto parser =
0a00: 20 70 61 72 73 65 72 46 72 6f 6d 53 74 72 69 6e   parserFromStrin
0a10: 67 28 60 76 61 72 20 78 20 3d 20 32 31 3b 20 78  g(`var x = 21; x
0a20: 20 3d 20 78 20 2b 20 78 2a 79 3b 60 29 3b 0d 0a   = x + x*y;`);..
0a30: 09 61 75 74 6f 20 70 72 6f 67 20 3d 20 70 61 72  .auto prog = par
0a40: 73 65 72 2e 70 61 72 73 65 50 72 6f 67 72 61 6d  ser.parseProgram
0a50: 28 29 3b 0d 0a 09 61 73 73 65 72 74 28 20 63 6f  ();...assert( co
0a60: 6c 6c 65 63 74 45 78 63 65 70 74 69 6f 6e 28 65  llectException(e
0a70: 76 61 6c 28 70 72 6f 67 29 29 20 29 3b 0d 0a 7d  val(prog)) );..}
0a80: 0d 0a 75 6e 69 74 74 65 73 74 0d 0a 7b 0d 0a 09  ..unittest..{...
0a90: 61 75 74 6f 20 70 61 72 73 65 72 20 3d 20 70 61  auto parser = pa
0aa0: 72 73 65 72 46 72 6f 6d 53 74 72 69 6e 67 28 60  rserFromString(`
0ab0: 76 61 72 20 78 20 3d 20 32 31 3b 20 79 20 3d 20  var x = 21; y = 
0ac0: 78 20 2b 20 78 2a 78 3b 60 29 3b 0d 0a 09 61 75  x + x*x;`);...au
0ad0: 74 6f 20 70 72 6f 67 20 3d 20 70 61 72 73 65 72  to prog = parser
0ae0: 2e 70 61 72 73 65 50 72 6f 67 72 61 6d 28 29 3b  .parseProgram();
0af0: 0d 0a 09 61 73 73 65 72 74 28 20 63 6f 6c 6c 65  ...assert( colle
0b00: 63 74 45 78 63 65 70 74 69 6f 6e 28 65 76 61 6c  ctException(eval
0b10: 28 70 72 6f 67 29 29 20 29 3b 0d 0a 7d 0d 0a     (prog)) );..}..