Diff
Not logged in

Differences From Artifact [f1a01bb8ba2daf26]:

To Artifact [57b0a5dd9a9946f6]:


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