Diff
Not logged in

Differences From Artifact [f1a01bb8ba2daf26]:

To Artifact [57b0a5dd9a9946f6]:


4 4 * 5 5 * Runtime data structures for Polemy programming language. 6 6 */ 7 7 module polemy.value; 8 8 import polemy._common; 9 9 import polemy.failure; 10 10 import polemy.ast; 11 +import polemy.layer; 11 12 12 13 /// Runtime values of Polemy 13 14 14 15 abstract class Value 15 16 { 16 17 } 17 18 ................................................................................ 59 60 override const(Parameter[]) params() { return ast.params; } 60 61 override Table definitionContext() { return defCtx; } 61 62 override Value invoke(in LexPosition pos, Layer lay, Table ctx) 62 63 { 63 64 // TODO: only auto raised ones need memo? no? 64 65 // auto memoization 65 66 /* 66 - if( lay != "@v" && lay != "@macro" ) 67 + if( lay != ValueLayer && lay != MacroLayer ) 67 68 { 68 69 if( auto memolay = lay in memo ) 69 70 if( auto pv = args in *memolay ) 70 71 return *pv; 71 72 memo[lay][args] = lift(e.pos,new UndValue,lay,ctx); 72 73 } 73 74 74 75 */ 75 76 // @macro run!!! 76 - if( lay == "@macro" ) 77 + if( lay == MacroLayer ) 77 78 return macroEval(ast.funbody, ctx, false); 78 79 /*TODO memo*/ AST macroMemo; 79 80 if( macroMemo is null ) { 80 81 // .prototype!, forced macro cannot access parameters 81 82 ctx.kill = true; scope(exit)ctx.kill=false; 82 - macroMemo = tableToAST("@v",macroEval(ast.funbody, ctx, true)); 83 + macroMemo = tableToAST(ValueLayer,macroEval(ast.funbody, ctx, true)); 83 84 } 84 85 auto v = eval(macroMemo, ctx, true, lay); 85 86 86 87 //auto v = eval(e.funbody, ctxNeo, true, lay); 87 88 // auto memoization 88 -// if( lay != "@v" && lay != "@macro" ) 89 +// if( lay != ValueLayer && lay != MacroLayer ) 89 90 // memo[lay][args] = v; 90 91 return v; 91 92 } 92 93 93 94 mixin SimpleClass; 94 95 override string toString() const { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); } 95 96 } ................................................................................ 110 111 this() 111 112 { 112 113 foreach(i, Ti; T) 113 114 params_data ~= new Parameter(text(i), []); 114 115 } 115 116 override Value invoke(in LexPosition pos, Layer lay, Table ctx) 116 117 { 117 - if( lay != "@v" ) 118 - throw genex!RuntimeException(pos, "only @v layer can call native function"); 118 + if( lay != ValueLayer ) 119 + throw genex!RuntimeException(pos, "only "~ValueLayer~" layer can call native function"); 119 120 T typed_args; 120 121 foreach(i, Ti; T) { 121 - typed_args[i] = cast(Ti) ctx.get(text(i), "@v"); 122 + typed_args[i] = cast(Ti) ctx.get(text(i), ValueLayer); 122 123 if( typed_args[i] is null ) 123 124 throw genex!RuntimeException(pos, sprintf!"type mismatch on the argument %d"(i+1)); 124 125 } 125 126 try { 126 127 return dg(typed_args); 127 128 } catch( RuntimeException e ) { 128 129 throw e.pos is null ? new RuntimeException(pos, e.msg, e.file, e.line) : e; 129 130 } 130 131 } 131 132 }; 132 133 } 133 134 134 -/// Layer ID 135 - 136 -alias string Layer; 137 - 138 135 /// Context (variable environment) 139 136 /// Simlar to prototype chain of ECMAScript etc. 140 137 /// But extended with the notion of "Layer" 141 138 142 139 class Table : Value 143 140 { 144 141 enum Kind {PropagateSet, NotPropagateSet}; ................................................................................ 245 242 unittest 246 243 { 247 244 Table c0 = new Table; 248 245 Table c01 = new Table(c0, Table.Kind.NotPropagateSet); 249 246 Table c012 = new Table(c01, Table.Kind.PropagateSet); 250 247 Table c013 = new Table(c01, Table.Kind.PropagateSet); 251 248 252 - assert_nothrow( c012.set("x", "@v", new IntValue(BigInt(12))) ); 253 - assert_throw!RuntimeException( c013.get("x", "@v") ); 254 - assert_nothrow( c013.set("x", "@v", new IntValue(BigInt(13))) ); 255 - assert_eq( c013.get("x", "@v"), new IntValue(BigInt(13)) ); 256 - assert_eq( c012.get("x", "@v"), new IntValue(BigInt(12)) ); 257 - assert_throw!RuntimeException( c01.get("x", "@v") ); 249 + assert_nothrow( c012.set("x", ValueLayer, new IntValue(BigInt(12))) ); 250 + assert_throw!RuntimeException( c013.get("x", ValueLayer) ); 251 + assert_nothrow( c013.set("x", ValueLayer, new IntValue(BigInt(13))) ); 252 + assert_eq( c013.get("x", ValueLayer), new IntValue(BigInt(13)) ); 253 + assert_eq( c012.get("x", ValueLayer), new IntValue(BigInt(12)) ); 254 + assert_throw!RuntimeException( c01.get("x", ValueLayer) ); 255 + 256 + assert_nothrow( c01.set("y", ValueLayer, new IntValue(BigInt(1))) ); 257 + assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(1)) ); 258 + assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(1)) ); 259 + assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(1)) ); 258 260 259 - assert_nothrow( c01.set("y", "@v", new IntValue(BigInt(1))) ); 260 - assert_eq( c013.get("y", "@v"), new IntValue(BigInt(1)) ); 261 - assert_eq( c012.get("y", "@v"), new IntValue(BigInt(1)) ); 262 - assert_eq( c01.get("y", "@v"), new IntValue(BigInt(1)) ); 261 + assert_nothrow( c0.set("z", ValueLayer, new IntValue(BigInt(0))) ); 262 + assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) ); 263 + assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(0)) ); 264 + assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) ); 265 + assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) ); 263 266 264 - assert_nothrow( c0.set("z", "@v", new IntValue(BigInt(0))) ); 265 - assert_eq( c013.get("z", "@v"), new IntValue(BigInt(0)) ); 266 - assert_eq( c012.get("z", "@v"), new IntValue(BigInt(0)) ); 267 - assert_eq( c01.get("z", "@v"), new IntValue(BigInt(0)) ); 268 - assert_eq( c0.get("z", "@v"), new IntValue(BigInt(0)) ); 267 + assert_nothrow( c012.set("y", ValueLayer, new IntValue(BigInt(444))) ); 268 + assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(444)) ); 269 + assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(444)) ); 270 + assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(444)) ); 269 271 270 - assert_nothrow( c012.set("y", "@v", new IntValue(BigInt(444))) ); 271 - assert_eq( c013.get("y", "@v"), new IntValue(BigInt(444)) ); 272 - assert_eq( c012.get("y", "@v"), new IntValue(BigInt(444)) ); 273 - assert_eq( c01.get("y", "@v"), new IntValue(BigInt(444)) ); 274 - 275 - assert_nothrow( c012.set("z", "@v", new IntValue(BigInt(555))) ); 276 - assert_eq( c013.get("z", "@v"), new IntValue(BigInt(0)) ); 277 - assert_eq( c012.get("z", "@v"), new IntValue(BigInt(555)) ); 278 - assert_eq( c01.get("z", "@v"), new IntValue(BigInt(0)) ); 279 - assert_eq( c0.get("z", "@v"), new IntValue(BigInt(0)) ); 272 + assert_nothrow( c012.set("z", ValueLayer, new IntValue(BigInt(555))) ); 273 + assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) ); 274 + assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) ); 275 + assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) ); 276 + assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) ); 280 277 281 278 // [TODO] define the semantics and test @layers 282 279 } 283 280 284 281 immutable(LexPosition) extractPos( Table t ) 285 282 { 286 - Layer theLayer = "@v"; 283 + Layer theLayer = ValueLayer; 287 284 if(auto tt = t.access!Table(theLayer, "pos")) 288 285 { 289 286 auto fn = tt.access!StrValue(theLayer, "filename"); 290 287 auto ln = tt.access!IntValue(theLayer, "lineno"); 291 288 auto cl = tt.access!IntValue(theLayer, "column"); 292 289 if(fn !is null && ln !is null && cl !is null) 293 290 return new immutable(LexPosition)(fn.data,cast(int)ln.data.toInt,cast(int)cl.data.toInt);