diff --git a/hscript/Error.hx b/hscript/Error.hx index d01f2fa..5c8cdd5 100644 --- a/hscript/Error.hx +++ b/hscript/Error.hx @@ -60,8 +60,34 @@ enum Error EInvalidEscape( s : String ); } -enum abstract ErrorMessage(String) to String { - final INVALID_CHAR_CODE_MULTI = "'char'.code only works on single characters"; - final FROM_CHAR_CODE_NON_INT = "String.fromCharCode only works on integers"; - final EMPTY_INTERPOLATION = "Invalid interpolation: Expression cannot be empty"; +enum abstract ErrorMessage(Int) from Int to Int { + final INVALID_CHAR_CODE_MULTI; + final FROM_CHAR_CODE_NON_INT; + final EMPTY_INTERPOLATION; + final UNKNOWN_MAP_TYPE; + final UNKNOWN_MAP_TYPE_RUNTIME; + final EXPECT_KEY_VALUE_SYNTAX; + + public function toString():String { + return switch(cast this) { + case INVALID_CHAR_CODE_MULTI: "'char'.code only works on single characters"; + case FROM_CHAR_CODE_NON_INT: "String.fromCharCode only works on integers"; + case EMPTY_INTERPOLATION: "Invalid interpolation: Expression cannot be empty"; + case UNKNOWN_MAP_TYPE: "Unknown Map Type"; + case UNKNOWN_MAP_TYPE_RUNTIME: "Unknown Map Type, while parsing at runtime"; + case EXPECT_KEY_VALUE_SYNTAX: "Expected a => b"; + } + } + + public static function fromString(s:String):ErrorMessage { + return switch(s) { + case "INVALID_CHAR_CODE_MULTI": INVALID_CHAR_CODE_MULTI; + case "FROM_CHAR_CODE_NON_INT": FROM_CHAR_CODE_NON_INT; + case "EMPTY_INTERPOLATION": EMPTY_INTERPOLATION; + case "UNKNOWN_MAP_TYPE": UNKNOWN_MAP_TYPE; + case "UNKNOWN_MAP_TYPE_RUNTIME": UNKNOWN_MAP_TYPE_RUNTIME; + case "EXPECT_KEY_VALUE_SYNTAX": EXPECT_KEY_VALUE_SYNTAX; + default: throw "Unknown ErrorMessage"; + } + } } \ No newline at end of file diff --git a/hscript/Interp.hx b/hscript/Interp.hx index e8bb265..e89b025 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -818,7 +818,7 @@ class Interp { var t = b2i(isKeyString) + b2i(isKeyInt) + b2i(isKeyObject) + b2i(isKeyEnum); if(t != 1) - error(ECustom("Unknown Map Type")); + error(EPreset(UNKNOWN_MAP_TYPE_RUNTIME)); else if(isKeyInt) type = IntMap; else if(isKeyString) type = StringMap; else if(isKeyEnum) type = EnumMap; diff --git a/hscript/Parser.hx b/hscript/Parser.hx index c9ee384..17b57c6 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -646,7 +646,7 @@ class Parser { values.push(eValue); } default: - error(ECustom("Expected a => b"), p1, p1); + error(EPreset(EXPECT_KEY_VALUE_SYNTAX), p1, p1); } } @@ -658,7 +658,7 @@ class Parser { isKeyEnum = false; } else { if(!isKeyObject && !isKeyEnum) { - error(ECustom("Unknown Type Key"), p1, p1); + error(EPreset(UNKNOWN_MAP_TYPE), p1, p1); } } } @@ -673,7 +673,7 @@ class Parser { else if(isKeyObject) type = ObjectMap; if(type == null) - error(ECustom("Unknown Map Type"), p1, p1); + error(EPreset(UNKNOWN_MAP_TYPE), p1, p1); return parseExprNext(mk(EMapDecl(type, keys, values), p1)); } diff --git a/hscript/Preprocessor.hx b/hscript/Preprocessor.hx index 5035c18..7cb10e8 100644 --- a/hscript/Preprocessor.hx +++ b/hscript/Preprocessor.hx @@ -18,7 +18,7 @@ class Preprocessor { if(e == null) return null; - trace(expr(e)); + //trace(expr(e)); e = Tools.map(e, function(e) { return process(e); @@ -35,13 +35,13 @@ class Preprocessor { case EConst(CInt(i)): return mk(EConst(CString(String.fromCharCode(i))), e); default: - // __StringWorkaround__fromCharCode(i); - #if !NO_FROM_CHAR_CODE_FIX - return mk(ECall(mk(EIdent("__StringWorkaround__fromCharCode"), e), [e]), e); - #else - throw Parser.getBaseError(EPreset(FROM_CHAR_CODE_NON_INT)); - #end } + // __StringWorkaround__fromCharCode(i); + #if !NO_FROM_CHAR_CODE_FIX + return mk(ECall(mk(EIdent("__StringWorkaround__fromCharCode"), e), [e]), e); + #else + throw Parser.getBaseError(EPreset(FROM_CHAR_CODE_NON_INT)); + #end default: } diff --git a/hscript/Printer.hx b/hscript/Printer.hx index 4a0e293..47212e7 100644 --- a/hscript/Printer.hx +++ b/hscript/Printer.hx @@ -521,6 +521,13 @@ class Printer { return Type.enumEq(Tools.cleanError(e1), Tools.cleanError(e2)); } + public inline static function getPrintableError( e : Error ) { + return Tools.cleanError(switch( Tools.cleanError(e) ) { + case EPreset(msg): Parser.getBaseError(ECustom(msg.toString())); + default: e; + }); + } + public static function errorToString( e : Error ) { var message = switch( Tools.cleanError(e) ) { case EInvalidChar(c): "Invalid character: '"+(StringTools.isEof(c) ? "EOF (End Of File)" : String.fromCharCode(c))+"' ("+c+")"; @@ -533,7 +540,7 @@ class Printer { case EInvalidOp(op): "Invalid operator: "+op; case EInvalidAccess(f): "Invalid access to field " + f; case ECustom(msg): msg; - case EPreset(msg): msg; + case EPreset(msg): msg.toString(); case EInvalidClass(cla): "Invalid class: " + cla + " was not found."; case EAlreadyExistingClass(cla): 'Custom Class named $cla already exists.'; case EInvalidEscape(s): "Invalid escape sequence: " + s; diff --git a/tests/src/tests/StringCase.hx b/tests/src/tests/StringCase.hx index 439706e..c9c60c1 100644 --- a/tests/src/tests/StringCase.hx +++ b/tests/src/tests/StringCase.hx @@ -130,32 +130,28 @@ class StringCase extends TestCase { assertEq("'hello ${5} world'", 'hello ${5} world'); assertEq("'hello ${5}'", 'hello ${5}'); - //Util.runKnownBug("string.code doesnt work", () -> { - assertEq('"f".code', "f".code); - assertEq('"o".code', "o".code); - assertEq('"1".code', "1".code); - assertEq('"b".code', "b".code); - assertEq('"a".code', "a".code); - assertEq('"r".code', "r".code); - assertEq('"r".code', "r".code); - assertError('"foo".code', Parser.getBaseError(EPreset(INVALID_CHAR_CODE_MULTI))); // multiple chars causes error - assertError('"bar".code', Parser.getBaseError(EPreset(INVALID_CHAR_CODE_MULTI))); // multiple chars causes error - //}); + assertEq('"f".code', "f".code); + assertEq('"o".code', "o".code); + assertEq('"1".code', "1".code); + assertEq('"b".code', "b".code); + assertEq('"a".code', "a".code); + assertEq('"r".code', "r".code); + assertEq('"r".code', "r".code); + assertError('"foo".code', Parser.getBaseError(EPreset(INVALID_CHAR_CODE_MULTI))); // multiple chars causes error + assertError('"bar".code', Parser.getBaseError(EPreset(INVALID_CHAR_CODE_MULTI))); // multiple chars causes error headerCode = ''; var a = 103; - //Util.runKnownBug("String.fromCharCode doesnt work", () -> { - assertEq('String.fromCharCode(65)', String.fromCharCode(65)); - assertEq('String.fromCharCode(97)', String.fromCharCode(97)); - assertEq('String.fromCharCode(98)', String.fromCharCode(98)); - assertEq('String.fromCharCode(99)', String.fromCharCode(99)); - assertEq('String.fromCharCode(100)', String.fromCharCode(100)); - assertEq('String.fromCharCode(101)', String.fromCharCode(101)); - assertEq('String.fromCharCode(102)', String.fromCharCode(102)); - assertEq('String.fromCharCode(103)', String.fromCharCode(103)); - assertEq('var a = 103; String.fromCharCode(a)', String.fromCharCode(test)); - //}); + assertEq('String.fromCharCode(65)', String.fromCharCode(65)); + assertEq('String.fromCharCode(97)', String.fromCharCode(97)); + assertEq('String.fromCharCode(98)', String.fromCharCode(98)); + assertEq('String.fromCharCode(99)', String.fromCharCode(99)); + assertEq('String.fromCharCode(100)', String.fromCharCode(100)); + assertEq('String.fromCharCode(101)', String.fromCharCode(101)); + assertEq('String.fromCharCode(102)', String.fromCharCode(102)); + assertEq('String.fromCharCode(103)', String.fromCharCode(103)); + assertEq('var a = 103; String.fromCharCode(a)', String.fromCharCode(test)); assertError("'hello ${}'", Parser.getBaseError(EPreset(EMPTY_INTERPOLATION))); } diff --git a/tests/src/tests/TestCase.hx b/tests/src/tests/TestCase.hx index 05fe3d5..5b8dff8 100644 --- a/tests/src/tests/TestCase.hx +++ b/tests/src/tests/TestCase.hx @@ -21,6 +21,7 @@ class TestCase extends HScriptRunner { } public function assertError(script:String, expectedError:hscript.Error, ?message:String, ?vars:Dynamic, ?pos:haxe.PosInfos) { + var expectedError = Printer.getPrintableError(expectedError); if(message == null) message = script; try { @@ -29,17 +30,18 @@ class TestCase extends HScriptRunner { else executeUnsafe(script); Sys.println("# For script: " + script); - Sys.println("## Expected error: " + Tools.cleanError(expectedError)); + Sys.println("## Expected error: " + expectedError); Sys.println("## Got result: " + result); Sys.println("> " + Printer.convertExprToString(lastExpr)); return Util.failed(); } catch(e:hscript.Error) { - if(Printer.compareErrors(e, expectedError)) { + var e = Printer.getPrintableError(e); + if(Type.enumEq(e, expectedError)) { return Util.passed(); } else { Sys.println("# For script: " + script); - Sys.println("## Expected error: " + Tools.cleanError(expectedError)); - Sys.println("## Actual error: " + Tools.cleanError(e)); + Sys.println("## Expected error: " + expectedError); + Sys.println("## Actual error: " + e); return Util.failed(); } }