diff --git a/hscript/Bytes.hx b/hscript/Bytes.hx index e11443a..1c8df52 100644 --- a/hscript/Bytes.hx +++ b/hscript/Bytes.hx @@ -74,6 +74,13 @@ class Bytes { return strings[id]; } + function doEncodeInt(v: Int) { + bout.addByte(v & 0xFF); + bout.addByte((v >> 8) & 0xFF); + bout.addByte((v >> 16) & 0xFF); + bout.addByte(v >>> 24); + } + function doEncodeConst( c : Const ) { switch( c ) { case CInt(v): @@ -82,10 +89,7 @@ class Bytes { bout.addByte(v); } else { bout.addByte(1); - bout.addByte(v & 0xFF); - bout.addByte((v >> 8) & 0xFF); - bout.addByte((v >> 16) & 0xFF); - bout.addByte(v >>> 24); + doEncodeInt(v); } #if !haxe3 case CInt32(v): @@ -105,13 +109,18 @@ class Bytes { } } + function doDecodeInt() { + var i = bin.get(pin) | (bin.get(pin+1) << 8) | (bin.get(pin+2) << 16) | (bin.get(pin+3) << 24); + pin += 4; + return i; + } + function doDecodeConst() { return switch( bin.get(pin++) ) { case 0: CInt(bin.get(pin++)); case 1: - var i = bin.get(pin) | (bin.get(pin+1) << 8) | (bin.get(pin+2) << 16) | (bin.get(pin+3) << 24); - pin += 4; + var i = doDecodeInt(); CInt(i); case 2: CFloat( Std.parseFloat(doDecodeString()) ); @@ -131,6 +140,8 @@ class Bytes { function doEncode( e : Expr ) { #if hscriptPos + doEncodeString(e.origin); + doEncodeInt(e.line); var e = e.e; #end bout.addByte(Type.enumIndex(e)); @@ -241,7 +252,9 @@ class Bytes { function doDecode() : Expr { #if hscriptPos - return { e : _doDecode(), pmin : 0, pmax : 0 }; + var origin = doDecodeString(); + var line = doDecodeInt(); + return { e : _doDecode(), pmin : 0, pmax : 0, origin : origin, line : line }; } function _doDecode() : ExprDef { #end @@ -371,4 +384,4 @@ class Bytes { return b.doDecode(); } -} \ No newline at end of file +} diff --git a/hscript/Expr.hx b/hscript/Expr.hx index a84e69d..633c7d4 100644 --- a/hscript/Expr.hx +++ b/hscript/Expr.hx @@ -38,6 +38,8 @@ typedef Expr = { var e : ExprDef; var pmin : Int; var pmax : Int; + var origin : String; + var line : Int; } enum ExprDef { #else @@ -84,10 +86,48 @@ class Error { public var e : ErrorDef; public var pmin : Int; public var pmax : Int; - public function new(e, pmin, pmax) { + public var origin : String; + public var line : Int; + public function new(e, pmin, pmax, origin, line) { this.e = e; this.pmin = pmin; this.pmax = pmax; + this.origin = origin; + this.line = line; + } + + private function errorDefToString(): String { + switch (e) { + case EInvalidChar(c): + return "Invalid character: '"+c+"'"; + + case EUnexpected(s): + return "Unexpected token: \""+s+"\""; + + case EUnterminatedString: + return "Unterminated string"; + + case EUnterminatedComment: + return "Unterminated comment"; + + case EUnknownVariable(v): + return "Unknown variable: "+v; + + case EInvalidIterator(v): + return "Invalid iterator: "+v; + + case EInvalidOp(op): + return "Invalid operator: "+op; + + case EInvalidAccess(f): + return "Invalid access to field "+f; + } + } + + public function toString(): String { + var message = errorDefToString(); + message = origin + ":" + line + ": " + message; + return message; } } enum ErrorDef { diff --git a/hscript/Interp.hx b/hscript/Interp.hx index ab6455c..27fdc6a 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -23,6 +23,7 @@ * DAMAGE. */ package hscript; +import haxe.PosInfos; import hscript.Expr; private enum Stop { @@ -63,10 +64,18 @@ class Interp { variables.set("null",null); variables.set("true",true); variables.set("false",false); - variables.set("trace",function(e) haxe.Log.trace(Std.string(e),cast { fileName : "hscript", lineNumber : 0 })); + variables.set("trace",function(e) haxe.Log.trace(Std.string(e), posInfos())); initOps(); } + public function posInfos(): PosInfos { + #if hscriptPos + if (curExpr != null) + return cast { fileName : curExpr.origin, lineNumber : curExpr.line }; + #end + return cast { fileName : "hscript", lineNumber : 0 }; + } + function initOps() { var me = this; #if haxe3 @@ -275,7 +284,7 @@ class Interp { inline function error(e : #if hscriptPos ErrorDef #else Error #end ) : Dynamic { #if hscriptPos - throw new Error(e, curExpr.pmin, curExpr.pmax); + throw new Error(e, curExpr.pmin, curExpr.pmax, curExpr.origin, curExpr.line); #else throw e; #end @@ -447,7 +456,7 @@ class Interp { } return f; case EArrayDecl(arr): - if (arr.length > 0 && arr[0].match(Expr.EBinop("=>", _))) { + if (arr.length > 0 && edef(arr[0]).match(EBinop("=>", _))) { var isAllString:Bool = true; var isAllInt:Bool = true; var isAllObject:Bool = true; @@ -455,8 +464,8 @@ class Interp { var keys:Array = []; var values:Array = []; for (e in arr) { - switch(e) { - case Expr.EBinop("=>", eKey, eValue): { + switch(edef(e)) { + case EBinop("=>", eKey, eValue): { var key:Dynamic = expr(eKey); var value:Dynamic = expr(eValue); isAllString = isAllString && Std.is(key, String); diff --git a/hscript/Macro.hx b/hscript/Macro.hx index 2b8c286..4bf0423 100644 --- a/hscript/Macro.hx +++ b/hscript/Macro.hx @@ -234,4 +234,4 @@ class Macro { }, pos : #if hscriptPos { file : p.file, min : e.pmin, max : e.pmax } #else p #end } } -} \ No newline at end of file +} diff --git a/hscript/Parser.hx b/hscript/Parser.hx index d391505..b4f594e 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -77,6 +77,7 @@ class Parser { var uid : Int = 0; #if hscriptPos + var origin : String; var readPos : Int; var tokenMin : Int; var tokenMax : Int; @@ -133,7 +134,7 @@ class Parser { public inline function error( err, pmin, pmax ) { #if hscriptPos - throw new Error(err, pmin, pmax); + throw new Error(err, pmin, pmax, origin, line); #else throw err; #end @@ -143,14 +144,15 @@ class Parser { error(EInvalidChar(c), readPos, readPos); } - public function parseString( s : String ) { - line = 1; + public function parseString( s : String, ?origin : String = "hscript" ) { uid = 0; - return parse( new haxe.io.StringInput(s) ); + return parse( new haxe.io.StringInput(s), origin ); } - public function parse( s : haxe.io.Input ) { + public function parse( s : haxe.io.Input, ?origin : String = "hscript" ) { + line = 1; #if hscriptPos + this.origin = origin; readPos = 0; tokenMin = oldTokenMin = 0; tokenMax = oldTokenMax = 0; @@ -224,9 +226,10 @@ class Parser { inline function mk(e,?pmin,?pmax) : Expr { #if hscriptPos + if( e == null ) return null; if( pmin == null ) pmin = tokenMin; if( pmax == null ) pmax = tokenMax; - return { e : e, pmin : pmin, pmax : pmax }; + return { e : e, pmin : pmin, pmax : pmax, origin : origin, line : line }; #else return e; #end @@ -480,7 +483,7 @@ class Parser { var e = parseExpr(); mk(EWhile(econd,e),p1,pmax(e)); case "do": - var e = parseExpr(); + var e = parseExpr(); var tk = token(); switch(tk) {