Overview
SHA1 Hash: | 2134cd44cc68f372bd694e0ebc28adb2c95052e0 |
---|---|
Date: | 2010-11-23 22:55:15 |
User: | kinaba |
Comment: | further clean-up for polemy2d |
Timelines: | family | ancestors | descendants | both | trunk |
Downloads: | Tarball | ZIP archive |
Other Links: | files | file ages | manifest |
Tags And Properties
- branch=trunk inherited from [f65680e1d2]
- sym-trunk inherited from [f65680e1d2]
Changes
Modified polemy/ast.d from [f7a981003352ec6b] to [2e3f1e0044f7841f].
89 { 89 { 90 Parameter[] params; 90 Parameter[] params; 91 AST funbody; 91 AST funbody; 92 92 93 mixin SimpleClass; 93 mixin SimpleClass; 94 } 94 } 95 95 > 96 /// List of AST Types > 97 > 98 alias TypeTuple!(Int,Str,Var,Lay,Let,App,Fun) ListOfASTTypes; > 99 96 /// Handy Generator for AST nodes. To use this, mixin EasyAst; 100 /// Handy Generator for AST nodes. To use this, mixin EasyAst; 97 101 98 /*mixin*/ 102 /*mixin*/ 99 template EasyAST() 103 template EasyAST() 100 { 104 { 101 /// 105 /// 102 template genEast(T) 106 template genEast(T)
Modified polemy/eval.d from [ca0ab118700475a8] to [a7c677ad83621b47].
98 } 98 } 99 99 100 Value eval( App e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 100 Value eval( App e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 101 { 101 { 102 Value f = eval( e.fun, lay, ctx ); 102 Value f = eval( e.fun, lay, ctx ); 103 if( isMacroishLayer(lay) ) 103 if( isMacroishLayer(lay) ) 104 if( auto ff = cast(FunValue)f ) 104 if( auto ff = cast(FunValue)f ) 105 return invokeFunction(ff, e.args, MacroLayer, ct | 105 return invokeFunction(ff, e.args, MacroLayer, ct 106 else 106 else 107 return ast2table(e, (AST e){return eval(e,lay,ct 107 return ast2table(e, (AST e){return eval(e,lay,ct 108 return invokeFunction(f, e.args, lay, ctx, e.pos); | 108 return invokeFunction(f, e.args, lay, ctx, e.pos, getNameIfPossi 109 } 109 } 110 110 111 Value eval( Fun e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 111 Value eval( Fun e, Layer lay, Table ctx, bool overwriteCtx=CascadeCtx ) 112 { 112 { 113 if( isMacroishLayer(lay) ) 113 if( isMacroishLayer(lay) ) 114 return ast2table(e, (AST e){return eval(e,lay,ctx);}); 114 return ast2table(e, (AST e){return eval(e,lay,ctx);}); 115 else 115 else ................................................................................................................................................................................ 137 string theLayer = e.layer.empty ? lay : e.layer; // neut 137 string theLayer = e.layer.empty ? lay : e.layer; // neut 138 ctx.set(e.name, theLayer, ri); 138 ctx.set(e.name, theLayer, ri); 139 return eval(e.expr, lay, ctx, OverwriteCtx); 139 return eval(e.expr, lay, ctx, OverwriteCtx); 140 } 140 } 141 } 141 } 142 142 143 private: 143 private: > 144 string getNameIfPossible(AST e) > 145 { > 146 if(auto v = cast(Var)e) > 147 return v.name; > 148 return ""; > 149 } > 150 144 Value invokeFunction(Value _f, AST[] args, Layer lay, Table ctx, LexPosi | 151 Value invokeFunction(Value _f, AST[] args, Layer lay, Table ctx, LexPosi 145 { 152 { 146 if(auto f = cast(FunValue)_f) 153 if(auto f = cast(FunValue)_f) 147 { 154 { 148 Table newCtx = new Table(f.definitionContext(), Table.Ki 155 Table newCtx = new Table(f.definitionContext(), Table.Ki 149 foreach(i,p; f.params()) 156 foreach(i,p; f.params()) 150 if( p.layers.empty ) 157 if( p.layers.empty ) 151 newCtx.set(p.name, (lay==RawMacroLayer ? 158 newCtx.set(p.name, (lay==RawMacroLayer ? 152 else 159 else 153 foreach(argLay; p.layers) 160 foreach(argLay; p.layers) 154 newCtx.set(p.name, argLay, eval( 161 newCtx.set(p.name, argLay, eval( > 162 scope _ = new PushCallStack(pos, callstackmsg); 155 return f.invoke(lay==RawMacroLayer ? MacroLayer : lay, n 163 return f.invoke(lay==RawMacroLayer ? MacroLayer : lay, n 156 } 164 } 157 throw genex!RuntimeException(pos, text("tried to call non-functi 165 throw genex!RuntimeException(pos, text("tried to call non-functi 158 } 166 } 159 167 160 Value lift(Value v, Layer lay, Table ctx, LexPosition pos=null) | 168 Value lift(Value v, Layer lay, Table ctx, LexPosition pos) 161 { 169 { 162 assert( !isMacroishLayer(lay), "lift to the @macro layer should | 170 assert( !isMacroishLayer(lay), "lift to the @macro layer should 163 171 164 // functions are automatically lifterd 172 // functions are automatically lifterd 165 if( cast(FunValue) v ) 173 if( cast(FunValue) v ) 166 return v; 174 return v; 167 175 > 176 if( !ctx.has(lay, SystemLayer) ) > 177 throw genex!RuntimeException(pos, "lift function for "~l > 178 168 // similar to invoke Function, but with only one argument bound | 179 // similar to invokeFunction, but with only one argument bound t 169 if(auto f = cast(FunValue)ctx.get(lay, SystemLayer, pos)) | 180 auto _f = ctx.get(lay, SystemLayer, pos); > 181 if(auto f = cast(FunValue)_f) 170 { 182 { 171 Table newCtx = new Table(f.definitionContext(), Table.Ki 183 Table newCtx = new Table(f.definitionContext(), Table.Ki 172 auto ps = f.params(); 184 auto ps = f.params(); 173 if( ps.length != 1 ) 185 if( ps.length != 1 ) 174 throw genex!RuntimeException(pos, "lift function | 186 throw genex!RuntimeException(pos, > 187 text("lift function for", lay, " must ta 175 if( ps[0].layers.length==0 || ps[0].layers.length==1 && 188 if( ps[0].layers.length==0 || ps[0].layers.length==1 && 176 { 189 { 177 newCtx.set(ps[0].name, ValueLayer, v); 190 newCtx.set(ps[0].name, ValueLayer, v); > 191 scope _ = new PushCallStack(pos, lay); 178 return f.invoke(ValueLayer, newCtx, pos); 192 return f.invoke(ValueLayer, newCtx, pos); 179 } 193 } 180 else 194 else 181 throw genex!RuntimeException(pos, "lift function | 195 throw genex!RuntimeException(pos, > 196 text("lift function for", lay, " must ta 182 } 197 } 183 throw genex!RuntimeException(pos, "tried to call non-function"); | 198 throw genex!RuntimeException(pos, > 199 text("non-function ", _f, " is registered as the lift fu 184 } 200 } 185 201 186 Value createNewFunction(Fun e, Table ctx) 202 Value createNewFunction(Fun e, Table ctx) 187 { 203 { 188 class UserDefinedFunValue : FunValue 204 class UserDefinedFunValue : FunValue 189 { 205 { 190 Fun ast; 206 Fun ast; ................................................................................................................................................................................ 215 assert(false, sprintf!"Cannot compare %s with %s 231 assert(false, sprintf!"Cannot compare %s with %s 216 } 232 } 217 233 218 override Value invoke(Layer lay, Table ctx, LexPosition 234 override Value invoke(Layer lay, Table ctx, LexPosition 219 { 235 { 220 if( lay == MacroLayer ) 236 if( lay == MacroLayer ) 221 return eval(ast.funbody, lay, ctx); 237 return eval(ast.funbody, lay, ctx); > 238 try { 222 if( afterMacroAST is null ) | 239 if( afterMacroAST is null ) 223 afterMacroAST = tableToAST(ValueLayer, e | 240 afterMacroAST = polemy2d!(AST)(e 224 return eval(afterMacroAST, lay, ctx); | 241 return eval(afterMacroAST, lay, ctx); > 242 } catch( RuntimeException e ) { > 243 throw e.pos is null ? new RuntimeExcepti > 244 } 225 } 245 } 226 246 227 AST afterMacroAST; 247 AST afterMacroAST; 228 } 248 } 229 return new UserDefinedFunValue(e,ctx); 249 return new UserDefinedFunValue(e,ctx); 230 } 250 } 231 251
Modified polemy/failure.d from [701f5b1b899607f2] to [1bc945d1d318d417].
17 { 17 { 18 immutable string filename; /// name of the source file 18 immutable string filename; /// name of the source file 19 immutable int lineno; /// 1-origin 19 immutable int lineno; /// 1-origin 20 immutable int column; /// 1-origin 20 immutable int column; /// 1-origin 21 21 22 mixin SimpleClass; 22 mixin SimpleClass; 23 override string toString() const 23 override string toString() const 24 { < 25 return sprintf!("%s:%d:%d")(filename, lineno, column); | 24 { return sprintf!("%s:%d:%d")(filename, lineno, column); } 26 } < 27 < 28 static LexPosition dummy; 25 static LexPosition dummy; 29 static this(){ dummy = new LexPosition("<unnamed>",0,0); } 26 static this(){ dummy = new LexPosition("<unnamed>",0,0); } 30 } 27 } 31 28 32 unittest 29 unittest 33 { 30 { 34 auto p = new LexPosition("hello.cpp", 123, 45); 31 auto p = new LexPosition("hello.cpp", 123, 45); ................................................................................................................................................................................ 50 47 51 /*mixin*/ 48 /*mixin*/ 52 template ExceptionWithPosition() 49 template ExceptionWithPosition() 53 { 50 { 54 LexPosition pos; 51 LexPosition pos; 55 this( LexPosition pos, string msg, string file=null, size_t line=0, Thro 52 this( LexPosition pos, string msg, string file=null, size_t line=0, Thro 56 { 53 { 57 if(pos is null) | 54 string fullmsg = pos is null ? sprintf!("\n[??] %s")(msg) 58 super(sprintf!("[??] %s")(msg), file, line, next); | 55 : sprintf!("\n[%s] %s")(pos, msg); 59 else | 56 for(int i=0; i<callstack_pos.length || i<callstack_msg.length; + > 57 { > 58 LexPosition p = (i<callstack_pos.length ? callstack_pos[ > 59 string m = (i<callstack_msg.length ? callstack_msg[ > 60 fullmsg ~= p is null ? sprintf!("\n[??] %s")(m) > 61 : sprintf!("\n[%s] %s")(p, m); > 62 } 60 super(sprintf!("[%s] %s")(pos, msg), file, line, next); | 63 super(fullmsg, file, line, next); 61 this.pos = pos; 64 this.pos = pos; > 65 } > 66 this( string msg, string file=null, size_t line=0, Throwable next=null ) > 67 { > 68 this(null, msg, file, line, next); 62 } 69 } 63 } 70 } 64 71 65 class UnexpectedEOF : Exception { mixin ExceptionWithPosition; } /// EOF during | 72 class UnexpectedEOF : Exception { mixin ExceptionWithPosition; } /// EOF duri 66 class LexException : Exception { mixin ExceptionWithPosition; } /// Lexer errors | 73 class LexException : Exception { mixin ExceptionWithPosition; } /// Lexer er 67 class ParseException : Exception { mixin ExceptionWithPosition; } /// Parser err | 74 class ParseException : Exception { mixin ExceptionWithPosition; } /// Parser e 68 class RuntimeException : Exception { mixin ExceptionWithPosition; } /// Evaluato 75 class RuntimeException : Exception { mixin ExceptionWithPosition; } /// Evaluato > 76 > 77 /// Per-thread call stack management. > 78 /// This scoped class's ctor&dtor maintain the callstack. > 79 /// TODO: make it "per-evaluator" !!!!!!!!!!! > 80 > 81 scope class PushCallStack > 82 { > 83 this(LexPosition pos, string msg) { callstackEnterFunction(pos,msg); } > 84 ~this() { callstackLeaveFunction(); } > 85 } > 86 > 87 LexPosition[] callstack_pos; > 88 string[] callstack_msg; > 89 > 90 private void callstackEnterFunction(LexPosition pos, string msg) > 91 { > 92 callstack_pos ~= pos; > 93 callstack_msg ~= msg; > 94 } > 95 > 96 private void callstackLeaveFunction() > 97 { > 98 callstack_pos.length -= 1; > 99 callstack_msg.length -= 1; > 100 }
Modified polemy/parse.d from [b6858e7b65012cb1] to [50e0836a1ece20de].
152 // [TODO] make this customizable from program 152 // [TODO] make this customizable from program 153 private static string[][] operator_perferences = [ 153 private static string[][] operator_perferences = [ 154 ["||"], 154 ["||"], 155 ["&&"], 155 ["&&"], 156 ["!="], 156 ["!="], 157 ["=="], 157 ["=="], 158 ["<","<=",">",">="], 158 ["<","<=",">",">="], 159 // ["|"], | 159 ["|"], 160 // ["^"], | 160 ["^"], 161 // ["&"], | 161 ["&"], 162 // ["<<", ">>", "<<<", ">>>"], | 162 ["<<", ">>", "<<<", ">>>"], 163 ["+","-"], 163 ["+","-"], 164 ["~"], 164 ["~"], 165 ["*","/","%"], 165 ["*","/","%"], 166 // ["^^","**"], | 166 ["^^","**"], 167 [".",".?"] 167 [".",".?"] 168 ]; 168 ]; 169 169 170 AST E(size_t level) 170 AST E(size_t level) 171 { 171 { 172 /// Expression ::= (Binary left-associative operators over) Func 172 /// Expression ::= (Binary left-associative operators over) Func 173 173
Modified polemy/runtime.d from [6af5a0863b67aa85] to [641d49d7fd647519].
> 1 1 /** 2 /** 2 * Authors: k.inaba 3 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 5 * 5 * Runtime library for Polemy programming language. 6 * Runtime library for Polemy programming language. 6 */ 7 */ 7 module polemy.runtime; 8 module polemy.runtime; 8 import polemy._common; 9 import polemy._common; 9 import polemy.layer; 10 import polemy.layer; > 11 import polemy.failure; 10 import polemy.value; 12 import polemy.value; 11 import polemy.eval; 13 import polemy.eval; 12 import std.stdio; 14 import std.stdio; 13 15 14 /// enroll the native implementations of primitive functions 16 /// enroll the native implementations of primitive functions 15 17 16 void enrollRuntimeLibrary( Evaluator e ) 18 void enrollRuntimeLibrary( Evaluator e ) 17 { 19 { > 20 // arithmetic operations > 21 e.addPrimitive("+", ValueLayer, 18 e.addPrimitive("+", ValueLayer, (IntValue lhs, IntValue rhs){return new | 22 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data + rhs. > 23 e.addPrimitive("-", ValueLayer, 19 e.addPrimitive("-", ValueLayer, (IntValue lhs, IntValue rhs){return new | 24 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data - rhs. > 25 e.addPrimitive("*", ValueLayer, 20 e.addPrimitive("*", ValueLayer, (IntValue lhs, IntValue rhs){return new | 26 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data * rhs. > 27 e.addPrimitive("/", ValueLayer, > 28 (IntValue lhs, IntValue rhs){ > 29 if( rhs.data == 0 ) > 30 throw genex!RuntimeException("division by 0"); 21 e.addPrimitive("/", ValueLayer, (IntValue lhs, IntValue rhs){return new | 31 return new IntValue(lhs.data / rhs.data); > 32 }); > 33 e.addPrimitive("%", ValueLayer, 22 e.addPrimitive("%", ValueLayer, (IntValue lhs, IntValue rhs){return new | 34 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data % rhs. 23 e.addPrimitive("~", ValueLayer, (Value lhs, Value rhs){return new StrVa < > 35 e.addPrimitive("||", ValueLayer, 24 e.addPrimitive("||", ValueLayer, (IntValue lhs, IntValue rhs){return new | 36 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data!=0 || > 37 e.addPrimitive("&&", ValueLayer, 25 e.addPrimitive("&&", ValueLayer, (IntValue lhs, IntValue rhs){return new | 38 (IntValue lhs, IntValue rhs){return new IntValue(lhs.data!=0 && > 39 // string operation(s) > 40 e.addPrimitive("~", ValueLayer, > 41 (Value lhs, Value rhs){return new StrValue(lhs.toString ~ rhs.to > 42 // comparison 26 e.addPrimitive("<", ValueLayer, (Value lhs, Value rhs){return new IntVa 43 e.addPrimitive("<", ValueLayer, (Value lhs, Value rhs){return new IntVa 27 e.addPrimitive(">", ValueLayer, (Value lhs, Value rhs){return new IntVa 44 e.addPrimitive(">", ValueLayer, (Value lhs, Value rhs){return new IntVa 28 e.addPrimitive("<=", ValueLayer, (Value lhs, Value rhs){return new IntVa 45 e.addPrimitive("<=", ValueLayer, (Value lhs, Value rhs){return new IntVa 29 e.addPrimitive(">=", ValueLayer, (Value lhs, Value rhs){return new IntVa 46 e.addPrimitive(">=", ValueLayer, (Value lhs, Value rhs){return new IntVa 30 e.addPrimitive("==", ValueLayer, (Value lhs, Value rhs){return new IntVa 47 e.addPrimitive("==", ValueLayer, (Value lhs, Value rhs){return new IntVa 31 e.addPrimitive("!=", ValueLayer, (Value lhs, Value rhs){return new IntVa 48 e.addPrimitive("!=", ValueLayer, (Value lhs, Value rhs){return new IntVa 32 e.addPrimitive("print", ValueLayer, (Value a){ | 49 // control flow 33 writeln(a); < 34 return new IntValue(0); < 35 }); < 36 e.addPrimitive("if", ValueLayer, (IntValue x, FunValue ft, FunValue fe){ 50 e.addPrimitive("if", ValueLayer, (IntValue x, FunValue ft, FunValue fe){ 37 auto toRun = (x.data==0 ? fe : ft); 51 auto toRun = (x.data==0 ? fe : ft); 38 // [TODO] fill positional information < 39 return toRun.invoke(ValueLayer, toRun.definitionContext(), null) 52 return toRun.invoke(ValueLayer, toRun.definitionContext(), null) 40 }); 53 }); > 54 // type test > 55 e.addPrimitive("_isint", ValueLayer, 41 e.addPrimitive("_isint", ValueLayer, (Value v){return new IntValue(cast( | 56 (Value v){return new IntValue(cast(IntValue)v !is null);} ); > 57 e.addPrimitive("_isstr", ValueLayer, 42 e.addPrimitive("_isstr", ValueLayer, (Value v){return new IntValue(cast( | 58 (Value v){return new IntValue(cast(StrValue)v !is null);} ); > 59 e.addPrimitive("_isfun", ValueLayer, 43 e.addPrimitive("_isfun", ValueLayer, (Value v){return new IntValue(cast( | 60 (Value v){return new IntValue(cast(FunValue)v !is null);} ); > 61 e.addPrimitive("_isundefined", ValueLayer, 44 e.addPrimitive("_isundefined", ValueLayer, (Value v){return new IntValue | 62 (Value v){return new IntValue(cast(UndefinedValue)v !is null);} > 63 e.addPrimitive("_istable", ValueLayer, 45 e.addPrimitive("_istable", ValueLayer, (Value v){return new IntValue(cas | 64 (Value v){return new IntValue(cast(Table)v !is null);} ); > 65 // table 46 e.addPrimitive(".", ValueLayer, (Table t, StrValue s){ 66 e.addPrimitive(".", ValueLayer, (Table t, StrValue s){ 47 return (t.has(s.data, ValueLayer) ? t.get(s.data, ValueLayer) : 67 return (t.has(s.data, ValueLayer) ? t.get(s.data, ValueLayer) : 48 }); 68 }); 49 e.addPrimitive(".?", ValueLayer, (Table t, StrValue s){ 69 e.addPrimitive(".?", ValueLayer, (Table t, StrValue s){ 50 return new IntValue(t.has(s.data, ValueLayer)); 70 return new IntValue(t.has(s.data, ValueLayer)); 51 }); 71 }); 52 e.addPrimitive(".=", ValueLayer, (Table t, StrValue s, Value v){ 72 e.addPrimitive(".=", ValueLayer, (Table t, StrValue s, Value v){ ................................................................................................................................................................................ 53 auto t2 = new Table(t, Table.Kind.NotPropagateSet); 73 auto t2 = new Table(t, Table.Kind.NotPropagateSet); 54 t2.set(s.data, ValueLayer, v); 74 t2.set(s.data, ValueLayer, v); 55 return t2; 75 return t2; 56 }); 76 }); 57 e.addPrimitive("{}", ValueLayer, (){ 77 e.addPrimitive("{}", ValueLayer, (){ 58 return new Table; 78 return new Table; 59 }); 79 }); > 80 // IO > 81 e.addPrimitive("print", ValueLayer, (Value a){ writeln(a); return new In 60 } 82 }
Modified polemy/value.d from [6d85ee04f34c61b7] to [43e26264d772abeb].
75 /// Context (variable environment) 75 /// Context (variable environment) 76 /// Simlar to prototype chain of ECMAScript etc. 76 /// Simlar to prototype chain of ECMAScript etc. 77 /// But extended with the notion of "Layer" 77 /// But extended with the notion of "Layer" 78 78 79 class Table : Value 79 class Table : Value 80 { 80 { 81 enum Kind {PropagateSet, NotPropagateSet}; 81 enum Kind {PropagateSet, NotPropagateSet}; 82 bool kill = false; // to refactor < 83 82 84 this( Table proto=null, Kind k = Kind.PropagateSet ) 83 this( Table proto=null, Kind k = Kind.PropagateSet ) 85 { this.prototype = proto; this.kind = k; } 84 { this.prototype = proto; this.kind = k; } 86 85 87 void set(string i, Layer lay, Value v, LexPosition pos=null) | 86 void set(string i, Layer lay, Value v) 88 { 87 { 89 if( setIfExist(i, lay, v) ) 88 if( setIfExist(i, lay, v) ) 90 return; 89 return; 91 data[i][lay] = v; 90 data[i][lay] = v; 92 } 91 } 93 92 94 bool has(string i, Layer lay) const 93 bool has(string i, Layer lay) const 95 { 94 { 96 if( i in data ) { | 95 if( i in data ) 97 if( lay !in data[i] ) | 96 return !!(lay in data[i]); 98 return false; < 99 if(kill) < 100 return false; < 101 return true; < 102 } < 103 if( prototype is null ) 97 if( prototype is null ) 104 return false; 98 return false; 105 return prototype.has(i, lay); 99 return prototype.has(i, lay); 106 } 100 } 107 101 108 Value get(string i, Layer lay, LexPosition pos=null) 102 Value get(string i, Layer lay, LexPosition pos=null) 109 { 103 { 110 if( i in data ) { 104 if( i in data ) { 111 // [TODO] consider forwarding to proto also in this case 105 // [TODO] consider forwarding to proto also in this case 112 if( lay !in data[i] ) 106 if( lay !in data[i] ) 113 throw genex!RuntimeException(pos, sprintf!"'%s' | 107 throw genex!RuntimeException(pos, sprintf!"'%s' 114 if(kill) < 115 throw genex!RuntimeException(pos, sprintf!"'%s' < 116 return data[i][lay]; 108 return data[i][lay]; 117 } 109 } 118 if( prototype is null ) 110 if( prototype is null ) 119 throw new RuntimeException(pos, sprintf!"'%s' not found" | 111 throw genex!RuntimeException(pos, sprintf!"'%s' not foun 120 return prototype.get(i, lay, pos); 112 return prototype.get(i, lay, pos); 121 } 113 } 122 114 123 T access(T,S...)( Layer lay, string path, S rest ) 115 T access(T,S...)( Layer lay, string path, S rest ) 124 { 116 { 125 static if( rest.length == 0 ) 117 static if( rest.length == 0 ) 126 { 118 { ................................................................................................................................................................................ 155 { 147 { 156 result ~= " / "; 148 result ~= " / "; 157 result ~= prototype.toStringWithoutParen(); 149 result ~= prototype.toStringWithoutParen(); 158 } 150 } 159 return result; 151 return result; 160 } 152 } 161 153 162 string toString() const | 154 string toString() 163 { 155 { > 156 if( isList() ) > 157 return text(toList()); 164 return "{" ~ toStringWithoutParen() ~ "}"; 158 return "{" ~ toStringWithoutParen() ~ "}"; 165 } 159 } > 160 > 161 public: > 162 /// Is this an empty table? > 163 bool empty() > 164 { > 165 return data.length==0 && (prototype is null || prototype.empty); > 166 } > 167 > 168 /// Can be seen as a cons-list? > 169 bool isList() > 170 { > 171 Table t = this; > 172 while(t.has("car", ValueLayer) && t.has("cdr", ValueLayer)) > 173 if(auto tt = cast(Table)t.get("cdr", ValueLayer)) > 174 t = tt; > 175 else > 176 return false; > 177 return t.empty; > 178 } > 179 > 180 /// Regard table as a cons-list and convert to an array > 181 Value[] toList() > 182 { > 183 Value[] result; > 184 Table t = this; > 185 while(t.has("car", ValueLayer) && t.has("cdr", ValueLayer)) > 186 { > 187 result ~= t.get("car", ValueLayer); > 188 if(auto tt = cast(Table)t.get("cdr", ValueLayer)) > 189 t = tt; > 190 else > 191 throw genex!RuntimeException("this table is not > 192 } > 193 if( t.empty ) > 194 return result; > 195 throw genex!RuntimeException("this table is not a cons-list"); > 196 } 166 197 167 private: 198 private: 168 Table prototype; 199 Table prototype; 169 Kind kind; 200 Kind kind; 170 Value[Layer][string] data; 201 Value[Layer][string] data; 171 202 172 bool setIfExist(string i, Layer lay, Value v) 203 bool setIfExist(string i, Layer lay, Value v) ................................................................................................................................................................................ 185 unittest 216 unittest 186 { 217 { 187 Table c0 = new Table; 218 Table c0 = new Table; 188 Table c01 = new Table(c0, Table.Kind.NotPropagateSet); 219 Table c01 = new Table(c0, Table.Kind.NotPropagateSet); 189 Table c012 = new Table(c01, Table.Kind.PropagateSet); 220 Table c012 = new Table(c01, Table.Kind.PropagateSet); 190 Table c013 = new Table(c01, Table.Kind.PropagateSet); 221 Table c013 = new Table(c01, Table.Kind.PropagateSet); 191 222 192 assert_nothrow( c012.set("x", ValueLayer, new IntValue(BigInt(12))) ); | 223 assert_nothrow( c012.set("x", ValueLayer, new IntValue(12)) ); 193 assert_throw!RuntimeException( c013.get("x", ValueLayer) ); 224 assert_throw!RuntimeException( c013.get("x", ValueLayer) ); 194 assert_nothrow( c013.set("x", ValueLayer, new IntValue(BigInt(13))) ); | 225 assert_nothrow( c013.set("x", ValueLayer, new IntValue(13)) ); 195 assert_eq( c013.get("x", ValueLayer), new IntValue(BigInt(13)) ); | 226 assert_eq( c013.get("x", ValueLayer), new IntValue(13) ); 196 assert_eq( c012.get("x", ValueLayer), new IntValue(BigInt(12)) ); | 227 assert_eq( c012.get("x", ValueLayer), new IntValue(12) ); 197 assert_throw!RuntimeException( c01.get("x", ValueLayer) ); 228 assert_throw!RuntimeException( c01.get("x", ValueLayer) ); 198 229 199 assert_nothrow( c01.set("y", ValueLayer, new IntValue(BigInt(1))) ); | 230 assert_nothrow( c01.set("y", ValueLayer, new IntValue(1)) ); 200 assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(1)) ); | 231 assert_eq( c013.get("y", ValueLayer), new IntValue(1) ); 201 assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(1)) ); | 232 assert_eq( c012.get("y", ValueLayer), new IntValue(1) ); 202 assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(1)) ); | 233 assert_eq( c01.get("y", ValueLayer), new IntValue(1) ); > 234 > 235 assert_nothrow( c0.set("z", ValueLayer, new IntValue(0)) ); > 236 assert_eq( c013.get("z", ValueLayer), new IntValue(0) ); > 237 assert_eq( c012.get("z", ValueLayer), new IntValue(0) ); > 238 assert_eq( c01.get("z", ValueLayer), new IntValue(0) ); > 239 assert_eq( c0.get("z", ValueLayer), new IntValue(0) ); 203 240 204 assert_nothrow( c0.set("z", ValueLayer, new IntValue(BigInt(0))) ); | 241 assert_nothrow( c012.set("y", ValueLayer, new IntValue(444)) ); 205 assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 242 assert_eq( c013.get("y", ValueLayer), new IntValue(444) ); 206 assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(0)) ); < 207 assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 243 assert_eq( c012.get("y", ValueLayer), new IntValue(444) ); 208 assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 244 assert_eq( c01.get("y", ValueLayer), new IntValue(444) ); 209 245 210 assert_nothrow( c012.set("y", ValueLayer, new IntValue(BigInt(444))) ); < 211 assert_eq( c013.get("y", ValueLayer), new IntValue(BigInt(444)) ); < 212 assert_eq( c012.get("y", ValueLayer), new IntValue(BigInt(444)) ); < 213 assert_eq( c01.get("y", ValueLayer), new IntValue(BigInt(444)) ); < 214 < 215 assert_nothrow( c012.set("z", ValueLayer, new IntValue(BigInt(555))) ); | 246 assert_nothrow( c012.set("z", ValueLayer, new IntValue(555)) ); 216 assert_eq( c013.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 247 assert_eq( c013.get("z", ValueLayer), new IntValue(0) ); 217 assert_eq( c012.get("z", ValueLayer), new IntValue(BigInt(555)) ); | 248 assert_eq( c012.get("z", ValueLayer), new IntValue(555) ); 218 assert_eq( c01.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 249 assert_eq( c01.get("z", ValueLayer), new IntValue(0) ); 219 assert_eq( c0.get("z", ValueLayer), new IntValue(BigInt(0)) ); | 250 assert_eq( c0.get("z", ValueLayer), new IntValue(0) ); 220 251 221 // [TODO] define the semantics and test @layers 252 // [TODO] define the semantics and test @layers 222 } 253 }
Modified polemy/valueconv.d from [76bd90b6c3824480] to [2816a291e16d0986].
10 import polemy.ast; 10 import polemy.ast; 11 import polemy.layer; 11 import polemy.layer; 12 import polemy.value; 12 import polemy.value; 13 import std.string; 13 import std.string; 14 14 15 LexPosition extractPos( Table t ) 15 LexPosition extractPos( Table t ) 16 { 16 { 17 Layer theLayer = ValueLayer; < 18 if(auto tt = t.access!Table(theLayer, "pos")) | 17 if(auto tt = t.access!Table(ValueLayer, "pos")) 19 { 18 { 20 auto fn = tt.access!StrValue(theLayer, "filename"); | 19 auto fn = tt.access!StrValue(ValueLayer, "filename"); 21 auto ln = tt.access!IntValue(theLayer, "lineno"); | 20 auto ln = tt.access!IntValue(ValueLayer, "lineno"); 22 auto cl = tt.access!IntValue(theLayer, "column"); | 21 auto cl = tt.access!IntValue(ValueLayer, "column"); 23 if(fn !is null && ln !is null && cl !is null) 22 if(fn !is null && ln !is null && cl !is null) 24 return new LexPosition(fn.data,cast(int)ln.data.toInt,ca 23 return new LexPosition(fn.data,cast(int)ln.data.toInt,ca 25 } 24 } 26 return null; 25 return null; 27 } 26 } 28 27 29 Value[] tableAsConsList( Layer theLayer, Table t ) | 28 /// Experimental!! Convert Polemy value to D Value 30 { < 31 Value[] result; < 32 while(t) < 33 if(auto v = t.access!Value(theLayer, "car")) < 34 { < 35 result ~= v; < 36 t = t.access!Table(theLayer, "cdr"); < 37 } < 38 else < 39 break; < 40 return result; < 41 } < 42 29 43 AST[] tableToASTList( Layer theLayer, Table t ) | 30 T polemy2d(T)(Value _v, LexPosition callpos=null) 44 { 31 { 45 AST[] result; | 32 static if(is(T==BigInt)) 46 foreach(v; tableAsConsList(theLayer, t)) < > 33 { 47 if(auto t = cast(Table)v) | 34 if(auto v = cast(IntValue)_v) 48 result ~= tableToAST(theLayer,t); | 35 return v.data; > 36 } 49 else | 37 else 50 throw genex!RuntimeException(cast(LexPosition)null, "Inv < > 38 static if(isIntegral!(T)) > 39 { > 40 if(auto v = cast(IntValue)_v) > 41 return cast(T) v.data.toLong(); > 42 } > 43 else > 44 static if(is(T==string)) > 45 { > 46 if(auto v = cast(StrValue)_v) > 47 return v.data; > 48 } > 49 else > 50 static if(is(T S : S[])) > 51 { > 52 if(auto t = cast(Table)_v) > 53 { > 54 S[] result; > 55 foreach(e; t.toList()) > 56 result ~= polemy2d!(S)(e, callpos); 51 return result; | 57 return result; 52 } | 58 } > 59 } > 60 else > 61 static if(is(T == AST)) > 62 { > 63 if(auto t = cast(Table)_v) > 64 { > 65 LexPosition pos = extractPos(t); 53 66 54 AST tableToAST( Layer theLayer, Value vvvv ) | 67 StrValue typ = cast(StrValue) t.access!StrValue(ValueLay 55 { < 56 Table t = cast(Table)vvvv; < 57 if( t is null ) | 68 if( typ is null ) 58 throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST | 69 throw genex!RuntimeException(text(`Invalid AST ( 59 70 60 auto nodeType = t.access!StrValue(theLayer, "is"); | 71 foreach(AT; ListOfASTTypes) > 72 if(typ.data == typeid(AT).name.split(".")[$-1].t > 73 { > 74 typeof(AT.tupleof) mems; > 75 foreach(i,m; mems) > 76 { > 77 string name = AT.tupleof[i].stri > 78 Value vm = t.access!Value(ValueL 61 if( nodeType is null ) | 79 if( vm is null ) 62 throw genex!RuntimeException(cast(LexPosition)null, "Invalid AST | 80 throw genex!RuntimeExcep 63 auto pos = extractPos(t); < 64 switch(nodeType.data) < > 81 text(`Invalid AS > 82 mems[i] = polemy2d!(typeof(m))(v > 83 } > 84 return new AT(pos,mems); > 85 } > 86 throw genex!RuntimeException(callpos, text(`Invalid AST > 87 } > 88 throw genex!RuntimeException(callpos, text(`Invalid AST (not a t > 89 } > 90 else > 91 static if(is(T == class)) 65 { 92 { 66 case "int": | 93 if(auto t = cast(Table)_v) 67 if(auto v = t.access!IntValue(theLayer, "data")) < 68 return new Int(pos, v.data); < 69 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST < 70 case "str": < 71 if(auto v = t.access!StrValue(theLayer, "data")) < 72 return new Str(pos, v.data); < 73 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST < 74 case "var": < 75 if(auto v = t.access!StrValue(theLayer, "name")) < 76 return new Var(pos, v.data); < 77 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST < 78 case "lay": < 79 if(auto v = t.access!StrValue(theLayer, "layer")) < 80 if(auto e = t.access!Table(theLayer, "expr")) < 81 return new Lay(pos, v.data, tableToAST(theLayer, < 82 else < 83 throw genex!RuntimeException(cast(LexPosition)nu < 84 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST < 85 case "let": < 86 if(auto n = t.access!StrValue(theLayer, "name")) < 87 if(auto e = t.access!Table(theLayer, "init")) < 88 if(auto b = t.access!Table(theLayer, "expr")) < 89 { 94 { 90 string nn = n.data; | 95 typeof(T.tupleof) mems; 91 auto ee = tableToAST(theLayer, e); | 96 foreach(i,m; mems) 92 auto bb = tableToAST(theLayer, b); | 97 mems[i] = polemy2d!(typeof(m))(t.get(T.tupleof[i 93 Layer lay=""; < 94 if(auto l = t.access!StrValue(theLayer, "layer")) < 95 lay = l.data; < 96 return new Let(pos, nn, lay, ee, bb); | 98 return new T(mems); 97 } 99 } 98 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST < 99 case "app": < 100 if(auto f = t.access!Table(theLayer, "fun")) < 101 if(auto a = t.access!Table(theLayer, "args")) < 102 return new App(pos, tableToAST(theLayer,f), tableToASTLi < 103 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST < 104 case "fun": < 105 if(auto p = t.access!Table(theLayer, "params")) < 106 if(auto b = t.access!Table(theLayer, "funbody")) < 107 { < 108 Parameter[] ps; < 109 foreach(v; tableAsConsList(theLayer, p)) < 110 { < 111 if(auto tt = cast(Table)v) < 112 if(auto ss = tt.access!StrValue(theLayer, "name" < 113 if(auto ll = tt.access!Table(theLayer, "layers") < 114 { < 115 Layer[] ls; < 116 foreach(lll; tableAsConsList(theLayer, l < 117 if(auto l = cast(StrValue)lll) < 118 ls ~= l.data; < 119 else < 120 throw genex!RuntimeExcep < 121 ps ~= new Parameter(ss.data, ls); < 122 continue; < 123 } < 124 else < 125 { < 126 Layer[] emp; < 127 ps ~= new Parameter(ss.data, emp); < 128 continue; < 129 } < 130 throw genex!RuntimeException(cast(LexPosition)nu < 131 } < 132 auto bb = tableToAST(theLayer, b); < 133 return new Fun(pos,ps,bb); < 134 } < 135 throw genex!RuntimeException(cast(LexPosition)null, `Invalid AST < 136 default: < 137 throw genex!RuntimeException(cast(LexPosition)null, sprintf!`Inv < 138 } 100 } > 101 else > 102 static assert(false, "unknown type <"~T.stringof~"> during polem > 103 throw genex!RuntimeException(callpos, text("Cannot convert ",_v," to ",T 139 } 104 } 140 105 141 /// Cons of two pairs 106 /// Cons of two pairs 142 107 143 Table makeCons(Value a, Value d) 108 Table makeCons(Value a, Value d) 144 { 109 { 145 Table t = new Table; 110 Table t = new Table; 146 t.set("car", ValueLayer, a); 111 t.set("car", ValueLayer, a); 147 t.set("cdr", ValueLayer, d); 112 t.set("cdr", ValueLayer, d); 148 return t; 113 return t; 149 } 114 } 150 115 151 /// Experimental!!! Convert D value (except AST) to Polemy Value | 116 /// Experimental!! Convert D value (except AST) to Polemy Value 152 117 153 Value d2polemy(T)(T e) 118 Value d2polemy(T)(T e) 154 { 119 { 155 return ast2table(e, delegate Value(AST){ assert(false); }); 120 return ast2table(e, delegate Value(AST){ assert(false); }); 156 } 121 } 157 122 158 /// Convert AST to Table so that it can be used in Polemy 123 /// Convert AST to Table so that it can be used in Polemy ................................................................................................................................................................................ 180 { 145 { 181 assert( typeid(e) == typeid(T), text("abstracted: ", typeid(e), 146 assert( typeid(e) == typeid(T), text("abstracted: ", typeid(e), 182 auto t = new Table; 147 auto t = new Table; 183 t.set("pos", ValueLayer, ast2table(e.pos,rec)); 148 t.set("pos", ValueLayer, ast2table(e.pos,rec)); 184 t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[ 149 t.set("is" , ValueLayer, new StrValue(typeid(e).name.split(".")[ 185 foreach(i,m; e.tupleof) 150 foreach(i,m; e.tupleof) 186 static if(is(typeof(m) : AST)) 151 static if(is(typeof(m) : AST)) 187 t.set(e.tupleof[i].stringof[2..$], ValueLayer, r | 152 t.set(e.tupleof[i].stringof.split(".")[$-1], Val 188 else 153 else 189 t.set(e.tupleof[i].stringof[2..$], ValueLayer, a | 154 t.set(e.tupleof[i].stringof.split(".")[$-1], Val 190 return t; 155 return t; 191 } 156 } 192 else 157 else 193 static if(is(T == class)) 158 static if(is(T == class)) 194 { 159 { 195 auto t = new Table; 160 auto t = new Table; 196 foreach(i,m; e.tupleof) 161 foreach(i,m; e.tupleof)