Differences From Artifact [f1a01bb8ba2daf26]:
- File
polemy/value.d
- 2010-11-21 08:18:05 - part of checkin [a5fe6233c1] on branch trunk - layered parameters implemented (user: kinaba) [annotate]
To Artifact [57b0a5dd9a9946f6]:
- File
polemy/value.d
- 2010-11-21 09:53:17 - part of checkin [435fa085ec] on branch trunk - refactored predefined layer names, and filled readme.txt. (user: kinaba) [annotate]
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