mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-31 22:31:14 +00:00
Created ASM parser & representation
This commit is contained in:
parent
91b455e042
commit
8f9f042144
47
src/dk/camelot64/kickc/asm/AsmAddressingMode.java
Normal file
47
src/dk/camelot64/kickc/asm/AsmAddressingMode.java
Normal file
@ -0,0 +1,47 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** 6502 Assembler Instruction Addressing Modes. */
|
||||
public enum AsmAddressingMode {
|
||||
NON("", "%i", 1),
|
||||
IMM("#imm", "%i #%p", 2),
|
||||
ZP("zp", "%i %p", 2),
|
||||
ZPX("zp,x", "%i %p,x", 2),
|
||||
ZPY("zp,y", "%i %p,y", 2),
|
||||
ABS("abs", "%i %p", 3),
|
||||
ABX("abs,x", "%i %p,x", 3),
|
||||
ABY("abs,y", "%i %p,y", 4),
|
||||
IZX("(zp,x)", "%i (%p,x)", 2),
|
||||
IZY("(zp),y", "%i (%p),y", 2),
|
||||
REL("rel", "%i %p", 2),
|
||||
IND("(ind)", "%i (%p)", 3);
|
||||
|
||||
|
||||
private String name;
|
||||
|
||||
private String template;
|
||||
|
||||
private int bytes;
|
||||
|
||||
AsmAddressingMode(String name, String template, int bytes) {
|
||||
this.bytes = bytes;
|
||||
this.template = template;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAsm(String mnemnonic, String parameter) {
|
||||
String replaced = template.replace("%i", mnemnonic);
|
||||
if(parameter!=null) {
|
||||
replaced = replaced.replace("%p", parameter);
|
||||
}
|
||||
return replaced;
|
||||
}
|
||||
|
||||
}
|
35
src/dk/camelot64/kickc/asm/AsmComment.java
Normal file
35
src/dk/camelot64/kickc/asm/AsmComment.java
Normal file
@ -0,0 +1,35 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** An assember comment */
|
||||
public class AsmComment implements AsmLine {
|
||||
private String comment;
|
||||
|
||||
public AsmComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineBytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLineCycles() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInvocationCountEstimate() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getEstimatedTotalCycles() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsm() {
|
||||
return "// "+comment;
|
||||
}
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
import dk.camelot64.kickc.asm.parser.Asm6502BaseVisitor;
|
||||
import dk.camelot64.kickc.asm.parser.Asm6502Lexer;
|
||||
import dk.camelot64.kickc.asm.parser.Asm6502Parser;
|
||||
import dk.camelot64.kickc.icl.*;
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -26,7 +30,7 @@ public class AsmFragment {
|
||||
private Map<String, Value> bindings;
|
||||
|
||||
/**
|
||||
* The string signature/name of the asm fragment.
|
||||
* The string signature/name of the fragment fragment.
|
||||
*/
|
||||
private String signature;
|
||||
|
||||
@ -106,8 +110,8 @@ public class AsmFragment {
|
||||
case ">=":
|
||||
case "=>":
|
||||
return "_ge_";
|
||||
default:
|
||||
return op;
|
||||
default:
|
||||
return op;
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +201,7 @@ public class AsmFragment {
|
||||
* @param name The name of the bound value in the fragment
|
||||
* @return The bound value to use in the generated ASM code
|
||||
*/
|
||||
public String getValue(String name) {
|
||||
public String getBoundValue(String name) {
|
||||
Value boundValue = getBinding(name);
|
||||
String bound;
|
||||
if (boundValue instanceof Variable) {
|
||||
@ -232,27 +236,30 @@ public class AsmFragment {
|
||||
public void generateAsm(AsmSequence asm) {
|
||||
String signature = this.getSignature();
|
||||
ClassLoader classLoader = this.getClass().getClassLoader();
|
||||
URL fragmentResource = classLoader.getResource("dk/camelot64/kickc/icl/asm/" + signature + ".asm");
|
||||
final URL fragmentResource = classLoader.getResource("dk/camelot64/kickc/asm/fragment/" + signature + ".asm");
|
||||
if (fragmentResource == null) {
|
||||
System.out.println("Fragment not found " + fragmentResource);
|
||||
asm.addAsm(" // Fragment not found: " + signature);
|
||||
return;
|
||||
}
|
||||
Pattern bindPattern = Pattern.compile(".*\\{([^}]*)}.*");
|
||||
|
||||
try {
|
||||
InputStream fragmentStream = fragmentResource.openStream();
|
||||
BufferedReader fragmentReader = new BufferedReader(new InputStreamReader(fragmentStream));
|
||||
String line;
|
||||
while ((line = fragmentReader.readLine()) != null) {
|
||||
Matcher matcher = bindPattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
String name = matcher.group(1);
|
||||
String bound = this.getValue(name);
|
||||
line = line.replaceFirst("\\{[^}]*}", bound);
|
||||
Asm6502Lexer lexer = new Asm6502Lexer(new ANTLRInputStream(fragmentStream));
|
||||
Asm6502Parser parser = new Asm6502Parser(new CommonTokenStream(lexer));
|
||||
parser.addErrorListener(new BaseErrorListener() {
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||
throw new RuntimeException("Error parsing fragment file "+fragmentResource+"\n - Line: "+line+"\n - Message: "+msg);
|
||||
}
|
||||
asm.addAsm(" " + line);
|
||||
});
|
||||
parser.setBuildParseTree(true);
|
||||
Asm6502Parser.FileContext file = parser.file();
|
||||
AsmSequenceGenerator asmSequenceGenerator = new AsmSequenceGenerator(fragmentResource);
|
||||
asmSequenceGenerator.generate(file);
|
||||
for (AsmLine asmLine : asmSequenceGenerator.program.getLines()) {
|
||||
asm.addAsm(" "+asmLine.getAsm());
|
||||
}
|
||||
fragmentReader.close();
|
||||
fragmentStream.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading code fragment " + fragmentResource);
|
||||
@ -260,5 +267,119 @@ public class AsmFragment {
|
||||
|
||||
}
|
||||
|
||||
private class AsmSequenceGenerator extends Asm6502BaseVisitor {
|
||||
|
||||
private URL fragmentResource;
|
||||
private AsmProgram program;
|
||||
|
||||
public AsmSequenceGenerator(URL fragmentResource, AsmProgram program) {
|
||||
this.fragmentResource = fragmentResource;
|
||||
this.program = program;
|
||||
}
|
||||
|
||||
public AsmSequenceGenerator(URL fragmentResource) {
|
||||
this.fragmentResource = fragmentResource;
|
||||
this.program = new AsmProgram();
|
||||
}
|
||||
|
||||
public AsmProgram getProgram() {
|
||||
return program;
|
||||
}
|
||||
|
||||
public void generate(Asm6502Parser.FileContext context) {
|
||||
this.visit(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLabel(Asm6502Parser.LabelContext ctx) {
|
||||
program.addLine(new AsmLabel(ctx.getChild(0).getText()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitComment(Asm6502Parser.CommentContext ctx) {
|
||||
program.addLine(new AsmComment(ctx.getChild(1).getText()));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object visitInstruction(Asm6502Parser.InstructionContext ctx) {
|
||||
Asm6502Parser.ParamModeContext paramModeCtx = ctx.paramMode();
|
||||
AsmInstruction instruction;
|
||||
if(paramModeCtx==null) {
|
||||
AsmInstructionType type = AsmInstuctionSet.getInstructionType(ctx.MNEMONIC().getText(), AsmAddressingMode.NON);
|
||||
instruction = new AsmInstruction(type, null, 1);
|
||||
} else {
|
||||
instruction = (AsmInstruction) this.visit(paramModeCtx);
|
||||
}
|
||||
if(instruction!=null) {
|
||||
program.addLine(instruction);
|
||||
} else {
|
||||
throw new RuntimeException("Error parsing ASM fragment line in "+fragmentResource.toString()+"\n - Line: "+ctx.getText());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModeAbs(Asm6502Parser.ModeAbsContext ctx) {
|
||||
return createAsmInstruction(ctx, ctx.param(), AsmAddressingMode.ABS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModeImm(Asm6502Parser.ModeImmContext ctx) {
|
||||
return createAsmInstruction(ctx, ctx.param(), AsmAddressingMode.IMM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModeAbsX(Asm6502Parser.ModeAbsXContext ctx) {
|
||||
return createAsmInstruction(ctx, ctx.param(), AsmAddressingMode.ABX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModeAbsY(Asm6502Parser.ModeAbsYContext ctx) {
|
||||
return createAsmInstruction(ctx, ctx.param(), AsmAddressingMode.ABY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModeIndY(Asm6502Parser.ModeIndYContext ctx) {
|
||||
return createAsmInstruction(ctx, ctx.param(), AsmAddressingMode.IZY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModeIndX(Asm6502Parser.ModeIndXContext ctx) {
|
||||
return createAsmInstruction(ctx, ctx.param(), AsmAddressingMode.IZX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitModeInd(Asm6502Parser.ModeIndContext ctx) {
|
||||
return createAsmInstruction(ctx, ctx.param(), AsmAddressingMode.IND);
|
||||
}
|
||||
|
||||
private AsmInstruction createAsmInstruction(Asm6502Parser.ParamModeContext ctx, Asm6502Parser.ParamContext paramCtx, AsmAddressingMode addressingMode) {
|
||||
Asm6502Parser.InstructionContext instructionCtx = (Asm6502Parser.InstructionContext) ctx.getParent();
|
||||
String mnemonic = instructionCtx.MNEMONIC().getSymbol().getText();
|
||||
String parameter = (String) this.visit(paramCtx);
|
||||
AsmInstructionType type = AsmInstuctionSet.getInstructionType(mnemonic, addressingMode);
|
||||
return new AsmInstruction(type, parameter, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParamInt(Asm6502Parser.ParamIntContext ctx) {
|
||||
return NumberParser.parseLiteral(ctx.NUMINT().getText()).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParamLabel(Asm6502Parser.ParamLabelContext ctx) {
|
||||
return ctx.NAME().getSymbol().getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParamReplace(Asm6502Parser.ParamReplaceContext ctx) {
|
||||
String replaceName = ctx.NAME().getSymbol().getText();
|
||||
return AsmFragment.this.getBoundValue(replaceName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
45
src/dk/camelot64/kickc/asm/AsmInstruction.java
Normal file
45
src/dk/camelot64/kickc/asm/AsmInstruction.java
Normal file
@ -0,0 +1,45 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** An assembler instruction */
|
||||
public class AsmInstruction implements AsmLine {
|
||||
|
||||
private AsmInstructionType type;
|
||||
|
||||
private String parameter;
|
||||
|
||||
private int invocationCountEstimate;
|
||||
|
||||
public AsmInstruction(AsmInstructionType type, String parameter, int invocationCountEstimate) {
|
||||
this.type = type;
|
||||
this.parameter = parameter;
|
||||
this.invocationCountEstimate = invocationCountEstimate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineBytes() {
|
||||
return type.getBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLineCycles() {
|
||||
return type.getCycles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInvocationCountEstimate() {
|
||||
return invocationCountEstimate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getEstimatedTotalCycles() {
|
||||
return getInvocationCountEstimate()*getLineCycles();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getAsm() {
|
||||
return type.getAsm(parameter);
|
||||
}
|
||||
|
||||
|
||||
}
|
41
src/dk/camelot64/kickc/asm/AsmInstructionType.java
Normal file
41
src/dk/camelot64/kickc/asm/AsmInstructionType.java
Normal file
@ -0,0 +1,41 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** The instructions of the 6502 assembler instruction set */
|
||||
public class AsmInstructionType {
|
||||
|
||||
private int opcode;
|
||||
|
||||
private String mnemnonic;
|
||||
|
||||
private AsmAddressingMode addressingMode;
|
||||
|
||||
private double cycles;
|
||||
|
||||
public AsmInstructionType(int opcode, String mnemnonic, AsmAddressingMode addressingMode, double cycles) {
|
||||
this.opcode = opcode;
|
||||
this.mnemnonic = mnemnonic;
|
||||
this.addressingMode = addressingMode;
|
||||
this.cycles = cycles;
|
||||
}
|
||||
|
||||
public String getMnemnonic() {
|
||||
return mnemnonic;
|
||||
}
|
||||
|
||||
public AsmAddressingMode getAddressingMode() {
|
||||
return addressingMode;
|
||||
}
|
||||
|
||||
public double getCycles() {
|
||||
return cycles;
|
||||
}
|
||||
|
||||
public int getBytes() {
|
||||
return addressingMode.getBytes();
|
||||
}
|
||||
|
||||
public String getAsm(String parameter) {
|
||||
return addressingMode.getAsm(mnemnonic, parameter);
|
||||
}
|
||||
|
||||
}
|
312
src/dk/camelot64/kickc/asm/AsmInstuctionSet.java
Normal file
312
src/dk/camelot64/kickc/asm/AsmInstuctionSet.java
Normal file
@ -0,0 +1,312 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The set of all 6502 assembler instructions
|
||||
*/
|
||||
public class AsmInstuctionSet {
|
||||
|
||||
private static AsmInstuctionSet set = new AsmInstuctionSet();
|
||||
|
||||
public static AsmInstructionType getInstructionType(String mnemonic, AsmAddressingMode mode) {
|
||||
AsmInstructionType type = set.getType(mnemonic, mode);
|
||||
if(type==null && AsmAddressingMode.ABS.equals(mode)) {
|
||||
type = set.getType(mnemonic, AsmAddressingMode.REL);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private List<AsmInstructionType> instructions;
|
||||
|
||||
private void add(int opcode, String mnemonic, AsmAddressingMode addressingmMode, double cycles) {
|
||||
instructions.add(new AsmInstructionType(opcode, mnemonic.toLowerCase(), addressingmMode, cycles));
|
||||
}
|
||||
|
||||
public AsmInstuctionSet() {
|
||||
this.instructions = new ArrayList<>();
|
||||
AsmAddressingMode non = AsmAddressingMode.NON;
|
||||
AsmAddressingMode zp = AsmAddressingMode.ZP;
|
||||
AsmAddressingMode zpx = AsmAddressingMode.ZPX;
|
||||
AsmAddressingMode zpy = AsmAddressingMode.ZPY;
|
||||
AsmAddressingMode imm = AsmAddressingMode.IMM;
|
||||
AsmAddressingMode abs = AsmAddressingMode.ABS;
|
||||
AsmAddressingMode abx = AsmAddressingMode.ABX;
|
||||
AsmAddressingMode aby = AsmAddressingMode.ABY;
|
||||
AsmAddressingMode izx = AsmAddressingMode.IZX;
|
||||
AsmAddressingMode izy = AsmAddressingMode.IZY;
|
||||
AsmAddressingMode rel = AsmAddressingMode.REL;
|
||||
AsmAddressingMode ind = AsmAddressingMode.IND;
|
||||
add(0x00, "BRK", non, 7.0);
|
||||
add(0x01, "ORA", izx, 6.0);
|
||||
add(0x01, "ORA", izx, 6.0);
|
||||
add(0x02, "KIL", non, 0.0);
|
||||
add(0x03, "SLO", izx, 8.0);
|
||||
add(0x04, "NOP", zp, 3.0);
|
||||
add(0x05, "ORA", zp, 3.0);
|
||||
add(0x06, "ASL", zp, 5.0);
|
||||
add(0x07, "SLO", zp, 5.0);
|
||||
add(0x08, "PHP", non, 3.0);
|
||||
add(0x09, "ORA", imm, 2.0);
|
||||
add(0x0a, "ASL", non, 2.0);
|
||||
add(0x0b, "ANC", imm, 2.0);
|
||||
add(0x0c, "NOP", abs, 4.0);
|
||||
add(0x0d, "ORA", abs, 4.0);
|
||||
add(0x0e, "ASL", abs, 6.0);
|
||||
add(0x0f, "SLO", abs, 6.0);
|
||||
add(0x10, "BPL", rel, 2.5);
|
||||
add(0x11, "ORA", izy, 5.5);
|
||||
add(0x12, "KIL", non, 0.0);
|
||||
add(0x13, "SLO", izy, 8.0);
|
||||
add(0x14, "NOP", zpx, 4.0);
|
||||
add(0x15, "ORA", zpx, 4.0);
|
||||
add(0x16, "ASL", zpx, 6.0);
|
||||
add(0x17, "SLO", zpx, 6.0);
|
||||
add(0x18, "CLC", non, 2.0);
|
||||
add(0x19, "ORA", aby, 4.5);
|
||||
add(0x1a, "NOP", non, 2.0);
|
||||
add(0x1b, "SLO", aby, 7.0);
|
||||
add(0x1c, "NOP", abx, 4.5);
|
||||
add(0x1d, "ORA", abx, 4.5);
|
||||
add(0x1e, "ASL", abx, 7.0);
|
||||
add(0x1f, "SLO", abx, 7.0);
|
||||
add(0x20, "JSR", abs, 6.0);
|
||||
add(0x21, "AND", izx, 6.0);
|
||||
add(0x22, "KIL", non, 0.0);
|
||||
add(0x23, "RLA", izx, 8.0);
|
||||
add(0x24, "BIT", zp, 3.0);
|
||||
add(0x25, "AND", zp, 3.0);
|
||||
add(0x26, "ROL", zp, 5.0);
|
||||
add(0x27, "RLA", zp, 5.0);
|
||||
add(0x28, "PLP", non, 4.0);
|
||||
add(0x29, "AND", imm, 2.0);
|
||||
add(0x2a, "ROL", non, 2.0);
|
||||
add(0x2b, "ANC", imm, 2.0);
|
||||
add(0x2c, "BIT", abs, 4.0);
|
||||
add(0x2d, "AND", abs, 4.0);
|
||||
add(0x2e, "ROL", abs, 6.0);
|
||||
add(0x2f, "RLA", abs, 6.0);
|
||||
add(0x30, "BMI", rel, 2.5);
|
||||
add(0x31, "AND", izy, 5.5);
|
||||
add(0x32, "KIL", non, 0.0);
|
||||
add(0x33, "RLA", izy, 8.0);
|
||||
add(0x34, "NOP", zpx, 4.0);
|
||||
add(0x35, "AND", zpx, 4.0);
|
||||
add(0x36, "ROL", zpx, 6.0);
|
||||
add(0x37, "RLA", zpx, 6.0);
|
||||
add(0x38, "SEC", non, 2.0);
|
||||
add(0x39, "AND", aby, 4.5);
|
||||
add(0x3a, "NOP", non, 2.0);
|
||||
add(0x3b, "RLA", aby, 7.0);
|
||||
add(0x3c, "NOP", abx, 4.5);
|
||||
add(0x3d, "AND", abx, 4.5);
|
||||
add(0x3e, "ROL", abx, 7.0);
|
||||
add(0x3f, "RLA", abx, 7.0);
|
||||
add(0x40, "RTI", non, 6.0);
|
||||
add(0x41, "EOR", izx, 6.0);
|
||||
add(0x42, "KIL", non, 0.0);
|
||||
add(0x43, "SRE", izx, 8.0);
|
||||
add(0x44, "NOP", zp, 3.0);
|
||||
add(0x45, "EOR", zp, 3.0);
|
||||
add(0x46, "LSR", zp, 5.0);
|
||||
add(0x47, "SRE", zp, 5.0);
|
||||
add(0x48, "PHA", non, 3.0);
|
||||
add(0x49, "EOR", imm, 2.0);
|
||||
add(0x4a, "LSR", non, 2.0);
|
||||
add(0x4b, "ALR", imm, 2.0);
|
||||
add(0x4c, "JMP", abs, 3.0);
|
||||
add(0x4d, "EOR", abs, 4.0);
|
||||
add(0x4e, "LSR", abs, 6.0);
|
||||
add(0x4f, "SRE", abs, 6.0);
|
||||
add(0x50, "BVC", rel, 2.5);
|
||||
add(0x51, "EOR", izy, 5.5);
|
||||
add(0x52, "KIL", non, 0.0);
|
||||
add(0x53, "SRE", izy, 8.0);
|
||||
add(0x54, "NOP", zpx, 4.0);
|
||||
add(0x55, "EOR", zpx, 4.0);
|
||||
add(0x56, "LSR", zpx, 6.0);
|
||||
add(0x57, "SRE", zpx, 6.0);
|
||||
add(0x58, "CLI", non, 2.0);
|
||||
add(0x59, "EOR", aby, 4.5);
|
||||
add(0x5a, "NOP", non, 2.0);
|
||||
add(0x5b, "SRE", aby, 7.0);
|
||||
add(0x5c, "NOP", abx, 4.5);
|
||||
add(0x5d, "EOR", abx, 4.5);
|
||||
add(0x5e, "LSR", abx, 7.0);
|
||||
add(0x5f, "SRE", abx, 7.0);
|
||||
add(0x60, "RTS", non, 6.0);
|
||||
add(0x61, "ADC", izx, 6.0);
|
||||
add(0x62, "KIL", non, 0.0);
|
||||
add(0x63, "RRA", izx, 8.0);
|
||||
add(0x64, "NOP", zp, 3.0);
|
||||
add(0x65, "ADC", zp, 3.0);
|
||||
add(0x66, "ROR", zp, 5.0);
|
||||
add(0x67, "RRA", zp, 5.0);
|
||||
add(0x68, "PLA", non, 4.0);
|
||||
add(0x69, "ADC", imm, 2.0);
|
||||
add(0x6a, "ROR", non, 2.0);
|
||||
add(0x6b, "ARR", imm, 2.0);
|
||||
add(0x6c, "JMP", ind, 5.0);
|
||||
add(0x6d, "ADC", abs, 4.0);
|
||||
add(0x6e, "ROR", abs, 6.0);
|
||||
add(0x6f, "RRA", abs, 6.0);
|
||||
add(0x70, "BVS", rel, 2.5);
|
||||
add(0x71, "ADC", izy, 5.5);
|
||||
add(0x72, "KIL", non, 0.0);
|
||||
add(0x73, "RRA", izy, 8.0);
|
||||
add(0x74, "NOP", zpx, 4.0);
|
||||
add(0x75, "ADC", zpx, 4.0);
|
||||
add(0x76, "ROR", zpx, 6.0);
|
||||
add(0x77, "RRA", zpx, 6.0);
|
||||
add(0x78, "SEI", non, 2.0);
|
||||
add(0x79, "ADC", aby, 4.5);
|
||||
add(0x7a, "NOP", non, 2.0);
|
||||
add(0x7b, "RRA", aby, 7.0);
|
||||
add(0x7c, "NOP", abx, 4.5);
|
||||
add(0x7d, "ADC", abx, 4.5);
|
||||
add(0x7e, "ROR", abx, 7.0);
|
||||
add(0x7f, "RRA", abx, 7.0);
|
||||
add(0x80, "NOP", imm, 2.0);
|
||||
add(0x81, "STA", izx, 6.0);
|
||||
add(0x82, "NOP", imm, 2.0);
|
||||
add(0x83, "SAX", izx, 6.0);
|
||||
add(0x84, "STY", zp, 3.0);
|
||||
add(0x85, "STA", zp, 3.0);
|
||||
add(0x86, "STX", zp, 3.0);
|
||||
add(0x87, "SAX", zp, 3.0);
|
||||
add(0x88, "DEY", non, 2.0);
|
||||
add(0x89, "NOP", imm, 2.0);
|
||||
add(0x8a, "TXA", non, 2.0);
|
||||
add(0x8b, "XAA", imm, 2.0);
|
||||
add(0x8c, "STY", abs, 4.0);
|
||||
add(0x8d, "STA", abs, 4.0);
|
||||
add(0x8e, "STX", abs, 4.0);
|
||||
add(0x8f, "SAX", abs, 4.0);
|
||||
add(0x90, "BCC", rel, 2.5);
|
||||
add(0x91, "STA", izy, 6.0);
|
||||
add(0x92, "KIL", non, 0.0);
|
||||
add(0x93, "AHX", izy, 6.0);
|
||||
add(0x94, "STY", zpx, 4.0);
|
||||
add(0x95, "STA", zpx, 4.0);
|
||||
add(0x96, "STX", zpy, 4.0);
|
||||
add(0x97, "SAX", zpy, 4.0);
|
||||
add(0x98, "TYA", non, 2.0);
|
||||
add(0x99, "STA", aby, 5.0);
|
||||
add(0x9a, "TXS", non, 2.0);
|
||||
add(0x9b, "TAS", aby, 5.0);
|
||||
add(0x9c, "SHY", abx, 5.0);
|
||||
add(0x9d, "STA", abx, 5.0);
|
||||
add(0x9e, "SHX", aby, 5.0);
|
||||
add(0x9f, "AHX", aby, 5.0);
|
||||
add(0xa0, "LDY", imm, 2.0);
|
||||
add(0xa1, "LDA", izx, 6.0);
|
||||
add(0xa2, "LDX", imm, 2.0);
|
||||
add(0xa3, "LAX", izx, 6.0);
|
||||
add(0xa4, "LDY", zp, 3.0);
|
||||
add(0xa5, "LDA", zp, 3.0);
|
||||
add(0xa6, "LDX", zp, 3.0);
|
||||
add(0xa7, "LAX", zp, 3.0);
|
||||
add(0xa8, "TAY", non, 2.0);
|
||||
add(0xa9, "LDA", imm, 2.0);
|
||||
add(0xaa, "TAX", non, 2.0);
|
||||
add(0xab, "LAX", imm, 2.0);
|
||||
add(0xac, "LDY", abs, 4.0);
|
||||
add(0xad, "LDA", abs, 4.0);
|
||||
add(0xae, "LDX", abs, 4.0);
|
||||
add(0xaf, "LAX", abs, 4.0);
|
||||
add(0xb0, "BCS", rel, 2.5);
|
||||
add(0xb1, "LDA", izy, 5.5);
|
||||
add(0xb2, "KIL", non, 0.0);
|
||||
add(0xb3, "LAX", izy, 5.5);
|
||||
add(0xb4, "LDY", zpx, 4.0);
|
||||
add(0xb5, "LDA", zpx, 4.0);
|
||||
add(0xb6, "LDX", zpy, 4.0);
|
||||
add(0xb7, "LAX", zpy, 4.0);
|
||||
add(0xb8, "CLV", non, 2.0);
|
||||
add(0xb9, "LDA", aby, 4.5);
|
||||
add(0xba, "TSX", non, 2.0);
|
||||
add(0xbb, "LAS", aby, 4.5);
|
||||
add(0xbc, "LDY", abx, 4.5);
|
||||
add(0xbd, "LDA", abx, 4.5);
|
||||
add(0xbe, "LDX", aby, 4.5);
|
||||
add(0xbf, "LAX", aby, 4.5);
|
||||
add(0xc0, "CPY", imm, 2.0);
|
||||
add(0xc1, "CMP", izx, 6.0);
|
||||
add(0xc2, "NOP", imm, 2.0);
|
||||
add(0xc3, "DCP", izx, 8.0);
|
||||
add(0xc4, "CPY", zp, 3.0);
|
||||
add(0xc5, "CMP", zp, 3.0);
|
||||
add(0xc6, "DEC", zp, 5.0);
|
||||
add(0xc7, "DCP", zp, 5.0);
|
||||
add(0xc8, "INY", non, 2.0);
|
||||
add(0xc9, "CMP", imm, 2.0);
|
||||
add(0xca, "DEX", non, 2.0);
|
||||
add(0xcb, "AXS", imm, 2.0);
|
||||
add(0xcc, "CPY", abs, 4.0);
|
||||
add(0xcd, "CMP", abs, 4.0);
|
||||
add(0xce, "DEC", abs, 6.0);
|
||||
add(0xcf, "DCP", abs, 6.0);
|
||||
add(0xd0, "BNE", rel, 2.5);
|
||||
add(0xd1, "CMP", izy, 5.5);
|
||||
add(0xd2, "KIL", non, 0.0);
|
||||
add(0xd3, "DCP", izy, 8.0);
|
||||
add(0xd4, "NOP", zpx, 4.0);
|
||||
add(0xd5, "CMP", zpx, 4.0);
|
||||
add(0xd6, "DEC", zpx, 6.0);
|
||||
add(0xd7, "DCP", zpx, 6.0);
|
||||
add(0xd8, "CLD", non, 2.0);
|
||||
add(0xd9, "CMP", aby, 4.5);
|
||||
add(0xda, "NOP", non, 2.0);
|
||||
add(0xdb, "DCP", aby, 7.0);
|
||||
add(0xdc, "NOP", abx, 4.5);
|
||||
add(0xdd, "CMP", abx, 4.5);
|
||||
add(0xde, "DEC", abx, 7.0);
|
||||
add(0xef, "CPX", imm, 2.0);
|
||||
add(0xe0, "SBC", izx, 6.0);
|
||||
add(0xe1, "NOP", imm, 2.0);
|
||||
add(0xe2, "ISC", izx, 8.0);
|
||||
add(0xe3, "CPX", zp, 3.0);
|
||||
add(0xe4, "SBC", zp, 3.0);
|
||||
add(0xe5, "INC", zp, 5.0);
|
||||
add(0xe6, "ISC", zp, 5.0);
|
||||
add(0xe7, "INX", non, 2.0);
|
||||
add(0xe8, "SBC", imm, 2.0);
|
||||
add(0xe9, "NOP", non, 2.0);
|
||||
add(0xea, "SBC", imm, 2.0);
|
||||
add(0xeb, "CPX", abs, 4.0);
|
||||
add(0xec, "SBC", abs, 4.0);
|
||||
add(0xed, "INC", abs, 6.0);
|
||||
add(0xee, "ISC", abs, 6.0);
|
||||
add(0xef, "DCP", abx, 7.0);
|
||||
add(0xf0, "BEQ", rel, 2.5);
|
||||
add(0xf1, "SBC", izy, 5.5);
|
||||
add(0xf2, "KIL", non, 0.0);
|
||||
add(0xf3, "ISC", izy, 8.0);
|
||||
add(0xf4, "NOP", zpx, 4.0);
|
||||
add(0xf5, "SBC", zpx, 4.0);
|
||||
add(0xf6, "INC", zpx, 6.0);
|
||||
add(0xf7, "ISC", zpx, 6.0);
|
||||
add(0xf8, "SED", non, 2.0);
|
||||
add(0xf9, "SBC", aby, 4.5);
|
||||
add(0xfa, "NOP", non, 2.0);
|
||||
add(0xfb, "ISC", aby, 7.0);
|
||||
add(0xfc, "NOP", abx, 4.5);
|
||||
add(0xfd, "SBC", abx, 4.5);
|
||||
add(0xfe, "INC", abx, 7.0);
|
||||
add(0xff, "ISC", abx, 7.0);
|
||||
|
||||
}
|
||||
|
||||
public AsmInstructionType getType(String mnemonic, AsmAddressingMode addressingMode) {
|
||||
for (AsmInstructionType candidate : instructions) {
|
||||
if(candidate.getMnemnonic().equals(mnemonic.toLowerCase()) && candidate.getAddressingMode().equals(addressingMode)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
36
src/dk/camelot64/kickc/asm/AsmLabel.java
Normal file
36
src/dk/camelot64/kickc/asm/AsmLabel.java
Normal file
@ -0,0 +1,36 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** A label / jump target */
|
||||
public class AsmLabel implements AsmLine {
|
||||
|
||||
private String label;
|
||||
|
||||
public AsmLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineBytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLineCycles() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInvocationCountEstimate() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getEstimatedTotalCycles() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsm() {
|
||||
return ":"+label;
|
||||
}
|
||||
}
|
16
src/dk/camelot64/kickc/asm/AsmLine.java
Normal file
16
src/dk/camelot64/kickc/asm/AsmLine.java
Normal file
@ -0,0 +1,16 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
/** A line of 6502 assembler code */
|
||||
public interface AsmLine {
|
||||
|
||||
public int getLineBytes();
|
||||
|
||||
public double getLineCycles();
|
||||
|
||||
public int getInvocationCountEstimate();
|
||||
|
||||
public double getEstimatedTotalCycles();
|
||||
|
||||
public String getAsm();
|
||||
|
||||
}
|
22
src/dk/camelot64/kickc/asm/AsmProgram.java
Normal file
22
src/dk/camelot64/kickc/asm/AsmProgram.java
Normal file
@ -0,0 +1,22 @@
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** A 6502 assembler program */
|
||||
public class AsmProgram {
|
||||
|
||||
private List<AsmLine> lines;
|
||||
|
||||
public AsmProgram() {
|
||||
this.lines = new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<AsmLine> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
public void addLine(AsmLine line) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
package dk.camelot64.kickc.asm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
1
src/dk/camelot64/kickc/asm/fragment/xby=coby1.asm
Normal file
1
src/dk/camelot64/kickc/asm/fragment/xby=coby1.asm
Normal file
@ -0,0 +1 @@
|
||||
ldx #{coby1}
|
1
src/dk/camelot64/kickc/asm/fragment/xby=xby_minus_1.asm
Normal file
1
src/dk/camelot64/kickc/asm/fragment/xby=xby_minus_1.asm
Normal file
@ -0,0 +1 @@
|
||||
dex
|
@ -0,0 +1,2 @@
|
||||
cpx #0
|
||||
bne {la1}
|
11
src/dk/camelot64/kickc/asm/fragment/zpbo1=zpby1_gt_coby1.asm
Normal file
11
src/dk/camelot64/kickc/asm/fragment/zpbo1=zpby1_gt_coby1.asm
Normal file
@ -0,0 +1,11 @@
|
||||
LDA {zpby1}
|
||||
CMP #{coby1}
|
||||
BEQ !f+
|
||||
BCS !t+
|
||||
!f:
|
||||
LDA #0
|
||||
JMP !d+
|
||||
!t:
|
||||
LDA #$ff
|
||||
!d:
|
||||
STA {zpbo1}
|
@ -5,4 +5,4 @@ beq !t+
|
||||
!f: lda #0
|
||||
jmp !d+
|
||||
!t: lda #$ff
|
||||
!d: sta {zpbo1}
|
||||
!d: sta {zpbo1
|
@ -4,4 +4,4 @@ bcc !t+
|
||||
!f: lda #0
|
||||
jmp !d+
|
||||
!t: lda #$ff
|
||||
!d: sta {zpbo1}
|
||||
!d: sta {zpbo1}
|
@ -1,2 +1,2 @@
|
||||
lda #{coby1}
|
||||
sta {zpby1}
|
||||
sta {zpby1}
|
@ -1,2 +1,2 @@
|
||||
lda {zpby2}
|
||||
sta {zpby1}
|
||||
sta {zpby1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpby2}
|
||||
sec
|
||||
sbc #1
|
||||
sta {zpby1}
|
@ -1,4 +1,4 @@
|
||||
lda {zpby2}
|
||||
sec
|
||||
sbc #{coby1}
|
||||
sta {zpby1}
|
||||
sta {zpby1}
|
@ -0,0 +1,4 @@
|
||||
lda {zpby1}
|
||||
clc
|
||||
adc #1
|
||||
sta {zpby2}
|
@ -1,4 +1,4 @@
|
||||
lda {zpby2}
|
||||
clc
|
||||
adc {zpby3}
|
||||
sta {zpby1}
|
||||
sta {zpby1}
|
@ -2,4 +2,4 @@ lda {zpby1}
|
||||
cmp #{coby1}
|
||||
beq !+
|
||||
bcs {la1}
|
||||
!:
|
||||
!:
|
@ -0,0 +1,3 @@
|
||||
lda {zpby1}
|
||||
cmp #{coby1}
|
||||
bcc {la1}
|
55
src/dk/camelot64/kickc/asm/parser/Asm6502.g4
Normal file
55
src/dk/camelot64/kickc/asm/parser/Asm6502.g4
Normal file
@ -0,0 +1,55 @@
|
||||
// 6502 Assembler Grammar
|
||||
grammar Asm6502;
|
||||
|
||||
file :
|
||||
lineSeq EOF
|
||||
;
|
||||
|
||||
lineSeq
|
||||
: line+
|
||||
;
|
||||
|
||||
line
|
||||
: label? instruction? comment? '\n'
|
||||
;
|
||||
|
||||
label
|
||||
: NAME ':'
|
||||
;
|
||||
|
||||
comment
|
||||
: '//' .*?
|
||||
;
|
||||
|
||||
instruction
|
||||
: MNEMONIC (paramMode)?
|
||||
;
|
||||
|
||||
paramMode
|
||||
: param #modeAbs
|
||||
| '#' param #modeImm
|
||||
| param ',x' #modeAbsX
|
||||
| param ',y' #modeAbsY
|
||||
| '(' param ')' ',y' #modeIndY
|
||||
| '(' param ',x' ')' #modeIndX
|
||||
| '(' param ')' #modeInd
|
||||
;
|
||||
|
||||
param
|
||||
: NAME #paramLabel
|
||||
| '{' NAME '}' #paramReplace
|
||||
| NUMINT #paramInt
|
||||
;
|
||||
|
||||
MNEMONIC: [A-Za-z][A-Za-z][A-Za-z];
|
||||
NUMINT : DECINTEGER | HEXINTEGER | BININTEGER ;
|
||||
BININTEGER : '0' [bB] BINDIGIT+ | '%' BINDIGIT+ ;
|
||||
DECINTEGER : DECDIGIT+ ;
|
||||
HEXINTEGER : ( '$' | '0x' | '0X' ) HEXDIGIT+ ;
|
||||
fragment BINDIGIT : [0-1];
|
||||
fragment DECDIGIT : [0-9];
|
||||
fragment HEXDIGIT : [0-9a-fA-F];
|
||||
NAME : NAME_START NAME_CHAR* [+-]* ;
|
||||
fragment NAME_START : [!a-zA-Z_];
|
||||
fragment NAME_CHAR : [a-zA-Z0-9_];
|
||||
WS : [ \t\r]+ -> skip ; // skip spaces, tabs
|
27
src/dk/camelot64/kickc/asm/parser/Asm6502.tokens
Normal file
27
src/dk/camelot64/kickc/asm/parser/Asm6502.tokens
Normal file
@ -0,0 +1,27 @@
|
||||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
MNEMONIC=11
|
||||
NUMINT=12
|
||||
BININTEGER=13
|
||||
DECINTEGER=14
|
||||
HEXINTEGER=15
|
||||
NAME=16
|
||||
WS=17
|
||||
'\n'=1
|
||||
':'=2
|
||||
'//'=3
|
||||
'#'=4
|
||||
',x'=5
|
||||
',y'=6
|
||||
'('=7
|
||||
')'=8
|
||||
'{'=9
|
||||
'}'=10
|
231
src/dk/camelot64/kickc/asm/parser/Asm6502BaseListener.java
Normal file
231
src/dk/camelot64/kickc/asm/parser/Asm6502BaseListener.java
Normal file
@ -0,0 +1,231 @@
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/dk/camelot64/kickc/asm/parser/Asm6502.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.asm.parser;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link Asm6502Listener},
|
||||
* which can be extended to create a listener which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*/
|
||||
public class Asm6502BaseListener implements Asm6502Listener {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterFile(Asm6502Parser.FileContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitFile(Asm6502Parser.FileContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterLineSeq(Asm6502Parser.LineSeqContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLineSeq(Asm6502Parser.LineSeqContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterLine(Asm6502Parser.LineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLine(Asm6502Parser.LineContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterLabel(Asm6502Parser.LabelContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitLabel(Asm6502Parser.LabelContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterComment(Asm6502Parser.CommentContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitComment(Asm6502Parser.CommentContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterInstruction(Asm6502Parser.InstructionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitInstruction(Asm6502Parser.InstructionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterModeAbs(Asm6502Parser.ModeAbsContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitModeAbs(Asm6502Parser.ModeAbsContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterModeImm(Asm6502Parser.ModeImmContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitModeImm(Asm6502Parser.ModeImmContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterModeAbsX(Asm6502Parser.ModeAbsXContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitModeAbsX(Asm6502Parser.ModeAbsXContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterModeAbsY(Asm6502Parser.ModeAbsYContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitModeAbsY(Asm6502Parser.ModeAbsYContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterModeIndY(Asm6502Parser.ModeIndYContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitModeIndY(Asm6502Parser.ModeIndYContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterModeIndX(Asm6502Parser.ModeIndXContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitModeIndX(Asm6502Parser.ModeIndXContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterModeInd(Asm6502Parser.ModeIndContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitModeInd(Asm6502Parser.ModeIndContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterParamLabel(Asm6502Parser.ParamLabelContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitParamLabel(Asm6502Parser.ParamLabelContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterParamReplace(Asm6502Parser.ParamReplaceContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitParamReplace(Asm6502Parser.ParamReplaceContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterParamInt(Asm6502Parser.ParamIntContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitParamInt(Asm6502Parser.ParamIntContext ctx) { }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitTerminal(TerminalNode node) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitErrorNode(ErrorNode node) { }
|
||||
}
|
126
src/dk/camelot64/kickc/asm/parser/Asm6502BaseVisitor.java
Normal file
126
src/dk/camelot64/kickc/asm/parser/Asm6502BaseVisitor.java
Normal file
@ -0,0 +1,126 @@
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/dk/camelot64/kickc/asm/parser/Asm6502.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.asm.parser;
|
||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link Asm6502Visitor},
|
||||
* which can be extended to create a visitor which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
public class Asm6502BaseVisitor<T> extends AbstractParseTreeVisitor<T> implements Asm6502Visitor<T> {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitFile(Asm6502Parser.FileContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitLineSeq(Asm6502Parser.LineSeqContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitLine(Asm6502Parser.LineContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitLabel(Asm6502Parser.LabelContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitComment(Asm6502Parser.CommentContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitInstruction(Asm6502Parser.InstructionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitModeAbs(Asm6502Parser.ModeAbsContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitModeImm(Asm6502Parser.ModeImmContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitModeAbsX(Asm6502Parser.ModeAbsXContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitModeAbsY(Asm6502Parser.ModeAbsYContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitModeIndY(Asm6502Parser.ModeIndYContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitModeIndX(Asm6502Parser.ModeIndXContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitModeInd(Asm6502Parser.ModeIndContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParamLabel(Asm6502Parser.ParamLabelContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParamReplace(Asm6502Parser.ParamReplaceContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParamInt(Asm6502Parser.ParamIntContext ctx) { return visitChildren(ctx); }
|
||||
}
|
152
src/dk/camelot64/kickc/asm/parser/Asm6502Lexer.java
Normal file
152
src/dk/camelot64/kickc/asm/parser/Asm6502Lexer.java
Normal file
@ -0,0 +1,152 @@
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/dk/camelot64/kickc/asm/parser/Asm6502.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.asm.parser;
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class Asm6502Lexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
|
||||
T__9=10, MNEMONIC=11, NUMINT=12, BININTEGER=13, DECINTEGER=14, HEXINTEGER=15,
|
||||
NAME=16, WS=17;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
public static final String[] ruleNames = {
|
||||
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
|
||||
"T__9", "MNEMONIC", "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER",
|
||||
"BINDIGIT", "DECDIGIT", "HEXDIGIT", "NAME", "NAME_START", "NAME_CHAR",
|
||||
"WS"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'\n'", "':'", "'//'", "'#'", "',x'", "',y'", "'('", "')'", "'{'",
|
||||
"'}'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, null, null, null, null, null, null, null, null, null, null, "MNEMONIC",
|
||||
"NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "WS"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String[] tokenNames;
|
||||
static {
|
||||
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||
for (int i = 0; i < tokenNames.length; i++) {
|
||||
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||
}
|
||||
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
|
||||
public Asm6502Lexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "Asm6502.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public String[] getChannelNames() { return channelNames; }
|
||||
|
||||
@Override
|
||||
public String[] getModeNames() { return modeNames; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\23\u008d\b\1\4\2"+
|
||||
"\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+
|
||||
"\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
|
||||
"\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\3\2\3\2\3\3\3"+
|
||||
"\3\3\4\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\7\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n"+
|
||||
"\3\13\3\13\3\f\3\f\3\f\3\f\3\r\3\r\3\r\5\rN\n\r\3\16\3\16\3\16\6\16S\n"+
|
||||
"\16\r\16\16\16T\3\16\3\16\6\16Y\n\16\r\16\16\16Z\5\16]\n\16\3\17\6\17"+
|
||||
"`\n\17\r\17\16\17a\3\20\3\20\3\20\3\20\3\20\5\20i\n\20\3\20\6\20l\n\20"+
|
||||
"\r\20\16\20m\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\7\24x\n\24\f\24\16"+
|
||||
"\24{\13\24\3\24\7\24~\n\24\f\24\16\24\u0081\13\24\3\25\3\25\3\26\3\26"+
|
||||
"\3\27\6\27\u0088\n\27\r\27\16\27\u0089\3\27\3\27\2\2\30\3\3\5\4\7\5\t"+
|
||||
"\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\2#\2%\2"+
|
||||
"\'\22)\2+\2-\23\3\2\13\4\2C\\c|\4\2DDdd\3\2\62\63\3\2\62;\5\2\62;CHch"+
|
||||
"\4\2--//\6\2##C\\aac|\6\2\62;C\\aac|\5\2\13\13\17\17\"\"\2\u0093\2\3\3"+
|
||||
"\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2"+
|
||||
"\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3"+
|
||||
"\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2\'\3\2\2\2\2-\3\2\2\2\3"+
|
||||
"/\3\2\2\2\5\61\3\2\2\2\7\63\3\2\2\2\t\66\3\2\2\2\138\3\2\2\2\r;\3\2\2"+
|
||||
"\2\17>\3\2\2\2\21@\3\2\2\2\23B\3\2\2\2\25D\3\2\2\2\27F\3\2\2\2\31M\3\2"+
|
||||
"\2\2\33\\\3\2\2\2\35_\3\2\2\2\37h\3\2\2\2!o\3\2\2\2#q\3\2\2\2%s\3\2\2"+
|
||||
"\2\'u\3\2\2\2)\u0082\3\2\2\2+\u0084\3\2\2\2-\u0087\3\2\2\2/\60\7\f\2\2"+
|
||||
"\60\4\3\2\2\2\61\62\7<\2\2\62\6\3\2\2\2\63\64\7\61\2\2\64\65\7\61\2\2"+
|
||||
"\65\b\3\2\2\2\66\67\7%\2\2\67\n\3\2\2\289\7.\2\29:\7z\2\2:\f\3\2\2\2;"+
|
||||
"<\7.\2\2<=\7{\2\2=\16\3\2\2\2>?\7*\2\2?\20\3\2\2\2@A\7+\2\2A\22\3\2\2"+
|
||||
"\2BC\7}\2\2C\24\3\2\2\2DE\7\177\2\2E\26\3\2\2\2FG\t\2\2\2GH\t\2\2\2HI"+
|
||||
"\t\2\2\2I\30\3\2\2\2JN\5\35\17\2KN\5\37\20\2LN\5\33\16\2MJ\3\2\2\2MK\3"+
|
||||
"\2\2\2ML\3\2\2\2N\32\3\2\2\2OP\7\62\2\2PR\t\3\2\2QS\5!\21\2RQ\3\2\2\2"+
|
||||
"ST\3\2\2\2TR\3\2\2\2TU\3\2\2\2U]\3\2\2\2VX\7\'\2\2WY\5!\21\2XW\3\2\2\2"+
|
||||
"YZ\3\2\2\2ZX\3\2\2\2Z[\3\2\2\2[]\3\2\2\2\\O\3\2\2\2\\V\3\2\2\2]\34\3\2"+
|
||||
"\2\2^`\5#\22\2_^\3\2\2\2`a\3\2\2\2a_\3\2\2\2ab\3\2\2\2b\36\3\2\2\2ci\7"+
|
||||
"&\2\2de\7\62\2\2ei\7z\2\2fg\7\62\2\2gi\7Z\2\2hc\3\2\2\2hd\3\2\2\2hf\3"+
|
||||
"\2\2\2ik\3\2\2\2jl\5%\23\2kj\3\2\2\2lm\3\2\2\2mk\3\2\2\2mn\3\2\2\2n \3"+
|
||||
"\2\2\2op\t\4\2\2p\"\3\2\2\2qr\t\5\2\2r$\3\2\2\2st\t\6\2\2t&\3\2\2\2uy"+
|
||||
"\5)\25\2vx\5+\26\2wv\3\2\2\2x{\3\2\2\2yw\3\2\2\2yz\3\2\2\2z\177\3\2\2"+
|
||||
"\2{y\3\2\2\2|~\t\7\2\2}|\3\2\2\2~\u0081\3\2\2\2\177}\3\2\2\2\177\u0080"+
|
||||
"\3\2\2\2\u0080(\3\2\2\2\u0081\177\3\2\2\2\u0082\u0083\t\b\2\2\u0083*\3"+
|
||||
"\2\2\2\u0084\u0085\t\t\2\2\u0085,\3\2\2\2\u0086\u0088\t\n\2\2\u0087\u0086"+
|
||||
"\3\2\2\2\u0088\u0089\3\2\2\2\u0089\u0087\3\2\2\2\u0089\u008a\3\2\2\2\u008a"+
|
||||
"\u008b\3\2\2\2\u008b\u008c\b\27\2\2\u008c.\3\2\2\2\r\2MTZ\\ahmy\177\u0089"+
|
||||
"\3\b\2\2";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
27
src/dk/camelot64/kickc/asm/parser/Asm6502Lexer.tokens
Normal file
27
src/dk/camelot64/kickc/asm/parser/Asm6502Lexer.tokens
Normal file
@ -0,0 +1,27 @@
|
||||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
MNEMONIC=11
|
||||
NUMINT=12
|
||||
BININTEGER=13
|
||||
DECINTEGER=14
|
||||
HEXINTEGER=15
|
||||
NAME=16
|
||||
WS=17
|
||||
'\n'=1
|
||||
':'=2
|
||||
'//'=3
|
||||
'#'=4
|
||||
',x'=5
|
||||
',y'=6
|
||||
'('=7
|
||||
')'=8
|
||||
'{'=9
|
||||
'}'=10
|
190
src/dk/camelot64/kickc/asm/parser/Asm6502Listener.java
Normal file
190
src/dk/camelot64/kickc/asm/parser/Asm6502Listener.java
Normal file
@ -0,0 +1,190 @@
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/dk/camelot64/kickc/asm/parser/Asm6502.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.asm.parser;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
|
||||
/**
|
||||
* This interface defines a complete listener for a parse tree produced by
|
||||
* {@link Asm6502Parser}.
|
||||
*/
|
||||
public interface Asm6502Listener extends ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by {@link Asm6502Parser#file}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterFile(Asm6502Parser.FileContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link Asm6502Parser#file}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitFile(Asm6502Parser.FileContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link Asm6502Parser#lineSeq}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLineSeq(Asm6502Parser.LineSeqContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link Asm6502Parser#lineSeq}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLineSeq(Asm6502Parser.LineSeqContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link Asm6502Parser#line}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLine(Asm6502Parser.LineContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link Asm6502Parser#line}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLine(Asm6502Parser.LineContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link Asm6502Parser#label}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLabel(Asm6502Parser.LabelContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link Asm6502Parser#label}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLabel(Asm6502Parser.LabelContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link Asm6502Parser#comment}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterComment(Asm6502Parser.CommentContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link Asm6502Parser#comment}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitComment(Asm6502Parser.CommentContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link Asm6502Parser#instruction}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterInstruction(Asm6502Parser.InstructionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link Asm6502Parser#instruction}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitInstruction(Asm6502Parser.InstructionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code modeAbs}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterModeAbs(Asm6502Parser.ModeAbsContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code modeAbs}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitModeAbs(Asm6502Parser.ModeAbsContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code modeImm}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterModeImm(Asm6502Parser.ModeImmContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code modeImm}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitModeImm(Asm6502Parser.ModeImmContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code modeAbsX}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterModeAbsX(Asm6502Parser.ModeAbsXContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code modeAbsX}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitModeAbsX(Asm6502Parser.ModeAbsXContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code modeAbsY}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterModeAbsY(Asm6502Parser.ModeAbsYContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code modeAbsY}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitModeAbsY(Asm6502Parser.ModeAbsYContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code modeIndY}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterModeIndY(Asm6502Parser.ModeIndYContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code modeIndY}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitModeIndY(Asm6502Parser.ModeIndYContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code modeIndX}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterModeIndX(Asm6502Parser.ModeIndXContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code modeIndX}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitModeIndX(Asm6502Parser.ModeIndXContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code modeInd}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterModeInd(Asm6502Parser.ModeIndContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code modeInd}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitModeInd(Asm6502Parser.ModeIndContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code paramLabel}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParamLabel(Asm6502Parser.ParamLabelContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code paramLabel}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParamLabel(Asm6502Parser.ParamLabelContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code paramReplace}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParamReplace(Asm6502Parser.ParamReplaceContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code paramReplace}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParamReplace(Asm6502Parser.ParamReplaceContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code paramInt}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParamInt(Asm6502Parser.ParamIntContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code paramInt}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParamInt(Asm6502Parser.ParamIntContext ctx);
|
||||
}
|
821
src/dk/camelot64/kickc/asm/parser/Asm6502Parser.java
Normal file
821
src/dk/camelot64/kickc/asm/parser/Asm6502Parser.java
Normal file
@ -0,0 +1,821 @@
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/dk/camelot64/kickc/asm/parser/Asm6502.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.asm.parser;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class Asm6502Parser extends Parser {
|
||||
static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
|
||||
T__9=10, MNEMONIC=11, NUMINT=12, BININTEGER=13, DECINTEGER=14, HEXINTEGER=15,
|
||||
NAME=16, WS=17;
|
||||
public static final int
|
||||
RULE_file = 0, RULE_lineSeq = 1, RULE_line = 2, RULE_label = 3, RULE_comment = 4,
|
||||
RULE_instruction = 5, RULE_paramMode = 6, RULE_param = 7;
|
||||
public static final String[] ruleNames = {
|
||||
"file", "lineSeq", "line", "label", "comment", "instruction", "paramMode",
|
||||
"param"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'\n'", "':'", "'//'", "'#'", "',x'", "',y'", "'('", "')'", "'{'",
|
||||
"'}'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, null, null, null, null, null, null, null, null, null, null, "MNEMONIC",
|
||||
"NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "WS"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String[] tokenNames;
|
||||
static {
|
||||
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||
for (int i = 0; i < tokenNames.length; i++) {
|
||||
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||
}
|
||||
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "Asm6502.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public Asm6502Parser(TokenStream input) {
|
||||
super(input);
|
||||
_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
public static class FileContext extends ParserRuleContext {
|
||||
public LineSeqContext lineSeq() {
|
||||
return getRuleContext(LineSeqContext.class,0);
|
||||
}
|
||||
public TerminalNode EOF() { return getToken(Asm6502Parser.EOF, 0); }
|
||||
public FileContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_file; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterFile(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitFile(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitFile(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final FileContext file() throws RecognitionException {
|
||||
FileContext _localctx = new FileContext(_ctx, getState());
|
||||
enterRule(_localctx, 0, RULE_file);
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(16);
|
||||
lineSeq();
|
||||
setState(17);
|
||||
match(EOF);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class LineSeqContext extends ParserRuleContext {
|
||||
public List<LineContext> line() {
|
||||
return getRuleContexts(LineContext.class);
|
||||
}
|
||||
public LineContext line(int i) {
|
||||
return getRuleContext(LineContext.class,i);
|
||||
}
|
||||
public LineSeqContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_lineSeq; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterLineSeq(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitLineSeq(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitLineSeq(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final LineSeqContext lineSeq() throws RecognitionException {
|
||||
LineSeqContext _localctx = new LineSeqContext(_ctx, getState());
|
||||
enterRule(_localctx, 2, RULE_lineSeq);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(20);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
do {
|
||||
{
|
||||
{
|
||||
setState(19);
|
||||
line();
|
||||
}
|
||||
}
|
||||
setState(22);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << T__2) | (1L << MNEMONIC) | (1L << NAME))) != 0) );
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class LineContext extends ParserRuleContext {
|
||||
public LabelContext label() {
|
||||
return getRuleContext(LabelContext.class,0);
|
||||
}
|
||||
public InstructionContext instruction() {
|
||||
return getRuleContext(InstructionContext.class,0);
|
||||
}
|
||||
public CommentContext comment() {
|
||||
return getRuleContext(CommentContext.class,0);
|
||||
}
|
||||
public LineContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_line; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterLine(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitLine(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitLine(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final LineContext line() throws RecognitionException {
|
||||
LineContext _localctx = new LineContext(_ctx, getState());
|
||||
enterRule(_localctx, 4, RULE_line);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(25);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==NAME) {
|
||||
{
|
||||
setState(24);
|
||||
label();
|
||||
}
|
||||
}
|
||||
|
||||
setState(28);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==MNEMONIC) {
|
||||
{
|
||||
setState(27);
|
||||
instruction();
|
||||
}
|
||||
}
|
||||
|
||||
setState(31);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==T__2) {
|
||||
{
|
||||
setState(30);
|
||||
comment();
|
||||
}
|
||||
}
|
||||
|
||||
setState(33);
|
||||
match(T__0);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class LabelContext extends ParserRuleContext {
|
||||
public TerminalNode NAME() { return getToken(Asm6502Parser.NAME, 0); }
|
||||
public LabelContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_label; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterLabel(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitLabel(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitLabel(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final LabelContext label() throws RecognitionException {
|
||||
LabelContext _localctx = new LabelContext(_ctx, getState());
|
||||
enterRule(_localctx, 6, RULE_label);
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(35);
|
||||
match(NAME);
|
||||
setState(36);
|
||||
match(T__1);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class CommentContext extends ParserRuleContext {
|
||||
public CommentContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_comment; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterComment(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitComment(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitComment(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final CommentContext comment() throws RecognitionException {
|
||||
CommentContext _localctx = new CommentContext(_ctx, getState());
|
||||
enterRule(_localctx, 8, RULE_comment);
|
||||
try {
|
||||
int _alt;
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(38);
|
||||
match(T__2);
|
||||
setState(42);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,4,_ctx);
|
||||
while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
if ( _alt==1+1 ) {
|
||||
{
|
||||
{
|
||||
setState(39);
|
||||
matchWildcard();
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(44);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,4,_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class InstructionContext extends ParserRuleContext {
|
||||
public TerminalNode MNEMONIC() { return getToken(Asm6502Parser.MNEMONIC, 0); }
|
||||
public ParamModeContext paramMode() {
|
||||
return getRuleContext(ParamModeContext.class,0);
|
||||
}
|
||||
public InstructionContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_instruction; }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterInstruction(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitInstruction(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitInstruction(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final InstructionContext instruction() throws RecognitionException {
|
||||
InstructionContext _localctx = new InstructionContext(_ctx, getState());
|
||||
enterRule(_localctx, 10, RULE_instruction);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(45);
|
||||
match(MNEMONIC);
|
||||
setState(47);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (1L << T__6) | (1L << T__8) | (1L << NUMINT) | (1L << NAME))) != 0)) {
|
||||
{
|
||||
setState(46);
|
||||
paramMode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class ParamModeContext extends ParserRuleContext {
|
||||
public ParamModeContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_paramMode; }
|
||||
|
||||
public ParamModeContext() { }
|
||||
public void copyFrom(ParamModeContext ctx) {
|
||||
super.copyFrom(ctx);
|
||||
}
|
||||
}
|
||||
public static class ModeIndXContext extends ParamModeContext {
|
||||
public ParamContext param() {
|
||||
return getRuleContext(ParamContext.class,0);
|
||||
}
|
||||
public ModeIndXContext(ParamModeContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterModeIndX(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitModeIndX(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitModeIndX(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ModeImmContext extends ParamModeContext {
|
||||
public ParamContext param() {
|
||||
return getRuleContext(ParamContext.class,0);
|
||||
}
|
||||
public ModeImmContext(ParamModeContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterModeImm(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitModeImm(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitModeImm(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ModeIndYContext extends ParamModeContext {
|
||||
public ParamContext param() {
|
||||
return getRuleContext(ParamContext.class,0);
|
||||
}
|
||||
public ModeIndYContext(ParamModeContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterModeIndY(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitModeIndY(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitModeIndY(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ModeAbsYContext extends ParamModeContext {
|
||||
public ParamContext param() {
|
||||
return getRuleContext(ParamContext.class,0);
|
||||
}
|
||||
public ModeAbsYContext(ParamModeContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterModeAbsY(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitModeAbsY(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitModeAbsY(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ModeIndContext extends ParamModeContext {
|
||||
public ParamContext param() {
|
||||
return getRuleContext(ParamContext.class,0);
|
||||
}
|
||||
public ModeIndContext(ParamModeContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterModeInd(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitModeInd(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitModeInd(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ModeAbsContext extends ParamModeContext {
|
||||
public ParamContext param() {
|
||||
return getRuleContext(ParamContext.class,0);
|
||||
}
|
||||
public ModeAbsContext(ParamModeContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterModeAbs(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitModeAbs(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitModeAbs(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ModeAbsXContext extends ParamModeContext {
|
||||
public ParamContext param() {
|
||||
return getRuleContext(ParamContext.class,0);
|
||||
}
|
||||
public ModeAbsXContext(ParamModeContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterModeAbsX(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitModeAbsX(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitModeAbsX(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final ParamModeContext paramMode() throws RecognitionException {
|
||||
ParamModeContext _localctx = new ParamModeContext(_ctx, getState());
|
||||
enterRule(_localctx, 12, RULE_paramMode);
|
||||
try {
|
||||
setState(72);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
|
||||
case 1:
|
||||
_localctx = new ModeAbsContext(_localctx);
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(49);
|
||||
param();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_localctx = new ModeImmContext(_localctx);
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(50);
|
||||
match(T__3);
|
||||
setState(51);
|
||||
param();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
_localctx = new ModeAbsXContext(_localctx);
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(52);
|
||||
param();
|
||||
setState(53);
|
||||
match(T__4);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
_localctx = new ModeAbsYContext(_localctx);
|
||||
enterOuterAlt(_localctx, 4);
|
||||
{
|
||||
setState(55);
|
||||
param();
|
||||
setState(56);
|
||||
match(T__5);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
_localctx = new ModeIndYContext(_localctx);
|
||||
enterOuterAlt(_localctx, 5);
|
||||
{
|
||||
setState(58);
|
||||
match(T__6);
|
||||
setState(59);
|
||||
param();
|
||||
setState(60);
|
||||
match(T__7);
|
||||
setState(61);
|
||||
match(T__5);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
_localctx = new ModeIndXContext(_localctx);
|
||||
enterOuterAlt(_localctx, 6);
|
||||
{
|
||||
setState(63);
|
||||
match(T__6);
|
||||
setState(64);
|
||||
param();
|
||||
setState(65);
|
||||
match(T__4);
|
||||
setState(66);
|
||||
match(T__7);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
_localctx = new ModeIndContext(_localctx);
|
||||
enterOuterAlt(_localctx, 7);
|
||||
{
|
||||
setState(68);
|
||||
match(T__6);
|
||||
setState(69);
|
||||
param();
|
||||
setState(70);
|
||||
match(T__7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class ParamContext extends ParserRuleContext {
|
||||
public ParamContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_param; }
|
||||
|
||||
public ParamContext() { }
|
||||
public void copyFrom(ParamContext ctx) {
|
||||
super.copyFrom(ctx);
|
||||
}
|
||||
}
|
||||
public static class ParamReplaceContext extends ParamContext {
|
||||
public TerminalNode NAME() { return getToken(Asm6502Parser.NAME, 0); }
|
||||
public ParamReplaceContext(ParamContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterParamReplace(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitParamReplace(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitParamReplace(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ParamIntContext extends ParamContext {
|
||||
public TerminalNode NUMINT() { return getToken(Asm6502Parser.NUMINT, 0); }
|
||||
public ParamIntContext(ParamContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterParamInt(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitParamInt(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitParamInt(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ParamLabelContext extends ParamContext {
|
||||
public TerminalNode NAME() { return getToken(Asm6502Parser.NAME, 0); }
|
||||
public ParamLabelContext(ParamContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public void enterRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).enterParamLabel(this);
|
||||
}
|
||||
@Override
|
||||
public void exitRule(ParseTreeListener listener) {
|
||||
if ( listener instanceof Asm6502Listener ) ((Asm6502Listener)listener).exitParamLabel(this);
|
||||
}
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof Asm6502Visitor ) return ((Asm6502Visitor<? extends T>)visitor).visitParamLabel(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final ParamContext param() throws RecognitionException {
|
||||
ParamContext _localctx = new ParamContext(_ctx, getState());
|
||||
enterRule(_localctx, 14, RULE_param);
|
||||
try {
|
||||
setState(79);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case NAME:
|
||||
_localctx = new ParamLabelContext(_localctx);
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(74);
|
||||
match(NAME);
|
||||
}
|
||||
break;
|
||||
case T__8:
|
||||
_localctx = new ParamReplaceContext(_localctx);
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(75);
|
||||
match(T__8);
|
||||
setState(76);
|
||||
match(NAME);
|
||||
setState(77);
|
||||
match(T__9);
|
||||
}
|
||||
break;
|
||||
case NUMINT:
|
||||
_localctx = new ParamIntContext(_localctx);
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(78);
|
||||
match(NUMINT);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\23T\4\2\t\2\4\3\t"+
|
||||
"\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\3\2\3\2\3\2\3\3\6\3"+
|
||||
"\27\n\3\r\3\16\3\30\3\4\5\4\34\n\4\3\4\5\4\37\n\4\3\4\5\4\"\n\4\3\4\3"+
|
||||
"\4\3\5\3\5\3\5\3\6\3\6\7\6+\n\6\f\6\16\6.\13\6\3\7\3\7\5\7\62\n\7\3\b"+
|
||||
"\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3"+
|
||||
"\b\3\b\3\b\3\b\3\b\5\bK\n\b\3\t\3\t\3\t\3\t\3\t\5\tR\n\t\3\t\3,\2\n\2"+
|
||||
"\4\6\b\n\f\16\20\2\2\2Y\2\22\3\2\2\2\4\26\3\2\2\2\6\33\3\2\2\2\b%\3\2"+
|
||||
"\2\2\n(\3\2\2\2\f/\3\2\2\2\16J\3\2\2\2\20Q\3\2\2\2\22\23\5\4\3\2\23\24"+
|
||||
"\7\2\2\3\24\3\3\2\2\2\25\27\5\6\4\2\26\25\3\2\2\2\27\30\3\2\2\2\30\26"+
|
||||
"\3\2\2\2\30\31\3\2\2\2\31\5\3\2\2\2\32\34\5\b\5\2\33\32\3\2\2\2\33\34"+
|
||||
"\3\2\2\2\34\36\3\2\2\2\35\37\5\f\7\2\36\35\3\2\2\2\36\37\3\2\2\2\37!\3"+
|
||||
"\2\2\2 \"\5\n\6\2! \3\2\2\2!\"\3\2\2\2\"#\3\2\2\2#$\7\3\2\2$\7\3\2\2\2"+
|
||||
"%&\7\22\2\2&\'\7\4\2\2\'\t\3\2\2\2(,\7\5\2\2)+\13\2\2\2*)\3\2\2\2+.\3"+
|
||||
"\2\2\2,-\3\2\2\2,*\3\2\2\2-\13\3\2\2\2.,\3\2\2\2/\61\7\r\2\2\60\62\5\16"+
|
||||
"\b\2\61\60\3\2\2\2\61\62\3\2\2\2\62\r\3\2\2\2\63K\5\20\t\2\64\65\7\6\2"+
|
||||
"\2\65K\5\20\t\2\66\67\5\20\t\2\678\7\7\2\28K\3\2\2\29:\5\20\t\2:;\7\b"+
|
||||
"\2\2;K\3\2\2\2<=\7\t\2\2=>\5\20\t\2>?\7\n\2\2?@\7\b\2\2@K\3\2\2\2AB\7"+
|
||||
"\t\2\2BC\5\20\t\2CD\7\7\2\2DE\7\n\2\2EK\3\2\2\2FG\7\t\2\2GH\5\20\t\2H"+
|
||||
"I\7\n\2\2IK\3\2\2\2J\63\3\2\2\2J\64\3\2\2\2J\66\3\2\2\2J9\3\2\2\2J<\3"+
|
||||
"\2\2\2JA\3\2\2\2JF\3\2\2\2K\17\3\2\2\2LR\7\22\2\2MN\7\13\2\2NO\7\22\2"+
|
||||
"\2OR\7\f\2\2PR\7\16\2\2QL\3\2\2\2QM\3\2\2\2QP\3\2\2\2R\21\3\2\2\2\n\30"+
|
||||
"\33\36!,\61JQ";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
119
src/dk/camelot64/kickc/asm/parser/Asm6502Visitor.java
Normal file
119
src/dk/camelot64/kickc/asm/parser/Asm6502Visitor.java
Normal file
@ -0,0 +1,119 @@
|
||||
// Generated from /Users/jespergravgaard/c64/src/kickc/src/dk/camelot64/kickc/asm/parser/Asm6502.g4 by ANTLR 4.7
|
||||
package dk.camelot64.kickc.asm.parser;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This interface defines a complete generic visitor for a parse tree produced
|
||||
* by {@link Asm6502Parser}.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
public interface Asm6502Visitor<T> extends ParseTreeVisitor<T> {
|
||||
/**
|
||||
* Visit a parse tree produced by {@link Asm6502Parser#file}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitFile(Asm6502Parser.FileContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link Asm6502Parser#lineSeq}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitLineSeq(Asm6502Parser.LineSeqContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link Asm6502Parser#line}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitLine(Asm6502Parser.LineContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link Asm6502Parser#label}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitLabel(Asm6502Parser.LabelContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link Asm6502Parser#comment}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitComment(Asm6502Parser.CommentContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link Asm6502Parser#instruction}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitInstruction(Asm6502Parser.InstructionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code modeAbs}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitModeAbs(Asm6502Parser.ModeAbsContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code modeImm}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitModeImm(Asm6502Parser.ModeImmContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code modeAbsX}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitModeAbsX(Asm6502Parser.ModeAbsXContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code modeAbsY}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitModeAbsY(Asm6502Parser.ModeAbsYContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code modeIndY}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitModeIndY(Asm6502Parser.ModeIndYContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code modeIndX}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitModeIndX(Asm6502Parser.ModeIndXContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code modeInd}
|
||||
* labeled alternative in {@link Asm6502Parser#paramMode}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitModeInd(Asm6502Parser.ModeIndContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code paramLabel}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParamLabel(Asm6502Parser.ParamLabelContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code paramReplace}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParamReplace(Asm6502Parser.ParamReplaceContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code paramInt}
|
||||
* labeled alternative in {@link Asm6502Parser#param}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParamInt(Asm6502Parser.ParamIntContext ctx);
|
||||
}
|
@ -22,10 +22,10 @@ public class Pass3RegisterAllocation {
|
||||
allocation.allocate(var, new RegisterAllocation.RegisterZpBool(currentZp++));
|
||||
}
|
||||
}
|
||||
allocation.allocate(symbols.getVariable("i#1"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(symbols.getVariable("i#3"), RegisterAllocation.getRegisterX());
|
||||
allocation.allocate(symbols.getVariable("n1#1"), new RegisterAllocation.RegisterZpByte(8));
|
||||
allocation.allocate(symbols.getVariable("n1#2"), new RegisterAllocation.RegisterZpByte(8));
|
||||
// allocation.allocate(symbols.getVariable("i#1"), RegisterAllocation.getRegisterX());
|
||||
// allocation.allocate(symbols.getVariable("i#3"), RegisterAllocation.getRegisterX());
|
||||
// allocation.allocate(symbols.getVariable("n1#1"), new RegisterAllocation.RegisterZpByte(8));
|
||||
// allocation.allocate(symbols.getVariable("n1#2"), new RegisterAllocation.RegisterZpByte(8));
|
||||
symbols.setAllocation(allocation);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.asm.AsmFragment;
|
||||
import dk.camelot64.kickc.asm.AsmSequence;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -27,12 +30,10 @@ public class Pass4CodeGeneration {
|
||||
// Generate exit
|
||||
ControlFlowBlock defaultSuccessor = block.getDefaultSuccessor();
|
||||
if (defaultSuccessor != null) {
|
||||
if (defaultSuccessor.getPredecessors().size() > 1) {
|
||||
String label = defaultSuccessor.getLabel().getName() + "_from_" + block.getLabel().getName();
|
||||
genAsmJump(asm, label);
|
||||
} else {
|
||||
genAsmJump(asm, defaultSuccessor.getLabel().getName());
|
||||
if(defaultSuccessor.getStatements().size()>0 && defaultSuccessor.getStatements().get(0) instanceof StatementPhi) {
|
||||
genBlockPhiTransition(asm, block, defaultSuccessor);
|
||||
}
|
||||
genAsmJump(asm, defaultSuccessor.getLabel().getName());
|
||||
}
|
||||
}
|
||||
return asm;
|
||||
@ -64,30 +65,45 @@ public class Pass4CodeGeneration {
|
||||
List<Statement> statements = block.getStatements();
|
||||
if (statements.size() > 0 && (statements.get(0) instanceof StatementPhi)) {
|
||||
for (ControlFlowBlock predecessor : block.getPredecessors()) {
|
||||
genBlockEntryPoint(asm, block, predecessor);
|
||||
if(block.equals(predecessor.getConditionalSuccessor())) {
|
||||
genBlockPhiTransition(asm, predecessor, block);
|
||||
genAsmJump(asm, block.getLabel().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void genBlockEntryPoint(AsmSequence asm, ControlFlowBlock block, ControlFlowBlock predecessor) {
|
||||
genAsmLabel(asm, block.getLabel().getName() + "_from_" + predecessor.getLabel().getName());
|
||||
for (Statement statement : block.getStatements()) {
|
||||
private void genBlockPhiTransition(AsmSequence asm, ControlFlowBlock fromBlock, ControlFlowBlock toBlock) {
|
||||
genAsmLabel(asm, toBlock.getLabel().getName() + "_from_" + fromBlock.getLabel().getName());
|
||||
for (Statement statement : toBlock.getStatements()) {
|
||||
if (!(statement instanceof StatementPhi)) {
|
||||
// No more phi statements to handle
|
||||
break;
|
||||
}
|
||||
StatementPhi phi = (StatementPhi) statement;
|
||||
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
|
||||
if (previousSymbol.getBlock().equals(predecessor)) {
|
||||
if (previousSymbol.getBlock().equals(fromBlock)) {
|
||||
genAsmMove(asm, phi.getLValue(), previousSymbol.getRValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
genAsmJump(asm, block.getLabel().getName());
|
||||
}
|
||||
|
||||
private RegisterAllocation.Register getRegister(RValue rValue) {
|
||||
if(rValue instanceof Variable) {
|
||||
return symbols.getRegister((Variable) rValue);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void genAsmMove(AsmSequence asm, LValue lValue, RValue rValue) {
|
||||
if(getRegister(lValue).equals(getRegister(rValue))) {
|
||||
// Do not move from register to itself
|
||||
asm.addAsm(" // " + lValue + " = " + rValue + " // register copy " );
|
||||
return;
|
||||
}
|
||||
AsmFragment asmFragment = new AsmFragment(lValue, rValue, symbols);
|
||||
asm.addAsm(" // " + lValue + " = " + rValue + " // " + asmFragment.getSignature());
|
||||
asmFragment.generateAsm(asm);
|
||||
|
@ -61,6 +61,21 @@ public class RegisterAllocation {
|
||||
public String toString() {
|
||||
return "zp byte:"+zp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
RegisterZpByte that = (RegisterZpByte) o;
|
||||
|
||||
return zp == that.zp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return zp;
|
||||
}
|
||||
}
|
||||
|
||||
/** A zero page address used as a register for a boolean variable. */
|
||||
@ -84,6 +99,21 @@ public class RegisterAllocation {
|
||||
public String toString() {
|
||||
return "zp bool:"+zp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
RegisterZpBool that = (RegisterZpBool) o;
|
||||
|
||||
return zp == that.zp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return zp;
|
||||
}
|
||||
}
|
||||
|
||||
/** The X register. */
|
||||
@ -97,6 +127,13 @@ public class RegisterAllocation {
|
||||
public String toString() {
|
||||
return "reg byte x";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static Register getRegisterX() {
|
||||
|
@ -1 +0,0 @@
|
||||
ldx #{coby1}
|
@ -1 +0,0 @@
|
||||
dex
|
@ -1,2 +0,0 @@
|
||||
cpx #0
|
||||
bne {la1}
|
@ -1,8 +0,0 @@
|
||||
lda {zpby1}
|
||||
cmp #{coby1}
|
||||
beq !f+
|
||||
bcs !t+
|
||||
!f: lda #0
|
||||
jmp !d+
|
||||
!t: lda #$ff
|
||||
!d: sta {zpbo1}
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.test;
|
||||
|
||||
import dk.camelot64.kickc.icl.*;
|
||||
import dk.camelot64.kickc.asm.AsmSequence;
|
||||
import dk.camelot64.kickc.parser.KickCLexer;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
|
Loading…
Reference in New Issue
Block a user