diff --git a/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java b/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java index acc43b761..920a76244 100644 --- a/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java +++ b/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java @@ -103,6 +103,8 @@ private MethodScriptCompiler() { private static final Pattern VAR_PATTERN = Pattern.compile("\\$[\\p{L}0-9_]+"); private static final Pattern IVAR_PATTERN = Pattern.compile(IVariable.VARIABLE_NAME_REGEX); + private static final Pattern NUM_PATTERN = Pattern.compile("[0-9]+"); + private static final Pattern FUNC_NAME_PATTERN = Pattern.compile("[_a-zA-Z0-9]+"); /** * Lexes the script, and turns it into a token stream.This looks through the script character by character. @@ -593,7 +595,7 @@ public static TokenStream lex(String script, Environment env, File file, } else { // It's not a keyword, but a normal function. String funcName = buf.toString(); - if(funcName.matches("[_a-zA-Z0-9]+")) { + if(FUNC_NAME_PATTERN.matcher(funcName).matches()) { tokenList.add(new Token(TType.FUNC_NAME, funcName, target)); } else { tokenList.add(new Token(TType.UNKNOWN, funcName, target)); @@ -911,8 +913,7 @@ public static TokenStream lex(String script, Environment env, File file, if(!prevNonWhitespace.type.isIdentifier() // Don't convert "number/string/var ± ...". && prevNonWhitespace.type != TType.FUNC_END // Don't convert "func() ± ...". && prevNonWhitespace.type != TType.RSQUARE_BRACKET // Don't convert "] ± ..." (arrays). - && !IVAR_PATTERN.matcher(t.val()).matches() // Don't convert "± @var". - && !VAR_PATTERN.matcher(t.val()).matches()) { // Don't convert "± $var". + && NUM_PATTERN.matcher(t.val()).matches()) { // Only convert numbers // It is a negative/positive number: Absorb the sign. t.value = prev1.value + t.value; it.remove(); // Remove 'prev1'. @@ -1769,28 +1770,35 @@ public static ParseTree compile(TokenStream stream, Environment environment, } catch (ConfigRuntimeException ex) { throw new ConfigCompileException(ex); } - if((c instanceof CInt || c instanceof CDecimal) && next1.type == TType.DOT && next2.type == TType.LIT) { - // make CDouble/CDecimal here because otherwise Long.parseLong() will remove - // minus zero before decimals and leading zeroes after decimals + // make CDouble/CDecimal here because otherwise Long.parseLong() will remove + // minus zero before decimals and leading zeroes after decimals + if(c instanceof CInt && next1.type == TType.DOT && next2.type == TType.LIT) { try { - if(t.value.startsWith("0m")) { - // CDecimal - String neg = ""; - if(prev1.value.equals("-")) { - neg = "-"; - } - c = new CDecimal(neg + t.value.substring(2) + '.' + next2.value, t.target); - } else { - // CDouble - c = new CDouble(Double.parseDouble(t.val() + '.' + next2.val()), t.target); - } + c = new CDouble(Double.parseDouble(t.val() + '.' + next2.val()), t.target); i += 2; } catch (NumberFormatException e) { // Not a double } + constructCount.peek().incrementAndGet(); + } else if(c instanceof CDecimal) { + String neg = ""; + if(prev1.value.equals("-")) { + // Absorb sign unless neg() becomes compatible with CDecimal + neg = "-"; + tree.removeChildAt(tree.getChildren().size() - 1); + } else { + constructCount.peek().incrementAndGet(); + } + if(next1.type == TType.DOT && next2.type == TType.LIT) { + c = new CDecimal(neg + t.value.substring(2) + '.' + next2.value, t.target); + i += 2; + } else { + c = new CDecimal(neg + t.value.substring(2), t.target); + } + } else { + constructCount.peek().incrementAndGet(); } tree.addChild(new ParseTree(c, fileOptions)); - constructCount.peek().incrementAndGet(); } else if(t.type.equals(TType.STRING) || t.type.equals(TType.COMMAND)) { tree.addChild(new ParseTree(new CString(t.val(), t.target), fileOptions)); constructCount.peek().incrementAndGet(); diff --git a/src/test/java/com/laytonsmith/core/MethodScriptCompilerTest.java b/src/test/java/com/laytonsmith/core/MethodScriptCompilerTest.java index 56b31bd1b..e268017a7 100644 --- a/src/test/java/com/laytonsmith/core/MethodScriptCompilerTest.java +++ b/src/test/java/com/laytonsmith/core/MethodScriptCompilerTest.java @@ -1005,7 +1005,6 @@ public void testWhitespaceAroundSymbol1() throws Exception { // verify(fakePlayer).sendMessage("yep yep"); // } @Test - @Ignore("Ignore for now, until the feature is implemented") public void testLiteralDecimal() throws Exception { assertEquals("123.4", SRun("0m123.4", fakePlayer)); assertEquals("123", SRun("0m123", fakePlayer)); @@ -1024,11 +1023,10 @@ public void testLiteralBinary() throws Exception { } @Test - @Ignore("Ignore for now, until the feature is implemented") public void testLiteralBinary2() throws Exception { assertEquals("6", SRun("0b0110", fakePlayer)); assertEquals("-6", SRun("-0b0110", fakePlayer)); - assertEquals("int", SRun("typeof(-0b0110)", fakePlayer)); + assertEquals("ms.lang.int", SRun("typeof(-0b0110)", fakePlayer)); } @Test