From 1ab03df9089e22dcb2832d67c32710ad472a48f8 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Wed, 29 Dec 2021 17:47:52 +0100 Subject: [PATCH] Moved signature parser to source. --- .../signature/AsmFragmentSignature.java | 20 ++ .../AsmFragmentSignatureInstantiator.java | 206 ++++++++++++++++++ .../TestFragmentSignatureParser.java | 204 +---------------- 3 files changed, 227 insertions(+), 203 deletions(-) create mode 100644 src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignatureInstantiator.java diff --git a/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java b/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java index afd70cd1f..33982bc5c 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java +++ b/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignature.java @@ -1,5 +1,11 @@ package dk.camelot64.kickc.fragment.signature; +import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureLexer; +import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureParser; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; + /** * A signature of an ASM fragment. * The signature captures the operation performed by the fragment and the types of the parameters. @@ -14,6 +20,20 @@ public interface AsmFragmentSignature { */ String getName(); + /** + * Parses a signature name to a typed signature. + * @param sigName The signature name (created by signature.getName()) + * @return The signature + */ + static AsmFragmentSignature parse(String sigName) { + final CharStream sigCharStream = CharStreams.fromString(sigName); + AsmFragmentSignatureLexer sigLexer = new AsmFragmentSignatureLexer(sigCharStream); + AsmFragmentSignatureParser sigParser = new AsmFragmentSignatureParser(new CommonTokenStream(sigLexer)); + final AsmFragmentSignatureParser.SignatureContext sigCtx = sigParser.signature(); + final AsmFragmentSignatureInstantiator instantiator = new AsmFragmentSignatureInstantiator(); + return instantiator.visitSignature(sigCtx); + } + /** * ASM fragment signature for an assignment A=B. */ diff --git a/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignatureInstantiator.java b/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignatureInstantiator.java new file mode 100644 index 000000000..269977909 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/fragment/signature/AsmFragmentSignatureInstantiator.java @@ -0,0 +1,206 @@ +package dk.camelot64.kickc.fragment.signature; + +import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureBaseVisitor; +import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureParser; +import dk.camelot64.kickc.model.operators.OperatorBinary; +import dk.camelot64.kickc.model.operators.OperatorUnary; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypePointer; +import dk.camelot64.kickc.model.types.SymbolTypeStruct; +import dk.camelot64.kickc.model.values.ConstantInteger; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.util.List; +import java.util.stream.Collectors; + +/** Creates a typed signature from the signature parser AST. */ +class AsmFragmentSignatureInstantiator extends AsmFragmentSignatureBaseVisitor { + + /** Dummy struct type used for fragments. */ + private static final SymbolTypeStruct STRUCT_TYPE = new SymbolTypeStruct("Struct", false, 0, false, false); + + @Override + public List visitSignatures(AsmFragmentSignatureParser.SignaturesContext ctx) { + return null; + } + + public AsmFragmentSignature visitSignature(AsmFragmentSignatureParser.SignatureContext ctx) { + return (AsmFragmentSignature) visit(ctx); + } + + @Override + public AsmFragmentSignature visitAssignment(AsmFragmentSignatureParser.AssignmentContext ctx) { + return new AsmFragmentSignature.Assignment(visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); + } + + @Override + public AsmFragmentSignature visitConditionalJump(AsmFragmentSignatureParser.ConditionalJumpContext ctx) { + final AsmFragmentSignatureExpr.Variable label = + new AsmFragmentSignatureExpr.Variable(ctx.LABEL().getText(), SymbolType.LABEL); + return new AsmFragmentSignature.ConditionalJump(visitExpr(ctx.expr()), label); + } + + @Override + public AsmFragmentSignature visitCall(AsmFragmentSignatureParser.CallContext ctx) { + return new AsmFragmentSignature.Call(visitExpr(ctx.expr())); + } + + @Override + public AsmFragmentSignature visitIsrRoutine(AsmFragmentSignatureParser.IsrRoutineContext ctx) { + final String type = ctx.NAME().stream().map(ParseTree::getText).collect(Collectors.joining("_")); + final String entryExitText = ctx.getChild(ctx.getChildCount() - 1).getText(); + AsmFragmentSignature.Isr.EntryExit entryExit; + switch (entryExitText) { + case "entry": + entryExit = AsmFragmentSignature.Isr.EntryExit.Entry; + break; + case "exit": + entryExit = AsmFragmentSignature.Isr.EntryExit.Exit; + break; + default: + throw new RuntimeException("Unknown ISR entry/exit type " + entryExitText); + } + return new AsmFragmentSignature.Isr(type, entryExit); + } + + @Override + public AsmFragmentSignature visitExprSideEffect(AsmFragmentSignatureParser.ExprSideEffectContext ctx) { + return new AsmFragmentSignature.ExprSideEffect(visitExpr(ctx.expr())); + } + + public AsmFragmentSignatureExpr visitExpr(AsmFragmentSignatureParser.ExprContext ctx) { + return (AsmFragmentSignatureExpr) visit(ctx); + } + + @Override + public AsmFragmentSignatureExpr visitPar(AsmFragmentSignatureParser.ParContext ctx) { + return this.visitExpr(ctx.expr()); + } + + @Override + public AsmFragmentSignatureExpr visitVar(AsmFragmentSignatureParser.VarContext ctx) { + final String varName = ctx.VAR().getText(); + // TODO: parse Type + SymbolType varType = SymbolType.VOID; + return new AsmFragmentSignatureExpr.Variable(varName, varType); + } + + @Override + public AsmFragmentSignatureExpr visitNum(AsmFragmentSignatureParser.NumContext ctx) { + final ConstantInteger num = new ConstantInteger((long) Integer.parseInt(ctx.NUM().getText())); + return new AsmFragmentSignatureExpr.Number(num); + } + + @Override + public AsmFragmentSignatureExpr visitBinary(AsmFragmentSignatureParser.BinaryContext ctx) { + final String operatorText = ctx.getChild(1).getText(); + final OperatorBinary operator = Operators.getBinaryFromAsmName(operatorText); + return new AsmFragmentSignatureExpr.Binary(operator, visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); + } + + @Override + public Object visitDerefSimple(AsmFragmentSignatureParser.DerefSimpleContext ctx) { + return new AsmFragmentSignatureExpr.DerefSimple(this.visitExpr(ctx.expr())); + } + + @Override + public Object visitDerefIdx(AsmFragmentSignatureParser.DerefIdxContext ctx) { + return new AsmFragmentSignatureExpr.DerefIdx(this.visitExpr(ctx.expr(0)), this.visitExpr(ctx.expr(1))); + } + + @Override + public AsmFragmentSignatureExpr visitUnary(AsmFragmentSignatureParser.UnaryContext ctx) { + final String operatorText = ctx.getChild(0).getText(); + final OperatorUnary operator = Operators.getUnaryFromAsmName(operatorText); + return new AsmFragmentSignatureExpr.Unary(operator, visitExpr(ctx.expr())); + } + + @Override + public AsmFragmentSignatureExpr visitMemset(AsmFragmentSignatureParser.MemsetContext ctx) { + return new AsmFragmentSignatureExpr.Memset(visitExpr(ctx.expr())); + } + + @Override + public AsmFragmentSignatureExpr visitMemcpy(AsmFragmentSignatureParser.MemcpyContext ctx) { + return new AsmFragmentSignatureExpr.Memcpy(visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); + } + + @Override + public AsmFragmentSignatureExpr visitStackPushPadding(AsmFragmentSignatureParser.StackPushPaddingContext ctx) { + final ConstantInteger bytes = new ConstantInteger((long) Integer.parseInt(ctx.NUM().getText())); + return new AsmFragmentSignatureExpr.StackPushPadding(bytes); + } + + @Override + public AsmFragmentSignatureExpr visitStackPullPadding(AsmFragmentSignatureParser.StackPullPaddingContext ctx) { + final ConstantInteger bytes = new ConstantInteger((long) Integer.parseInt(ctx.NUM().getText())); + return new AsmFragmentSignatureExpr.StackPullPadding(bytes); + } + + private SymbolType parseSymbolType(String typeText) { + switch (typeText) { + case "ptr": + return new SymbolTypePointer(SymbolType.VOID); + case "byte": + return SymbolType.BYTE; + case "sbyte": + return SymbolType.SBYTE; + case "word": + return SymbolType.WORD; + case "sword": + return SymbolType.SWORD; + case "dword": + return SymbolType.DWORD; + case "sdword": + return SymbolType.SDWORD; + default: + throw new RuntimeException("Unknown type " + typeText); + } + } + + @Override + public AsmFragmentSignatureExpr visitStackIdx(AsmFragmentSignatureParser.StackIdxContext ctx) { + final String typeText = ctx.getChild(0).getText().substring("stackidx".length()); + SymbolType type = parseSymbolType(typeText); + return new AsmFragmentSignatureExpr.StackIdx(type, null, visitExpr(ctx.expr())); + } + + @Override + public AsmFragmentSignatureExpr visitStackIdxStruct(AsmFragmentSignatureParser.StackIdxStructContext ctx) { + return new AsmFragmentSignatureExpr.StackIdx(STRUCT_TYPE, visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); + } + + @Override + public AsmFragmentSignatureExpr visitStackPush(AsmFragmentSignatureParser.StackPushContext ctx) { + final String typeText = ctx.getChild(0).getText().substring("stackpush".length()); + SymbolType type = parseSymbolType(typeText); + return new AsmFragmentSignatureExpr.StackPush(type, null); + } + + @Override + public AsmFragmentSignatureExpr visitStackPushStruct(AsmFragmentSignatureParser.StackPushStructContext ctx) { + return new AsmFragmentSignatureExpr.StackPush(STRUCT_TYPE, visitExpr(ctx.expr())); + } + + @Override + public AsmFragmentSignatureExpr visitStackPull(AsmFragmentSignatureParser.StackPullContext ctx) { + final String typeText = ctx.getChild(0).getText().substring("stackpull".length()); + SymbolType type = parseSymbolType(typeText); + return new AsmFragmentSignatureExpr.StackPull(type, null); + } + + @Override + public AsmFragmentSignatureExpr visitStackPullStruct(AsmFragmentSignatureParser.StackPullStructContext ctx) { + return new AsmFragmentSignatureExpr.StackPull(STRUCT_TYPE, visitExpr(ctx.expr())); + } + + @Override + public AsmFragmentSignatureExpr visitMakelong4(AsmFragmentSignatureParser.Makelong4Context ctx) { + return new AsmFragmentSignatureExpr.Makelong4( + visitExpr(ctx.expr(0)), + visitExpr(ctx.expr(1)), + visitExpr(ctx.expr(2)), + visitExpr(ctx.expr(3))); + } +} diff --git a/src/test/java/dk/camelot64/kickc/parsing/fragments/TestFragmentSignatureParser.java b/src/test/java/dk/camelot64/kickc/parsing/fragments/TestFragmentSignatureParser.java index 982df3e28..d2c47f058 100644 --- a/src/test/java/dk/camelot64/kickc/parsing/fragments/TestFragmentSignatureParser.java +++ b/src/test/java/dk/camelot64/kickc/parsing/fragments/TestFragmentSignatureParser.java @@ -1,21 +1,6 @@ package dk.camelot64.kickc.parsing.fragments; -import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureBaseVisitor; -import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureLexer; -import dk.camelot64.kickc.asm.fragment.signature.AsmFragmentSignatureParser; import dk.camelot64.kickc.fragment.signature.AsmFragmentSignature; -import dk.camelot64.kickc.fragment.signature.AsmFragmentSignatureExpr; -import dk.camelot64.kickc.model.operators.OperatorBinary; -import dk.camelot64.kickc.model.operators.OperatorUnary; -import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeStruct; -import dk.camelot64.kickc.model.values.ConstantInteger; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTree; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -24,9 +9,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.MessageFormat; -import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; public class TestFragmentSignatureParser { @@ -40,12 +23,7 @@ public class TestFragmentSignatureParser { try (BufferedReader br = new BufferedReader(fragmentsReader)) { int line = 1; for (String sigName; (sigName = br.readLine()) != null; ) { - final CharStream sigCharStream = CharStreams.fromString(sigName); - AsmFragmentSignatureLexer sigLexer = new AsmFragmentSignatureLexer(sigCharStream); - AsmFragmentSignatureParser sigParser = new AsmFragmentSignatureParser(new CommonTokenStream(sigLexer)); - final AsmFragmentSignatureParser.SignatureContext sigCtx = sigParser.signature(); - final AsmFragmentSignatureInstantiator instantiator = new AsmFragmentSignatureInstantiator(); - final AsmFragmentSignature sig = instantiator.visitSignature(sigCtx); + final AsmFragmentSignature sig = AsmFragmentSignature.parse(sigName); System.out.println(MessageFormat.format("Parsing {0}: {1}", line, sigName)); Assertions.assertNotNull(sig); Assertions.assertEquals(sigName, sig.getName()); @@ -55,184 +33,4 @@ public class TestFragmentSignatureParser { } - public static class AsmFragmentSignatureInstantiator extends AsmFragmentSignatureBaseVisitor { - - public static final SymbolTypeStruct STRUCT_TYPE = new SymbolTypeStruct("Struct", false, 0, false, false); - - @Override - public List visitSignatures(AsmFragmentSignatureParser.SignaturesContext ctx) { - return null; - } - - public AsmFragmentSignature visitSignature(AsmFragmentSignatureParser.SignatureContext ctx) { - return (AsmFragmentSignature) visit(ctx); - } - - @Override - public AsmFragmentSignature visitAssignment(AsmFragmentSignatureParser.AssignmentContext ctx) { - return new AsmFragmentSignature.Assignment(visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); - } - - @Override - public AsmFragmentSignature visitConditionalJump(AsmFragmentSignatureParser.ConditionalJumpContext ctx) { - final AsmFragmentSignatureExpr.Variable label = - new AsmFragmentSignatureExpr.Variable(ctx.LABEL().getText(), SymbolType.LABEL); - return new AsmFragmentSignature.ConditionalJump(visitExpr(ctx.expr()), label); - } - - @Override - public AsmFragmentSignature visitCall(AsmFragmentSignatureParser.CallContext ctx) { - return new AsmFragmentSignature.Call(visitExpr(ctx.expr())); - } - - @Override - public AsmFragmentSignature visitIsrRoutine(AsmFragmentSignatureParser.IsrRoutineContext ctx) { - final String type = ctx.NAME().stream().map(ParseTree::getText).collect(Collectors.joining("_")); - final String entryExitText = ctx.getChild(ctx.getChildCount() - 1).getText(); - AsmFragmentSignature.Isr.EntryExit entryExit; - switch (entryExitText) { - case "entry": - entryExit = AsmFragmentSignature.Isr.EntryExit.Entry; - break; - case "exit": - entryExit = AsmFragmentSignature.Isr.EntryExit.Exit; - break; - default: - throw new RuntimeException("Unknown ISR entry/exit type " + entryExitText); - } - return new AsmFragmentSignature.Isr(type, entryExit); - } - - @Override - public AsmFragmentSignature visitExprSideEffect(AsmFragmentSignatureParser.ExprSideEffectContext ctx) { - return new AsmFragmentSignature.ExprSideEffect(visitExpr(ctx.expr())); - } - - public AsmFragmentSignatureExpr visitExpr(AsmFragmentSignatureParser.ExprContext ctx) { - return (AsmFragmentSignatureExpr) visit(ctx); - } - - @Override - public AsmFragmentSignatureExpr visitPar(AsmFragmentSignatureParser.ParContext ctx) { - return this.visitExpr(ctx.expr()); - } - - @Override - public AsmFragmentSignatureExpr visitVar(AsmFragmentSignatureParser.VarContext ctx) { - final String varName = ctx.VAR().getText(); - // TODO: parse Type - SymbolType varType = SymbolType.VOID; - return new AsmFragmentSignatureExpr.Variable(varName, varType); - } - - @Override - public AsmFragmentSignatureExpr visitNum(AsmFragmentSignatureParser.NumContext ctx) { - final ConstantInteger num = new ConstantInteger((long) Integer.parseInt(ctx.NUM().getText())); - return new AsmFragmentSignatureExpr.Number(num); - } - - @Override - public AsmFragmentSignatureExpr visitBinary(AsmFragmentSignatureParser.BinaryContext ctx) { - final String operatorText = ctx.getChild(1).getText(); - final OperatorBinary operator = Operators.getBinaryFromAsmName(operatorText); - return new AsmFragmentSignatureExpr.Binary(operator, visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); - } - - @Override - public Object visitDerefSimple(AsmFragmentSignatureParser.DerefSimpleContext ctx) { - return new AsmFragmentSignatureExpr.DerefSimple(this.visitExpr(ctx.expr())); - } - - @Override - public Object visitDerefIdx(AsmFragmentSignatureParser.DerefIdxContext ctx) { - return new AsmFragmentSignatureExpr.DerefIdx(this.visitExpr(ctx.expr(0)), this.visitExpr(ctx.expr(1))); - } - - @Override - public AsmFragmentSignatureExpr visitUnary(AsmFragmentSignatureParser.UnaryContext ctx) { - final String operatorText = ctx.getChild(0).getText(); - final OperatorUnary operator = Operators.getUnaryFromAsmName(operatorText); - return new AsmFragmentSignatureExpr.Unary(operator, visitExpr(ctx.expr())); - } - - @Override - public AsmFragmentSignatureExpr visitMemset(AsmFragmentSignatureParser.MemsetContext ctx) { - return new AsmFragmentSignatureExpr.Memset(visitExpr(ctx.expr())); - } - - @Override - public AsmFragmentSignatureExpr visitMemcpy(AsmFragmentSignatureParser.MemcpyContext ctx) { - return new AsmFragmentSignatureExpr.Memcpy(visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); - } - - @Override - public AsmFragmentSignatureExpr visitStackPushPadding(AsmFragmentSignatureParser.StackPushPaddingContext ctx) { - final ConstantInteger bytes = new ConstantInteger((long) Integer.parseInt(ctx.NUM().getText())); - return new AsmFragmentSignatureExpr.StackPushPadding(bytes); - } - - @Override - public AsmFragmentSignatureExpr visitStackPullPadding(AsmFragmentSignatureParser.StackPullPaddingContext ctx) { - final ConstantInteger bytes = new ConstantInteger((long) Integer.parseInt(ctx.NUM().getText())); - return new AsmFragmentSignatureExpr.StackPullPadding(bytes); - } - - private SymbolType parseSymbolType(String typeText) { - switch (typeText) { - case "ptr": return new SymbolTypePointer(SymbolType.VOID); - case "byte": return SymbolType.BYTE; - case "sbyte": return SymbolType.SBYTE; - case "word": return SymbolType.WORD; - case "sword": return SymbolType.SWORD; - case "dword": return SymbolType.DWORD; - case "sdword": return SymbolType.SDWORD; - default: throw new RuntimeException("Unknown type "+typeText); - } - } - - @Override - public AsmFragmentSignatureExpr visitStackIdx(AsmFragmentSignatureParser.StackIdxContext ctx) { - final String typeText = ctx.getChild(0).getText().substring("stackidx".length()); - SymbolType type = parseSymbolType(typeText); - return new AsmFragmentSignatureExpr.StackIdx(type, null, visitExpr(ctx.expr())); - } - - @Override - public AsmFragmentSignatureExpr visitStackIdxStruct(AsmFragmentSignatureParser.StackIdxStructContext ctx) { - return new AsmFragmentSignatureExpr.StackIdx(STRUCT_TYPE, visitExpr(ctx.expr(0)), visitExpr(ctx.expr(1))); - } - - @Override - public AsmFragmentSignatureExpr visitStackPush(AsmFragmentSignatureParser.StackPushContext ctx) { - final String typeText = ctx.getChild(0).getText().substring("stackpush".length()); - SymbolType type = parseSymbolType(typeText); - return new AsmFragmentSignatureExpr.StackPush(type, null); - } - - @Override - public AsmFragmentSignatureExpr visitStackPushStruct(AsmFragmentSignatureParser.StackPushStructContext ctx) { - return new AsmFragmentSignatureExpr.StackPush(STRUCT_TYPE, visitExpr(ctx.expr())); - } - - @Override - public AsmFragmentSignatureExpr visitStackPull(AsmFragmentSignatureParser.StackPullContext ctx) { - final String typeText = ctx.getChild(0).getText().substring("stackpull".length()); - SymbolType type = parseSymbolType(typeText); - return new AsmFragmentSignatureExpr.StackPull(type, null); - } - - @Override - public AsmFragmentSignatureExpr visitStackPullStruct(AsmFragmentSignatureParser.StackPullStructContext ctx) { - return new AsmFragmentSignatureExpr.StackPull(STRUCT_TYPE, visitExpr(ctx.expr())); - } - - @Override - public AsmFragmentSignatureExpr visitMakelong4(AsmFragmentSignatureParser.Makelong4Context ctx) { - return new AsmFragmentSignatureExpr.Makelong4( - visitExpr(ctx.expr(0)), - visitExpr(ctx.expr(1)), - visitExpr(ctx.expr(2)), - visitExpr(ctx.expr(3))); - } - } }