Overview
SHA1 Hash: | 0569f7b8c23ef9b26e3b3cb4aae86b9fb0dbf2a5 |
---|---|
Date: | 2010-11-07 23:34:29 |
User: | kinaba |
Comment: | - Added function literal evaluator (i.e., closure). - Workaround for d2stacktrace's infinite-loop bug. (when std.demangle.demangle use exception inside it, it will go into an infinite loop. to avoid this, I choose to unset TraceHandler during stacktrace generation. This is far from the complete solution, but at least it should work as expected under single-thread environment...) |
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 d2stacktrace/stacktrace.d from [02abce9abb958e1c] to [059fc11fc8a1312c].
232 info.length = info.length + 1; 232 info.length = info.length + 1; 233 info[info.length-1] = str; 233 info[info.length-1] = str; 234 } 234 } 235 } 235 } 236 } 236 } 237 237 238 static Throwable.TraceInfo TraceHandler(void* ptr){ 238 static Throwable.TraceInfo TraceHandler(void* ptr){ > 239 // modified by k.inaba to avoid a throw inside std.demangle.dema > 240 // not quite thread safe > 241 Runtime.traceHandler(&core.runtime.defaultTraceHandler); > 242 scope(exit) Runtime.traceHandler(&TraceHandler); > 243 239 StackTrace trace = new StackTrace(); | 244 StackTrace trace = new StackTrace(); 240 return trace.GetCallstack(); | 245 return trace.GetCallstack(); 241 } 246 } 242 247 243 public: 248 public: 244 static this(){ 249 static this(){ 245 Runtime.traceHandler(&TraceHandler); 250 Runtime.traceHandler(&TraceHandler); 246 SetUnhandledExceptionFilter(&UnhandeledExceptionFilterHandler); 251 SetUnhandledExceptionFilter(&UnhandeledExceptionFilterHandler); 247 } 252 } ................................................................................................................................................................................ 360 } 365 } 361 } 366 } 362 367 363 free(Symbol); 368 free(Symbol); 364 return stack; 369 return stack; 365 } 370 } 366 }; 371 }; > 372
Modified polemy/_common.d from [0abd8de4d8be4f44] to [935cc3e03ebe462f].
6 */ 6 */ 7 module polemy._common; 7 module polemy._common; 8 public import std.array; 8 public import std.array; 9 public import std.range; 9 public import std.range; 10 public import std.algorithm; 10 public import std.algorithm; 11 public import std.conv : to; 11 public import std.conv : to; 12 public import std.bigint; 12 public import std.bigint; > 13 public import std.exception; 13 public import polemy.tricks; 14 public import polemy.tricks;
Modified polemy/eval.d from [c5ee9ab6830c78bd] to [cea762cacb86424f].
2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 5 * Evaluator for Polemy programming language. 5 * Evaluator for Polemy programming language. 6 */ 6 */ 7 module polemy.eval; 7 module polemy.eval; 8 import polemy._common; 8 import polemy._common; > 9 import polemy.lex : LexPosition; 9 import polemy.ast; 10 import polemy.ast; 10 import polemy.parse; 11 import polemy.parse; 11 import polemy.runtime; 12 import polemy.runtime; > 13 import std.typecons; 12 14 13 Context createGlobalContext() 15 Context createGlobalContext() 14 { 16 { 15 auto ctx = new Context; 17 auto ctx = new Context; 16 ctx.add("+", new PrimitiveFunction(delegate Value(Value[] args){ | 18 ctx.add("+", new FunValue(delegate Value(immutable LexPosition pos, Valu 17 if( args.length != 2 ) 19 if( args.length != 2 ) 18 throw new PolemyRuntimeException("+ takes two arguments! | 20 throw new PolemyRuntimeException("+ takes two arguments! 19 if( auto x = cast(IntValue)args[0] ) 21 if( auto x = cast(IntValue)args[0] ) 20 if( auto y = cast(IntValue)args[1] ) 22 if( auto y = cast(IntValue)args[1] ) 21 return new IntValue(x.data+y.data); 23 return new IntValue(x.data+y.data); 22 throw new PolemyRuntimeException("cannot add non-integers"); // | 24 throw new PolemyRuntimeException("cannot add non-integers ["~to! 23 })); 25 })); 24 ctx.add("-", new PrimitiveFunction(delegate Value(Value[] args){ | 26 ctx.add("-", new FunValue(delegate Value(immutable LexPosition pos, Valu 25 if( args.length != 2 ) 27 if( args.length != 2 ) 26 throw new PolemyRuntimeException("- takes two arguments! | 28 throw new PolemyRuntimeException("- takes two arguments! 27 if( auto x = cast(IntValue)args[0] ) 29 if( auto x = cast(IntValue)args[0] ) 28 if( auto y = cast(IntValue)args[1] ) 30 if( auto y = cast(IntValue)args[1] ) 29 return new IntValue(x.data-y.data); 31 return new IntValue(x.data-y.data); 30 throw new PolemyRuntimeException("cannot add non-integers"); // | 32 throw new PolemyRuntimeException("cannot add non-integers ["~to! 31 })); 33 })); 32 ctx.add("*", new PrimitiveFunction(delegate Value(Value[] args){ | 34 ctx.add("*", new FunValue(delegate Value(immutable LexPosition pos, Valu 33 if( args.length != 2 ) 35 if( args.length != 2 ) 34 throw new PolemyRuntimeException("* takes two arguments! | 36 throw new PolemyRuntimeException("* takes two arguments! 35 if( auto x = cast(IntValue)args[0] ) 37 if( auto x = cast(IntValue)args[0] ) 36 if( auto y = cast(IntValue)args[1] ) 38 if( auto y = cast(IntValue)args[1] ) 37 return new IntValue(x.data*y.data); 39 return new IntValue(x.data*y.data); 38 throw new PolemyRuntimeException("cannot add non-integers"); // | 40 throw new PolemyRuntimeException("cannot add non-integers ["~to! 39 })); 41 })); 40 ctx.add("/", new PrimitiveFunction(delegate Value(Value[] args){ | 42 ctx.add("/", new FunValue(delegate Value(immutable LexPosition pos, Valu 41 if( args.length != 2 ) 43 if( args.length != 2 ) 42 throw new PolemyRuntimeException("/ takes two arguments! | 44 throw new PolemyRuntimeException("/ takes two arguments! 43 if( auto x = cast(IntValue)args[0] ) 45 if( auto x = cast(IntValue)args[0] ) 44 if( auto y = cast(IntValue)args[1] ) 46 if( auto y = cast(IntValue)args[1] ) 45 return new IntValue(x.data/y.data); 47 return new IntValue(x.data/y.data); 46 throw new PolemyRuntimeException("cannot add non-integers"); // | 48 throw new PolemyRuntimeException("cannot add non-integers ["~to! 47 })); 49 })); 48 return ctx; 50 return ctx; 49 } 51 } 50 52 51 Context evalString(T...)(T params) | 53 Tuple!(Value,"val",Context,"ctx") evalString(T...)(T params) 52 { 54 { 53 return eval( parserFromString(params).parseProgram() ); 55 return eval( parserFromString(params).parseProgram() ); 54 } 56 } 55 57 56 Context evalFile(T...)(T params) | 58 Tuple!(Value,"val",Context,"ctx") evalFile(T...)(T params) 57 { 59 { 58 return eval( parserFromFile(params).parseProgram() ); 60 return eval( parserFromFile(params).parseProgram() ); 59 } 61 } 60 62 61 Context eval(Program prog) | 63 Tuple!(Value,"val",Context,"ctx") eval(Program prog) 62 { 64 { 63 return eval(prog, createGlobalContext()); | 65 Context ctx = createGlobalContext(); > 66 return typeof(return)(eval(prog, ctx), ctx); 64 } 67 } 65 68 66 Context eval(Program prog, Context ctx) | 69 Value eval(Program prog, Context ctx) 67 { 70 { > 71 Value v = new UndefinedValue; 68 foreach(s; prog) 72 foreach(s; prog) 69 ctx = eval(s, ctx); | 73 v = eval(s, ctx); 70 return ctx; | 74 return v; 71 } 75 } 72 76 73 Context eval(Statement _s, Context ctx) | 77 Value eval(Statement _s, Context ctx) 74 { 78 { 75 if( auto s = cast(DeclStatement)_s ) 79 if( auto s = cast(DeclStatement)_s ) 76 { 80 { 77 auto v = eval(s.expr, ctx); 81 auto v = eval(s.expr, ctx); 78 ctx.add(s.var, v); 82 ctx.add(s.var, v); 79 return ctx; | 83 return v; 80 } 84 } 81 else 85 else 82 if( auto s = cast(ExprStatement)_s ) 86 if( auto s = cast(ExprStatement)_s ) 83 { 87 { 84 eval(s.expr, ctx); | 88 return eval(s.expr, ctx); 85 return ctx; < 86 } 89 } 87 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Statement %s a 90 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Statement %s a 88 } 91 } 89 92 90 Value eval(Expression _e, Context ctx) 93 Value eval(Expression _e, Context ctx) 91 { 94 { 92 if( auto e = cast(StrLiteralExpression)_e ) 95 if( auto e = cast(StrLiteralExpression)_e ) ................................................................................................................................................................................ 118 if( auto e = cast(FuncallExpression)_e ) 121 if( auto e = cast(FuncallExpression)_e ) 119 { 122 { 120 Value _f = eval(e.fun, ctx); 123 Value _f = eval(e.fun, ctx); 121 if( auto f = cast(FunValue)_f ) { 124 if( auto f = cast(FunValue)_f ) { 122 Value[] args; 125 Value[] args; 123 foreach(a; e.args) 126 foreach(a; e.args) 124 args ~= eval(a, ctx); 127 args ~= eval(a, ctx); 125 return f.call(args); | 128 return f.call(e.pos, args); 126 } else 129 } else 127 throw new PolemyRuntimeException(sprintf!"Non-funcion is 130 throw new PolemyRuntimeException(sprintf!"Non-funcion is > 131 } > 132 else > 133 if( auto e = cast(FunLiteralExpression)_e ) > 134 { > 135 return new FunValue(delegate Value(immutable LexPosition pos, Va > 136 if( e.params.length != args.length ) > 137 throw new PolemyRuntimeException(sprintf!"Argume > 138 (e.params.length, args.length, e.pos)); > 139 Context ctxNeo = new Context(ctx); > 140 foreach(i,p; e.params) > 141 ctxNeo.add(p, args[i]); > 142 return eval(e.funbody, ctxNeo); > 143 }); 128 } 144 } 129 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Expression %s 145 throw new PolemyRuntimeException(sprintf!"Unknown Kind of Expression %s 130 } 146 } 131 147 132 < 133 version(unittest) import polemy.parse; < 134 version(unittest) import std.stdio; | 148 import std.stdio; 135 version(unittest) import std.exception; < 136 unittest 149 unittest 137 { 150 { 138 auto ctx = evalString(`var x = 21; x = x + x*x;`); | 151 auto r = evalString(`var x = 21; x = x + x*x;`); > 152 assert( r.val == new IntValue(BigInt(21+21*21)) ); 139 assert( ctx["x"] == new IntValue(BigInt(21+21*21)) ); | 153 assert( r.ctx["x"] == new IntValue(BigInt(21+21*21)) ); 140 assert( !collectException(ctx["x"]) ); | 154 assert( !collectException(r.ctx["x"]) ); 141 assert( collectException(ctx["y"]) ); | 155 assert( collectException(r.ctx["y"]) ); 142 } 156 } 143 unittest 157 unittest 144 { 158 { 145 assert( collectException(evalString(`var x = 21; x = x + x*y;`)) ); 159 assert( collectException(evalString(`var x = 21; x = x + x*y;`)) ); > 160 assert( collectException(evalString(`x=1;`)) ); > 161 } > 162 unittest > 163 { > 164 auto r = evalString(`var x = fun(a){1+a;}(2);`); > 165 assert( r.ctx["x"] == new IntValue(BigInt(3)) ); > 166 assert( r.val == new IntValue(BigInt(3)) ); 146 } 167 } 147 unittest 168 unittest 148 { 169 { 149 assert( collectException(evalString(`var x = 21; y = x + x*x;`)) ); | 170 auto r = evalString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); f();`); > 171 assert( r.ctx["x"] == new IntValue(BigInt(4)) ); > 172 assert( r.val == new IntValue(BigInt(4)) ); 150 } 173 }
Modified polemy/parse.d from [4856c979362ef435] to [1d6de9cb69bbf7d4].
188 return e; 188 return e; 189 } 189 } 190 190 191 if( tryEat("fun") ) 191 if( tryEat("fun") ) 192 { 192 { 193 eat("(", "after fun"); 193 eat("(", "after fun"); 194 string[] params; 194 string[] params; 195 for(;;) | 195 while(!tryEat(")")) 196 { 196 { 197 if( lex.empty ) { 197 if( lex.empty ) { 198 auto e = ParserException.create(lex,"Une 198 auto e = ParserException.create(lex,"Une 199 throw e; 199 throw e; 200 } 200 } 201 if( lex.front.kind != Token.Kind.identifier ) { 201 if( lex.front.kind != Token.Kind.identifier ) { 202 auto e = ParserException.create(lex,"Ide 202 auto e = ParserException.create(lex,"Ide ................................................................................................................................................................................ 306 new IntLiteralExpression(null, BigInt(1)), 306 new IntLiteralExpression(null, BigInt(1)), 307 new FuncallExpression(null, 307 new FuncallExpression(null, 308 new FunLiteralExpression(null, ["abc"], [ 308 new FunLiteralExpression(null, ["abc"], [ 309 ]), 309 ]), 310 new IntLiteralExpression(null, BigInt(4)) 310 new IntLiteralExpression(null, BigInt(4)) 311 )))); 311 )))); 312 } 312 } > 313 unittest > 314 { > 315 auto p = parserFromString(`var x = 1; var f = fun(){x=x+1;}; f(); f(); x > 316 Program prog = p.parseProgram(); > 317 }
Modified polemy/runtime.d from [c94ffd3733368117] to [eb7f695558db6c0f].
2 * Authors: k.inaba 2 * Authors: k.inaba 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 * 4 * 5 * Runtime data structures for Polemy programming language. 5 * Runtime data structures for Polemy programming language. 6 */ 6 */ 7 module polemy.runtime; 7 module polemy.runtime; 8 import polemy._common; 8 import polemy._common; > 9 import polemy.lex : LexPosition; > 10 import std.stdio; 9 11 10 class PolemyRuntimeException : Exception 12 class PolemyRuntimeException : Exception 11 { 13 { 12 this(string msg) { super(msg); } 14 this(string msg) { super(msg); } 13 } 15 } 14 16 15 abstract class Value 17 abstract class Value 16 { 18 { 17 } 19 } > 20 > 21 class UndefinedValue : Value > 22 { > 23 mixin SimpleConstructor; > 24 mixin SimpleCompare; > 25 } 18 26 19 class IntValue : Value 27 class IntValue : Value 20 { 28 { 21 BigInt data; 29 BigInt data; 22 mixin SimpleConstructor; 30 mixin SimpleConstructor; 23 mixin SimpleCompare; 31 mixin SimpleCompare; 24 } 32 } ................................................................................................................................................................................ 26 class StrValue : Value 34 class StrValue : Value 27 { 35 { 28 string data; 36 string data; 29 mixin SimpleConstructor; 37 mixin SimpleConstructor; 30 mixin SimpleCompare; 38 mixin SimpleCompare; 31 } 39 } 32 40 33 abstract class FunValue : Value | 41 class FunValue : Value 34 { 42 { 35 Value call(Value[] args); | 43 Value delegate(immutable LexPosition pos, Value[]) data; > 44 mixin SimpleConstructor; > 45 Value call(immutable LexPosition pos, Value[] args) { return data(pos,ar 36 } 46 } 37 < 38 class PrimitiveFunction : FunValue < 39 { < 40 Value delegate(Value[]) data; < 41 mixin SimpleConstructor; < 42 override Value call(Value[] args) { return data(args); } < 43 } < 44 < > 47 import std.stdio; 45 class Context 48 class Context 46 { 49 { 47 Context parent; 50 Context parent; 48 Value[string] table; 51 Value[string] table; 49 this(Context parent = null) { this.parent = parent; } 52 this(Context parent = null) { this.parent = parent; } 50 53 51 void add(string i, Value v) 54 void add(string i, Value v)
Modified polemy/tricks.d from [193cf29f54393c6e] to [16f826d18ff480be].
26 /// Mixing-in the bean constructor for a class 26 /// Mixing-in the bean constructor for a class 27 27 28 /*mixin*/ template SimpleConstructor() 28 /*mixin*/ template SimpleConstructor() 29 { 29 { 30 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 30 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 31 this( typeof(this.tupleof) params ) 31 this( typeof(this.tupleof) params ) 32 { 32 { > 33 static if(this.tupleof.length>0) 33 this.tupleof = params; | 34 this.tupleof = params; 34 } 35 } 35 else 36 else 36 // this parameter list is not always desirable but should work f 37 // this parameter list is not always desirable but should work f 37 this( typeof(super.tupleof) ps, typeof(this.tupleof) params ) 38 this( typeof(super.tupleof) ps, typeof(this.tupleof) params ) 38 { 39 { 39 super(ps); 40 super(ps); > 41 static if(this.tupleof.length>0) 40 this.tupleof = params; | 42 this.tupleof = params; 41 } 43 } 42 } 44 } 43 45 44 /// Mixing-in the (MOST-DERIVED) member-wise comparator for a class 46 /// Mixing-in the (MOST-DERIVED) member-wise comparator for a class 45 47 46 /*mixin*/ template SimpleCompare() 48 /*mixin*/ template SimpleCompare() 47 { 49 {