Diff
Not logged in

Differences From Artifact [c82fe33ef6c72ef2]:

To Artifact [0a7ac481ec249b42]:


4 * 4 * 5 * Evaluator for Polemy programming language. 5 * Evaluator for Polemy programming language. 6 */ 6 */ 7 module polemy.eval; 7 module polemy.eval; 8 import polemy._common; 8 import polemy._common; 9 import polemy.ast; 9 import polemy.ast; 10 import polemy.runtime; 10 import polemy.runtime; > 11 > 12 Context createGlobalContext() > 13 { > 14 auto ctx = new Context; > 15 ctx.add("+", new PrimitiveFunction(delegate Value(Value[] args){ > 16 if( args.length != 2 ) > 17 throw new PolemyRuntimeException("+ takes two arguments! > 18 if( auto x = cast(IntValue)args[0] ) > 19 if( auto y = cast(IntValue)args[1] ) > 20 return new IntValue(x.data+y.data); > 21 throw new PolemyRuntimeException("cannot add non-integers"); // > 22 })); > 23 ctx.add("-", new PrimitiveFunction(delegate Value(Value[] args){ > 24 if( args.length != 2 ) > 25 throw new PolemyRuntimeException("- takes two arguments! > 26 if( auto x = cast(IntValue)args[0] ) > 27 if( auto y = cast(IntValue)args[1] ) > 28 return new IntValue(x.data-y.data); > 29 throw new PolemyRuntimeException("cannot add non-integers"); // > 30 })); > 31 ctx.add("*", new PrimitiveFunction(delegate Value(Value[] args){ > 32 if( args.length != 2 ) > 33 throw new PolemyRuntimeException("* takes two arguments! > 34 if( auto x = cast(IntValue)args[0] ) > 35 if( auto y = cast(IntValue)args[1] ) > 36 return new IntValue(x.data*y.data); > 37 throw new PolemyRuntimeException("cannot add non-integers"); // > 38 })); > 39 ctx.add("/", new PrimitiveFunction(delegate Value(Value[] args){ > 40 if( args.length != 2 ) > 41 throw new PolemyRuntimeException("/ takes two arguments! > 42 if( auto x = cast(IntValue)args[0] ) > 43 if( auto y = cast(IntValue)args[1] ) > 44 return new IntValue(x.data/y.data); > 45 throw new PolemyRuntimeException("cannot add non-integers"); // > 46 })); > 47 return ctx; > 48 } 11 49 12 Context eval(Program prog) 50 Context eval(Program prog) 13 { 51 { 14 return eval(prog, new Context); | 52 return eval(prog, createGlobalContext()); 15 } 53 } 16 54 17 Context eval(Program prog, Context ctx) 55 Context eval(Program prog, Context ctx) 18 { 56 { 19 foreach(s; prog) 57 foreach(s; prog) 20 ctx = eval(s, ctx); 58 ctx = eval(s, ctx); 21 return ctx; 59 return ctx; ................................................................................................................................................................................ 51 } 89 } 52 else 90 else 53 if( auto e = cast(VarExpression)_e ) 91 if( auto e = cast(VarExpression)_e ) 54 { 92 { 55 return ctx[e.var]; 93 return ctx[e.var]; 56 } 94 } 57 else 95 else 58 if( auto e = cast(BinOpExpression)_e ) | 96 if( auto e = cast(AssignExpression)_e ) 59 { 97 { 60 if( e.op == "=" ) | 98 if( auto ev = cast(VarExpression)e.lhs ) 61 { 99 { 62 if( auto ev = cast(VarExpression)e.lhs ) < 63 { < 64 Value r = eval(e.rhs, ctx); | 100 Value r = eval(e.rhs, ctx); 65 ctx[ev.var] = r; | 101 ctx[ev.var] = r; 66 return r; | 102 return r; 67 } < 68 throw new PolemyRuntimeException(sprintf!"Lhs of assignm < 69 } 103 } > 104 throw new PolemyRuntimeException(sprintf!"Lhs of assignment must 70 | 105 } 71 Value l = eval(e.lhs, ctx); < 72 Value r = eval(e.rhs, ctx); | 106 else 73 if( auto lv = cast(IntValue)l ) | 107 if( auto e = cast(FuncallExpression)_e ) 74 if( auto rv = cast(IntValue)r ) < 75 final switch(e.op) < 76 { | 108 { > 109 Value _f = eval(e.fun, ctx); > 110 if( auto f = cast(FunValue)_f ) { 77 case "+": return new IntValue(lv.data+rv.data); | 111 Value[] args; 78 case "-": return new IntValue(lv.data-rv.data); | 112 foreach(a; e.args) 79 case "*": return new IntValue(lv.data*rv.data); | 113 args ~= eval(a, ctx); 80 case "/": return new IntValue(lv.data/rv.data); | 114 return f.call(args); 81 } < 82 else | 115 } else 83 throw new PolemyRuntimeException(sprintf!"rhs of | 116 throw new PolemyRuntimeException(sprintf!"Non-funcion is 84 else < 85 throw new PolemyRuntimeException(sprintf!"lhs of %s must < 86 } 117 } 87 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Expression %s 118 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Expression %s 88 } 119 } 89 120 90 121 91 version(unittest) import polemy.parse; 122 version(unittest) import polemy.parse; 92 version(unittest) import std.stdio; 123 version(unittest) import std.stdio;