Differences From Artifact [f1d2e31afdaaee9d]:
- File
polemy/value.d
- 2010-11-20 16:35:14 - part of checkin [3464a035ec] on branch trunk - source code cleanup (user: kinaba) [annotate]
To 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]
29 29 {
30 30 string data;
31 31
32 32 mixin SimpleClass;
33 33 override string toString() const { return data; }
34 34 }
35 35
36 -///
37 -class FunValue : Value
38 -{
39 - Value delegate(immutable LexPosition pos, string lay, Value[]) data;
40 -
41 - mixin SimpleConstructor;
42 - alias data call;
43 - override string toString() const { return sprintf!"(function:%s:%s)"(data.ptr,data.funcptr); }
44 -}
45 -
46 36 ///
47 37 class UndValue : Value
48 38 {
49 39 mixin SimpleClass;
50 40 override string toString() const { return "<undefined>"; }
51 41 }
52 42
53 -/// Named Constructor for FunValue
54 43
55 -FunValue nativef(Value delegate(immutable LexPosition pos, Layer lay, Value[] args) dg)
44 +///
45 +abstract class FunValue : Value
46 +{
47 + const(Parameter[]) params();
48 + Table definitionContext();
49 + Value invoke(in LexPosition pos, Layer lay, Table ctx);
50 +}
51 +
52 +import polemy.eval; // circular...
53 +
54 +///
55 +class UserDefinedFunValue : FunValue
56 +{
57 + FunLiteral ast;
58 + Table defCtx;
59 + override const(Parameter[]) params() { return ast.params; }
60 + override Table definitionContext() { return defCtx; }
61 + override Value invoke(in LexPosition pos, Layer lay, Table ctx)
62 + {
63 + // TODO: only auto raised ones need memo? no?
64 + // auto memoization
65 +/*
66 + if( lay != "@v" && lay != "@macro" )
67 + {
68 + if( auto memolay = lay in memo )
69 + if( auto pv = args in *memolay )
70 + return *pv;
71 + memo[lay][args] = lift(e.pos,new UndValue,lay,ctx);
72 + }
73 +
74 +*/
75 + // @macro run!!!
76 + if( lay == "@macro" )
77 + return macroEval(ast.funbody, ctx, false);
78 +/*TODO memo*/ AST macroMemo;
79 + if( macroMemo is null ) {
80 + // .prototype!, forced macro cannot access parameters
81 + ctx.kill = true; scope(exit)ctx.kill=false;
82 + macroMemo = tableToAST("@v",macroEval(ast.funbody, ctx, true));
83 + }
84 + auto v = eval(macroMemo, ctx, true, lay);
85 +
86 + //auto v = eval(e.funbody, ctxNeo, true, lay);
87 + // auto memoization
88 +// if( lay != "@v" && lay != "@macro" )
89 +// memo[lay][args] = v;
90 + return v;
91 + }
92 +
93 + mixin SimpleClass;
94 + override string toString() const { return sprintf!"(function:%x:%x)"(cast(void*)ast, cast(void*)defCtx); }
95 +}
96 +
97 +///
98 +abstract class NativeFunValue : FunValue
56 99 {
57 - return new FunValue(dg);
100 + Parameter[] params_data;
101 + override const(Parameter[]) params() { return params_data; }
102 + override Table definitionContext() { return new Table; } // todo: cache overrie
58 103 }
59 104
60 105 /// Named Constructor for FunValue
61 106
62 107 FunValue native(R,T...)(R delegate (T) dg)
63 108 {
64 - return nativef( delegate Value(immutable LexPosition pos, Layer lay, Value[] args) {
65 - if( lay != "@v" )
66 - throw genex!RuntimeException(pos, "only @v layer can call native function");
67 - if( T.length != args.length )
68 - throw genex!RuntimeException(pos, "argument number mismatch!");
69 - T typed_args;
70 - foreach(i, Ti; T)
109 + return new class NativeFunValue {
110 + this()
111 + {
112 + foreach(i, Ti; T)
113 + params_data ~= new Parameter(text(i), []);
114 + }
115 + override Value invoke(in LexPosition pos, Layer lay, Table ctx)
71 116 {
72 - typed_args[i] = cast(Ti) args[i];
73 - if( typed_args[i] is null )
74 - throw genex!RuntimeException(pos, sprintf!"type mismatch on the argument %d"(i+1));
75 - }
76 - try {
77 - return dg(typed_args);
78 - } catch( RuntimeException e ) {
79 - throw e.pos is null ? new RuntimeException(pos, e.msg, e.file, e.line) : e;
117 + if( lay != "@v" )
118 + throw genex!RuntimeException(pos, "only @v layer can call native function");
119 + T typed_args;
120 + foreach(i, Ti; T) {
121 + typed_args[i] = cast(Ti) ctx.get(text(i), "@v");
122 + if( typed_args[i] is null )
123 + throw genex!RuntimeException(pos, sprintf!"type mismatch on the argument %d"(i+1));
124 + }
125 + try {
126 + return dg(typed_args);
127 + } catch( RuntimeException e ) {
128 + throw e.pos is null ? new RuntimeException(pos, e.msg, e.file, e.line) : e;
129 + }
80 130 }
81 - });
131 + };
82 132 }
83 133
84 134 /// Layer ID
85 135
86 136 alias string Layer;
87 137
88 138 /// Context (variable environment)
89 139 /// Simlar to prototype chain of ECMAScript etc.
90 140 /// But extended with the notion of "Layer"
91 141
92 142 class Table : Value
93 143 {
94 144 enum Kind {PropagateSet, NotPropagateSet};
145 + bool kill = false; // to refactor
95 146
96 147 this( Table proto=null, Kind k = Kind.PropagateSet )
97 148 { this.prototype = proto; this.kind = k; }
98 149
99 150 void set(string i, Layer lay, Value v, in LexPosition pos=null)
100 151 {
101 152 if( setIfExist(i, lay, v) )
................................................................................
103 154 data[i][lay] = v;
104 155 }
105 156
106 157 bool has(string i, Layer lay, in LexPosition pos=null)
107 158 {
108 159 if( i in data ) {
109 160 if( lay !in data[i] )
161 + return false;
162 + if(kill)
110 163 return false;
111 164 return true;
112 165 }
113 166 if( prototype is null )
114 167 return false;
115 168 return prototype.has(i, lay, pos);
116 169 }
................................................................................
117 170
118 171 Value get(string i, Layer lay, in LexPosition pos=null)
119 172 {
120 173 if( i in data ) {
121 174 // [TODO] consider forwarding to proto also in this case
122 175 if( lay !in data[i] )
123 176 throw genex!RuntimeException(pos, sprintf!"variable %s is not set in layer %s"(i,lay));
177 + if(kill)
178 + throw genex!RuntimeException(pos, sprintf!"variable %s is killed in macro"(i));
124 179 return data[i][lay];
125 180 }
126 181 if( prototype is null )
127 182 throw new RuntimeException(pos, sprintf!"variable %s not found"(i));
128 183 return prototype.get(i, lay, pos);
129 184 }
130 185