From eb895fffef967cace46cd921b7d5a92f02ad3236 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Thu, 2 May 2019 01:23:49 +0200 Subject: [PATCH] Added parser for typed integer literal postfix (ub/sb/uc/sc/uw/sw/ui/si/us/ss/ud/sd/ul/sl and l) --- .../java/dk/camelot64/kickc/NumberParser.java | 73 ++++++++++++------- .../kickc/model/values/ConstantInteger.java | 6 +- .../Pass0GenerateStatementSequence.java | 7 +- .../dk/camelot64/kickc/test/TestPrograms.java | 5 ++ src/test/kc/int-literals.kc | 19 +++++ 5 files changed, 78 insertions(+), 32 deletions(-) create mode 100644 src/test/kc/int-literals.kc diff --git a/src/main/java/dk/camelot64/kickc/NumberParser.java b/src/main/java/dk/camelot64/kickc/NumberParser.java index 5465bad9a..4f222860d 100644 --- a/src/main/java/dk/camelot64/kickc/NumberParser.java +++ b/src/main/java/dk/camelot64/kickc/NumberParser.java @@ -1,38 +1,61 @@ package dk.camelot64.kickc; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.values.ConstantInteger; + /** Parser for converting literal numbers to the corresponding Java Integer/Double */ public class NumberParser { - public static Number parseLiteral(String literal) { - boolean isInt = !literal.contains("."); + public static ConstantInteger parseIntegerLiteral(String literal) { - if(isInt) { - if(literal.startsWith("0x")) { - return parseHexInt(literal.substring(2)); - } else if(literal.startsWith("$")) { - return parseHexInt(literal.substring(1)); - } else if(literal.startsWith("0b")) { - return parseBinInt(literal.substring(2)); - } else if(literal.startsWith("%")) { - return parseBinInt(literal.substring(1)); - } else { - return parseDecInt(literal); - } - } else { + boolean isInt = !literal.contains("."); + if(!isInt) { throw new NumberFormatException("Not Implemented: non-integer parsing. " + literal); } + + SymbolType type = null; + if(literal.endsWith("ub") || literal.endsWith("uc")) { + type = SymbolType.BYTE; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("sb") || literal.endsWith("sc")) { + type = SymbolType.SBYTE; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("uw") || literal.endsWith("ui")|| literal.endsWith("us")) { + type = SymbolType.WORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("sw") || literal.endsWith("si")|| literal.endsWith("ss")) { + type = SymbolType.SWORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("ud") || literal.endsWith("ul")) { + type = SymbolType.DWORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("sd") || literal.endsWith("sl")) { + type = SymbolType.SDWORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("l")) { + type = SymbolType.SDWORD; + literal = literal.substring(0, literal.length()-1); + } + + Long value; + if(literal.startsWith("0x")) { + value = Long.parseLong(literal.substring(2), 16); + } else if(literal.startsWith("$")) { + value = Long.parseLong(literal.substring(1), 16); + } else if(literal.startsWith("0b")) { + value = Long.parseLong(literal.substring(2), 2); + } else if(literal.startsWith("%")) { + value = Long.parseLong(literal.substring(1), 2); + } else { + value = Long.parseLong(literal); + } + return new ConstantInteger(value, type); + } - private static Long parseHexInt(String literal) { - return Long.parseLong(literal, 16); - } - - private static Long parseBinInt(String literal) { - return Long.parseLong(literal, 2); - } - - private static Long parseDecInt(String literal) { - return Long.parseLong(literal); + public static Number parseLiteral(String literal) { + ConstantInteger constantInteger = parseIntegerLiteral(literal); + return constantInteger.getValue(); } diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java index b0131e99e..c4f8620eb 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java @@ -21,7 +21,11 @@ public class ConstantInteger implements ConstantEnumerable { public ConstantInteger(Long number, SymbolType type) { this.number = number; - this.type = type; + if(type!=null) { + this.type = type; + } else { + this.type = SymbolTypeMulti.getMultiType(number); + } } @Override diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 6889b48b4..efc72cdbd 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -1298,12 +1298,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { @Override public RValue visitExprNumber(KickCParser.ExprNumberContext ctx) { - Number number = NumberParser.parseLiteral(ctx.getText()); - if(number instanceof Long) { - return new ConstantInteger((Long) number); - } else { - return new ConstantDouble((Double) number); - } + return NumberParser.parseIntegerLiteral(ctx.getText()); } @Override diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index fe61073bd..cbc3675db 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -32,6 +32,11 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testIntegerLiterals() throws IOException, URISyntaxException { + compileAndCompare("int-literals"); + } + @Test public void testSimpleLoop() throws IOException, URISyntaxException { compileAndCompare("simple-loop"); diff --git a/src/test/kc/int-literals.kc b/src/test/kc/int-literals.kc new file mode 100644 index 000000000..0a66f2042 --- /dev/null +++ b/src/test/kc/int-literals.kc @@ -0,0 +1,19 @@ +// Tests different integer literals + +void main() { + unsigned byte ub = 12ub; + unsigned char uc = 12uc; + signed byte sb = 12sb; + signed byte sc = 12sc; + unsigned word uw = 12uw; + unsigned int ui = 12ui; + unsigned short us = 12us; + signed word sw = 12sw; + signed int si = 12si; + signed short ss = 12ss; + unsigned dword ud = 12ud; + unsigned long ul = 12ul; + signed dword sd = 12sd; + signed long sl = 12sl; + long l = 12l; +} \ No newline at end of file