Check-in [dc93ad8cf6]
Not logged in
Overview
SHA1 Hash:dc93ad8cf6f70f294a04d1fab62e2041f3acd931
Date: 2010-11-09 19:28:08
User: kinaba
Comment:layered exec expression @lay(...) added
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified polemy/ast.d from [c08643c4271f8f35] to [dd714695d64176f9].

30 30 } 31 31 32 32 class VarExpression : AST 33 33 { 34 34 string var; 35 35 mixin SimpleClass; 36 36 } 37 + 38 +class LayeredExpression : AST 39 +{ 40 + string lay; 41 + AST expr; 42 + mixin SimpleClass; 43 +} 37 44 38 45 class LetExpression : AST 39 46 { 40 47 string var; 41 48 string layer; 42 49 AST init; 43 50 AST expr; ................................................................................ 68 75 template genEast(T) 69 76 { T genEast(P...)(P ps) { return new T(LexPosition.dummy, ps); } } 70 77 71 78 alias genEast!StrLiteral strl; 72 79 alias genEast!IntLiteral intl; 73 80 auto fun(string[] xs, AST ps) { return genEast!FunLiteral(xs,ps); } // to help type inference of D 74 81 alias genEast!VarExpression var; 82 + alias genEast!LayeredExpression lay; 75 83 alias genEast!LetExpression let; 76 84 alias genEast!FuncallExpression call; 77 85 }

Modified polemy/eval.d from [73d121b46bcd4718] to [cdb82702a34f8def].

97 97 98 98 Tuple!(Value,"val",Table,"ctx") eval(AST e) 99 99 { 100 100 Table ctx = createGlobalContext(); 101 101 return typeof(return)(eval(e, ctx), ctx); 102 102 } 103 103 104 -Value eval(AST _e, Table ctx, bool splitCtx = false) 104 +Value eval(AST _e, Table ctx, bool splitCtx = false, Layer lay="@val") 105 105 { 106 106 if( auto e = cast(StrLiteral)_e ) 107 107 { 108 108 return new StrValue(e.data); 109 109 } 110 110 else 111 111 if( auto e = cast(IntLiteral)_e ) 112 112 { 113 113 return new IntValue(e.data); 114 114 } 115 115 else 116 116 if( auto e = cast(VarExpression)_e ) 117 117 { 118 - return ctx.get(e.var, "@val", e.pos); 118 + return ctx.get(e.var, lay, e.pos); 119 + } 120 + else 121 + if( auto e = cast(LayeredExpression)_e ) 122 + { 123 + return eval(e.expr, ctx, false, e.lay); 119 124 } 120 125 else 121 126 if( auto e = cast(LetExpression)_e ) 122 127 { 123 128 // for letrec, we need this, but should avoid overwriting???? 124 129 // ctx.set(e.var, "@val", new UndefinedValue, e.pos); 125 130 Value v = eval(e.init, ctx, true); 126 131 if(splitCtx) 127 132 ctx = new Table(ctx, Table.Kind.NotPropagateSet); 128 - ctx.set(e.var, "@val", v, e.pos); 133 + ctx.set(e.var, (e.layer.length ? e.layer : lay), v, e.pos); 129 134 return eval(e.expr, ctx); 130 135 } 131 136 else 132 137 if( auto e = cast(FuncallExpression)_e ) 133 138 { 134 139 Value _f = eval(e.fun, ctx); 135 140 if( auto f = cast(FunValue)_f ) { ................................................................................ 178 183 assert_nothrow( evalString(`print(fun(){});`) ); 179 184 } 180 185 unittest 181 186 { 182 187 assert_eq( evalString(`let x=1; let y=(let x=2); x`).val, new IntValue(BigInt(1)) ); 183 188 assert_eq( evalString(`let x=1; let y=(let x=2;fun(){x}); y()`).val, new IntValue(BigInt(2)) ); 184 189 } 190 +unittest 191 +{ 192 + assert_eq( evalString(`@a x=1; @b x=2; @a(x)`).val, new IntValue(BigInt(1)) ); 193 + assert_eq( evalString(`@a x=1; @b x=2; @b(x)`).val, new IntValue(BigInt(2)) ); 194 + assert_eq( evalString(`let x=1; let _ = (@a x=2;2); x`).val, new IntValue(BigInt(1)) ); 195 + assert_throw!Error( evalString(`let x=1; let _ = (@a x=2;2); @a(x)`) ); 196 +} 197 + 185 198 unittest 186 199 { 187 200 assert_nothrow( evalString(`var fac = fun(x){ 188 201 1; 189 202 }; 190 203 print(fac(3));`)); 191 204 assert_nothrow( evalString(`var fac = fun(x){

Modified polemy/parse.d from [e14df84da140adf3] to [fafb5e120f10db35].

55 55 } 56 56 57 57 AST Body() 58 58 { 59 59 if( lex.empty || !lex.front.quoted && lex.front.str=="}" ) 60 60 return doNothingExpression(); 61 61 62 + auto saved = lex.save; 62 63 auto pos = lex.front.pos; 63 64 string kwd = lex.front.str; 64 65 if( tryEat("let") || tryEat("var") || tryEat("def") || tryEat("@") ) 65 66 { 66 - if( kwd == "@" ) 67 + if( kwd == "@" ) { 67 68 kwd ~= eatId("after @"); 69 + if( tryEat("(") ) { 70 + lex = saved; 71 + goto asExpression; 72 + } 73 + } 68 74 immutable LexPosition varpos = (lex.empty ? null : lex.front.pos); 69 75 string var = eatId("after "~kwd); 70 76 eat("=", "after "~kwd); 71 77 kwd = (kwd[0]=='@' ? kwd : ""); // "let, var, def ==> neutral layer" 72 78 auto e = E(0); 73 79 if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) ) 74 80 return new LetExpression(pos, var, kwd, e, Body()); 75 81 else 76 82 return new LetExpression(pos, var, kwd, e, new VarExpression(varpos, var)); 77 83 } 78 84 else 79 85 { 86 + asExpression: 80 87 auto e = E(0); 81 88 if( tryEat(";") && !lex.empty && (lex.front.quoted || (lex.front.str!="}" && lex.front.str!=")")) ) 82 89 return new LetExpression(pos, "_", "@val", e, Body()); 83 90 else 84 91 return e; 85 92 } 86 93 } ................................................................................ 158 165 return new StrLiteral(pos, lex.front.str); 159 166 } 160 167 if( isNumber(lex.front.str) ) 161 168 { 162 169 scope(exit) lex.popFront; 163 170 return new IntLiteral(pos, BigInt(cast(string)lex.front.str)); 164 171 } 172 + if( tryEat("@") ) 173 + { 174 + auto lay = "@"~eatId("for layer ID"); 175 + eat("(", "for layered execution"); 176 + auto e = E(0); 177 + eat(")", "after "~lay~"(..."); 178 + return new LayeredExpression(pos, lay, e); 179 + } 165 180 if( tryEat("(") ) 166 181 { 167 182 auto e = Body(); 168 183 eat(")", "after parenthesized expression"); 169 184 return e; 170 185 } 171 186 if( tryEat("if") ) ................................................................................ 273 288 assert_eq(parseString(`if(1){2}else{3}`), call(var("if"),intl(1),fun([],intl(2)),fun([],intl(3)))); 274 289 assert_eq(parseString(`if(1){}else{3}()()`), 275 290 call(call(call(var("if"),intl(1),fun([],intl(178)),fun([],intl(3)))))); 276 291 assert_eq(parseString(`1+2*3`), call(var("+"),intl(1),call(var("*"),intl(2),intl(3)))); 277 292 assert_eq(parseString(`(1+2)*3`), call(var("*"),call(var("+"),intl(1),intl(2)),intl(3))); 278 293 assert_eq(parseString(`1*(2+3)`), call(var("*"),intl(1),call(var("+"),intl(2),intl(3)))); 279 294 assert_eq(parseString(`1*2+3`), call(var("+"),call(var("*"),intl(1),intl(2)),intl(3))); 295 + assert_eq(parseString(`@x(1)`), lay("@x", intl(1))); 280 296 281 297 assert_eq(parseString(` 282 298 let x = 100; #comment 283 299 let y = 200; #comment!!!!! 284 300 x+y 285 301 `), 286 302 let("x", "", intl(100), let("y", "", intl(200), call(var("+"), var("x"), var("y"))))

Modified polemy/value.d from [38155bcc400d812f] to [737774791c82ade1].

10 10 11 11 /// Raised when something went wrong in runtime 12 12 13 13 class RuntimeException : Exception 14 14 { 15 15 const LexPosition pos; 16 16 17 - this( const LexPosition pos, string msg ) 18 - { super(sprintf!"%s at [%s]"(msg, pos)); this.pos = pos; } 17 + this( const LexPosition pos, string msg, string file=null, size_t line=0, Throwable next=null ) 18 + { super(sprintf!"[%s] %s"(pos, msg), file, line, next); this.pos = pos; } 19 19 } 20 20 21 21 /// Runtime values of Polemy 22 22 23 23 abstract class Value 24 24 { 25 25 }