Index: d2stacktrace/stacktrace.d ================================================================== --- d2stacktrace/stacktrace.d +++ d2stacktrace/stacktrace.d @@ -31,10 +31,11 @@ import core.runtime; import std.stdio; import std.c.stdlib; import std.demangle; import std.conv; +import std.path; extern(Windows){ DWORD GetEnvironmentVariableA(LPCSTR lpName, LPSTR pBuffer, DWORD nSize); void RtlCaptureContext(CONTEXT* ContextRecord); typedef LONG function(void*) UnhandeledExceptionFilterFunc; @@ -335,24 +336,29 @@ if(stackframe.AddrPC.Offset != 0){ string lineStr = ""; Dbghelp.DWORD64 offsetFromSymbol = cast(Dbghelp.DWORD64)0; if( Dbghelp.SymGetSymFromAddr64(hProcess,stackframe.AddrPC.Offset,&offsetFromSymbol,Symbol) == TRUE){ - char[] symName = new char[strlen(cast(const(char)*)Symbol.Name.ptr)+1]; + char[] symName = new char[strlen(cast(const(char)*)Symbol.Name.ptr)]; memcpy(symName.ptr,Symbol.Name.ptr,symName.length); string symString = ""; if(symName[0] == 'D') symString = "_"; symString ~= symName; - string demangeledName = demangle(symString); - lineStr ~= demangeledName; + string demangledName = demangle(symString); + bool isOK = true; + for(int i=0; i= 0x80 ) + isOK = false; + if(isOK) + lineStr ~= demangledName; DWORD zeichen = 0; if(Dbghelp.SymGetLineFromAddr64(hProcess,stackframe.AddrPC.Offset,&zeichen,&Line) == TRUE){ char[] fileName = new char[strlen(Line.FileName)]; - fileName[] = Line.FileName[0..fileName.length]; + fileName = std.path.basename( Line.FileName[0..fileName.length] ); lineStr = to!string(fileName ~ "::" ~ to!string(Line.LineNumber) ~ "(" ~ to!string(zeichen) ~ ") " ~ lineStr); } } else { lineStr = to!string(cast(ulong)stackframe.AddrPC.Offset); Index: main.d ================================================================== --- main.d +++ main.d @@ -20,10 +20,14 @@ string buf; Value lastVal; int lineno = 1; int nextlineno = 1; this() { ctx = createGlobalContext(); } + this(string filename) { + ctx = createGlobalContext(); + eval(parseFile(filename), ctx, false, "@v"); + } bool tryRun( string s ) { scope(failure) { buf = ""; lineno = nextlineno; } @@ -54,18 +58,24 @@ return true; } } /// Entry point. If args.length==1, invoke REPL. +/// If args.length==3 && args[1]=="-l" read args[2] and invoke REPL. /// Otherwise interpret the argument as a filename. void main( string[] args ) { if( args.length <= 1 ) { writeln("Welcome to Polemy 0.1.0"); for(auto r = new REPL; r.singleInteraction();) {} } + else if( args.length>=3 && args[1]=="-l" ) + { + writeln("Welcome to Polemy 0.1.0"); + for(auto r = new REPL(args[2]); r.singleInteraction();) {} + } else { evalFile(args[1]); } } Index: polemy/_common.d ================================================================== --- polemy/_common.d +++ polemy/_common.d @@ -11,5 +11,6 @@ public import std.conv : to; public import std.bigint; public import std.exception; public import tricks.tricks; public import tricks.test; +public import std.stdio : writeln; // for debugging... Index: polemy/eval.d ================================================================== --- polemy/eval.d +++ polemy/eval.d @@ -75,10 +75,11 @@ throw genex!RuntimeException(pos, "type mismatch in if"); })); ctx.set("_isint", "@v", native( (Value v){return new IntValue(BigInt(cast(IntValue)v is null ? 0 : 1));} )); ctx.set("_isstr", "@v", native( (Value v){return new IntValue(BigInt(cast(StrValue)v is null ? 0 : 1));} )); ctx.set("_isfun", "@v", native( (Value v){return new IntValue(BigInt(cast(FunValue)v is null ? 0 : 1));} )); + ctx.set("_isundefined", "@v", native( (Value v){return new IntValue(BigInt(cast(UndValue)v is null ? 0 : 1));} )); return ctx; } /// Entry point of this module @@ -163,19 +164,38 @@ } throw genex!RuntimeException(e.pos, "Non-funcion is applied"); }, (FunLiteral e) { - // funvalue need not be rised - return new FunValue(delegate Value(immutable LexPosition pos, string lay, Value[] args){ + Value[Value[]][Layer] memo; + + // funvalue need not be rised + // no, need to be rised !! suppose @t(fib)("int") + return new FunValue(delegate Value(immutable LexPosition pos, string lay, Value[] args){ + // TODO: only auto raised ones need memo? no? + // auto memoization + if( lay != "@v" ) + { + if( auto memolay = lay in memo ) + if( auto pv = args in *memolay ) + return *pv; + memo[lay][args] = (cast(FunValue)ctx.get(lay, "(system)", e.pos)).call(e.pos, "@v", + [new UndValue] + ); + } + if( e.params.length != args.length ) throw genex!RuntimeException(e.pos, sprintf!"Argument Number Mismatch (%d required but %d given)" (e.params.length, args.length)); Table ctxNeo = new Table(ctx, Table.Kind.NotPropagateSet); foreach(i,p; e.params) ctxNeo.set(p.name, lay, args[i]); - return eval(e.funbody, ctxNeo, true, lay); + auto v = eval(e.funbody, ctxNeo, true, lay); + // auto memoization + if( lay != "@v" ) + memo[lay][args] = v; + return v; }); }, delegate Value (AST e) { throw genex!RuntimeException(e.pos, sprintf!"Unknown Kind of Expression %s"(typeid(e))); Index: polemy/value.d ================================================================== --- polemy/value.d +++ polemy/value.d @@ -43,10 +43,16 @@ mixin SimpleConstructor; alias data call; override string toString() const { return sprintf!"(function:%s:%s)"(data.ptr,data.funcptr); } } + +class UndValue : Value +{ + mixin SimpleClass; + override string toString() const { return ""; } +} /// Layer ID alias string Layer; @@ -68,15 +74,18 @@ data[i][lay] = v; } Value get(string i, Layer lay, in LexPosition pos=null) { - if( i in data ) + if( i in data ) { + if( lay !in data[i] ) + throw genex!RuntimeException(pos, sprintf!"variable %s is not set in layer %s"(i,lay)); return data[i][lay]; + } if( prototype is null ) throw new RuntimeException(pos, sprintf!"variable %s not found"(i)); - return prototype.get(i, lay); + return prototype.get(i, lay, pos); } private: Table prototype; Kind kind; ADDED sample/type.pmy Index: sample/type.pmy ================================================================== --- sample/type.pmy +++ sample/type.pmy @@ -0,0 +1,28 @@ +@@type = fun(x){ + if( _isint(x) ) { "int" } + else { if( _isstr(x) ) { "str" } + else { if( _isfun(x) ) { x } + else { if( _isundefined(x) ) { "undefined" } + else { "any" }}}} +}; + +def binop(a,b,c) { + fun(x,y){@v( + if( @type(x)=="undefined" || @type(y)=="undefined" ) { "undefined" } else { + if( @type(x)==a && @type(y)==b ) { c } else { "error" } + } + )} +}; + +@type "+" = binop("int", "int", "int"); +@type "-" = binop("int", "int", "int"); +@type "<" = binop("int", "int", "int"); +@type ">" = binop("int", "int", "int"); + +def mergeType(a,b) { + if( a == "undefined" ) { if(b=="undefined"){"error"}else{b} } else { a } +}; + +@type "if" = fun(c,t,e) {@v( + if(@type(c)=="int" ) { mergeType(@type(t()), @type(e())) } else { "error" } +)};