mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-20 00:29:10 +00:00
Refactored directive parsing slightly.
This commit is contained in:
parent
90b2077ac5
commit
8f274f18a6
@ -101,7 +101,9 @@ directive
|
||||
| ALIGN PAR_BEGIN NUMBER PAR_END #directiveAlign
|
||||
| REGISTER ( PAR_BEGIN ( NAME ) PAR_END)? #directiveRegister
|
||||
| NOTREGISTER #directiveNotRegister
|
||||
| ADDRESS_ZEROPAGE | ADDRESS_MAINMEM | ( ADDRESS PAR_BEGIN ( NUMBER ) PAR_END) #directiveMemoryArea
|
||||
| ADDRESS_ZEROPAGE #directiveMemoryAreaZp
|
||||
| ADDRESS_MAINMEM #directiveMemoryAreaMain
|
||||
| ADDRESS PAR_BEGIN ( NUMBER ) PAR_END #directiveMemoryAreaAddress
|
||||
| INLINE #directiveInline
|
||||
| VOLATILE #directiveVolatile
|
||||
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -390,13 +390,37 @@ public class KickCParserBaseListener implements KickCParserListener {
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) { }
|
||||
@Override public void enterDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) { }
|
||||
@Override public void exitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -236,7 +236,21 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -358,17 +358,41 @@ public interface KickCParserListener extends ParseTreeListener {
|
||||
*/
|
||||
void exitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code directiveMemoryArea}
|
||||
* Enter a parse tree produced by the {@code directiveMemoryAreaZp}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx);
|
||||
void enterDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code directiveMemoryArea}
|
||||
* Exit a parse tree produced by the {@code directiveMemoryAreaZp}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx);
|
||||
void exitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code directiveMemoryAreaMain}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code directiveMemoryAreaMain}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code directiveMemoryAreaAddress}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code directiveMemoryAreaAddress}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code directiveInline}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
|
@ -218,12 +218,26 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
|
||||
*/
|
||||
T visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code directiveMemoryArea}
|
||||
* Visit a parse tree produced by the {@code directiveMemoryAreaZp}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx);
|
||||
T visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code directiveMemoryAreaMain}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code directiveMemoryAreaAddress}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code directiveInline}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
|
@ -162,7 +162,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
/** The current calling convention for procedures. */
|
||||
Procedure.CallingConvension currentCallingConvention = Procedure.CallingConvension.PHI_CALL;
|
||||
private Procedure.CallingConvension currentCallingConvention = Procedure.CallingConvension.PHI_CALL;
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx) {
|
||||
@ -174,7 +174,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
/** The current code segment - if null the default segment is used. */
|
||||
String currentCodeSegment = Scope.SEGMENT_CODE_DEFAULT;
|
||||
private String currentCodeSegment = Scope.SEGMENT_CODE_DEFAULT;
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) {
|
||||
@ -183,7 +183,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
/** The current data segment - if null the default segment is used. */
|
||||
String currentDataSegment = Scope.SEGMENT_DATA_DEFAULT;
|
||||
private String currentDataSegment = Scope.SEGMENT_DATA_DEFAULT;
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) {
|
||||
@ -469,7 +469,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
/** ASM Directive specifying clobber registers. */
|
||||
private class AsmDirectiveClobber implements AsmDirective {
|
||||
private static class AsmDirectiveClobber implements AsmDirective {
|
||||
private AsmClobber clobber;
|
||||
|
||||
AsmDirectiveClobber(AsmClobber clobber) {
|
||||
@ -519,8 +519,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
@Override
|
||||
public Object visitDeclTypes(KickCParser.DeclTypesContext ctx) {
|
||||
List<KickCParser.DirectiveContext> directive = ctx.directive();
|
||||
SymbolType varType = (SymbolType) visit(ctx.typeDecl());
|
||||
this.declVarType = varType;
|
||||
this.declVarType = (SymbolType) visit(ctx.typeDecl());
|
||||
this.declVarDirectives = getDirectives(directive);
|
||||
this.declVarComments = getCommentsSymbol(ctx.getParent());
|
||||
return null;
|
||||
@ -712,21 +711,22 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
lValue.setDeclaredMemoryAddress(directiveMemoryArea.address);
|
||||
}
|
||||
}
|
||||
} else if(directive instanceof DirectiveNotRegister) {
|
||||
lValue.setDeclaredNotRegister(true);
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.LOAD_STORE);
|
||||
//lValue.setMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY);
|
||||
} else if(directive instanceof DirectiveRegister) {
|
||||
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
||||
lValue.setDeclaredAsRegister(true);
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_MASTER);
|
||||
if(directiveRegister.name != null) {
|
||||
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
|
||||
Registers.Register register = Registers.getRegister(directiveRegister.name);
|
||||
if(register == null) {
|
||||
throw new CompileError("Error! Unknown register " + directiveRegister.name, source);
|
||||
if(directiveRegister.isRegister) {
|
||||
lValue.setDeclaredAsRegister(true);
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_MASTER);
|
||||
if(directiveRegister.name != null) {
|
||||
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
|
||||
Registers.Register register = Registers.getRegister(directiveRegister.name);
|
||||
if(register == null) {
|
||||
throw new CompileError("Error! Unknown register " + directiveRegister.name, source);
|
||||
}
|
||||
lValue.setDeclaredRegister(register);
|
||||
}
|
||||
lValue.setDeclaredRegister(register);
|
||||
} else {
|
||||
lValue.setDeclaredNotRegister(true);
|
||||
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.LOAD_STORE);
|
||||
}
|
||||
} else {
|
||||
throw new CompileError("Unsupported variable directive " + directive, source);
|
||||
@ -829,34 +829,34 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
if(ctx.NAME() != null) {
|
||||
name = ctx.NAME().getText();
|
||||
}
|
||||
return new DirectiveRegister(name);
|
||||
return new DirectiveRegister(true, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDirectiveNotRegister(KickCParser.DirectiveNotRegisterContext ctx) {
|
||||
return new DirectiveNotRegister();
|
||||
return new DirectiveRegister(false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDirectiveMemoryArea(KickCParser.DirectiveMemoryAreaContext ctx) {
|
||||
if(ctx.ADDRESS_ZEROPAGE()!=null) {
|
||||
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
} else if(ctx.ADDRESS_MAINMEM()!=null) {
|
||||
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
} else if(ctx.ADDRESS()!=null && ctx.NUMBER()!=null) {
|
||||
Long address = null;
|
||||
if(ctx.NUMBER() != null) {
|
||||
try {
|
||||
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
|
||||
address = memoryAddress.getInteger();
|
||||
SymbolVariable.MemoryArea memoryArea = (address<0x100)? SymbolVariable.MemoryArea.ZEROPAGE_MEMORY : SymbolVariable.MemoryArea.MAIN_MEMORY;
|
||||
return new DirectiveMemoryArea(memoryArea, address);
|
||||
} catch(NumberFormatException e) {
|
||||
throw new CompileError(e.getMessage(), new StatementSource(ctx));
|
||||
}
|
||||
}
|
||||
public Object visitDirectiveMemoryAreaZp(KickCParser.DirectiveMemoryAreaZpContext ctx) {
|
||||
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDirectiveMemoryAreaMain(KickCParser.DirectiveMemoryAreaMainContext ctx) {
|
||||
return new DirectiveMemoryArea(SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDirectiveMemoryAreaAddress(KickCParser.DirectiveMemoryAreaAddressContext ctx) {
|
||||
try {
|
||||
ConstantInteger memoryAddress = NumberParser.parseIntegerLiteral(ctx.NUMBER().getText());
|
||||
Long address = memoryAddress.getInteger();
|
||||
SymbolVariable.MemoryArea memoryArea = (address<0x100)? SymbolVariable.MemoryArea.ZEROPAGE_MEMORY : SymbolVariable.MemoryArea.MAIN_MEMORY;
|
||||
return new DirectiveMemoryArea(memoryArea, address);
|
||||
} catch(NumberFormatException e) {
|
||||
throw new CompileError(e.getMessage(), new StatementSource(ctx));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1655,19 +1655,19 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
* statement can make sure to output any rValue that has not been output.
|
||||
* Null if we are not currently monitoring this.
|
||||
*/
|
||||
public Set<RValue> exprNotConsumed = null;
|
||||
private Set<RValue> exprNotConsumed = null;
|
||||
|
||||
/**
|
||||
* Begins monitoring list of expressions not consumed.
|
||||
*/
|
||||
void beginNotConsumedTracking() {
|
||||
private void beginNotConsumedTracking() {
|
||||
exprNotConsumed = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends monitoring list of expressions not consumed.
|
||||
*/
|
||||
void endNotConsumedTracking() {
|
||||
private void endNotConsumedTracking() {
|
||||
exprNotConsumed = null;
|
||||
}
|
||||
|
||||
@ -1677,7 +1677,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
*
|
||||
* @param rValue The RValue being consume
|
||||
*/
|
||||
void consumeExpr(RValue rValue) {
|
||||
private void consumeExpr(RValue rValue) {
|
||||
if(exprNotConsumed != null)
|
||||
exprNotConsumed.remove(rValue);
|
||||
}
|
||||
@ -1688,7 +1688,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
*
|
||||
* @param rValue The RValue that has been produced but not consumed
|
||||
*/
|
||||
void addExprToConsume(RValue rValue) {
|
||||
private void addExprToConsume(RValue rValue) {
|
||||
if(exprNotConsumed != null)
|
||||
exprNotConsumed.add(rValue);
|
||||
}
|
||||
@ -1698,7 +1698,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
*
|
||||
* @return true if the RValue is in the list
|
||||
*/
|
||||
boolean notConsumed(RValue rValue) {
|
||||
private boolean notConsumed(RValue rValue) {
|
||||
return exprNotConsumed.contains(rValue);
|
||||
}
|
||||
|
||||
@ -2146,7 +2146,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
/** Set containing the token index of all comment blocks that have already been used. */
|
||||
HashSet<Integer> usedCommentTokenIndices = new HashSet<>();
|
||||
private HashSet<Integer> usedCommentTokenIndices = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Ensures that the comments have not already been "used" in another context.
|
||||
@ -2209,9 +2209,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
/** Function with specific declared calling convention. */
|
||||
private static class DirectiveCallingConvention implements Directive {
|
||||
Procedure.CallingConvension callingConvension;
|
||||
private Procedure.CallingConvension callingConvension;
|
||||
|
||||
public DirectiveCallingConvention(Procedure.CallingConvension callingConvension) {
|
||||
DirectiveCallingConvention(Procedure.CallingConvension callingConvension) {
|
||||
this.callingConvension = callingConvension;
|
||||
}
|
||||
|
||||
@ -2231,9 +2231,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
/** Function declared interrupt. */
|
||||
private static class DirectiveInterrupt implements Directive {
|
||||
public Procedure.InterruptType interruptType;
|
||||
Procedure.InterruptType interruptType;
|
||||
|
||||
public DirectiveInterrupt(Procedure.InterruptType interruptType) {
|
||||
DirectiveInterrupt(Procedure.InterruptType interruptType) {
|
||||
this.interruptType = interruptType;
|
||||
}
|
||||
}
|
||||
@ -2243,32 +2243,28 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
private int alignment;
|
||||
|
||||
public DirectiveAlign(int alignment) {
|
||||
private DirectiveAlign(int alignment) {
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Variable register allocation. */
|
||||
/** Variable register or __notregister directive . */
|
||||
private static class DirectiveRegister implements Directive {
|
||||
|
||||
/** Name of register to use for the variable */
|
||||
/** true if the directive is a register directive. false if it is a notregister directive. */
|
||||
private boolean isRegister;
|
||||
|
||||
/** Name of register to use for the variable (if named) */
|
||||
private String name;
|
||||
|
||||
public DirectiveRegister(String name) {
|
||||
DirectiveRegister(boolean isRegister, String name) {
|
||||
this.isRegister = isRegister;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Variable not regsiter declaration. */
|
||||
private static class DirectiveNotRegister implements Directive {
|
||||
|
||||
public DirectiveNotRegister() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Variable memory area declaration. */
|
||||
private static class DirectiveMemoryArea implements Directive {
|
||||
|
||||
@ -2278,7 +2274,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
/** Optional hard-coded address to use for storing the variable. */
|
||||
private Long address;
|
||||
|
||||
public DirectiveMemoryArea(SymbolVariable.MemoryArea memoryArea, Long address) {
|
||||
DirectiveMemoryArea(SymbolVariable.MemoryArea memoryArea, Long address) {
|
||||
this.memoryArea = memoryArea;
|
||||
this.address = address;
|
||||
}
|
||||
@ -2290,7 +2286,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
private static class DirectiveReserveZp implements Directive {
|
||||
List<Integer> reservedZp;
|
||||
|
||||
public DirectiveReserveZp(List<Integer> reservedZp) {
|
||||
DirectiveReserveZp(List<Integer> reservedZp) {
|
||||
this.reservedZp = reservedZp;
|
||||
}
|
||||
|
||||
@ -2303,20 +2299,20 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
private List<PrePostModifier> preMods;
|
||||
private Pass0GenerateStatementSequence mainParser;
|
||||
|
||||
public PrePostModifierHandler(Pass0GenerateStatementSequence mainParser) {
|
||||
PrePostModifierHandler(Pass0GenerateStatementSequence mainParser) {
|
||||
this.mainParser = mainParser;
|
||||
preMods = new ArrayList<>();
|
||||
postMods = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static void addPostModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
|
||||
static void addPostModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
|
||||
PrePostModifierHandler prePostModifierHandler = new PrePostModifierHandler(parser);
|
||||
prePostModifierHandler.visit(ctx);
|
||||
List<PrePostModifier> modifiers = prePostModifierHandler.getPostMods();
|
||||
addModifierStatements(parser, modifiers, statementSource);
|
||||
}
|
||||
|
||||
public static void addPreModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
|
||||
static void addPreModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx, StatementSource statementSource) {
|
||||
PrePostModifierHandler modifierHandler = new PrePostModifierHandler(parser);
|
||||
modifierHandler.visit(ctx);
|
||||
List<PrePostModifier> modifiers = modifierHandler.getPreMods();
|
||||
|
@ -2718,11 +2718,6 @@ public class TestPrograms {
|
||||
compileAndCompare("var-register-zp");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVarRegisterZp2() throws IOException, URISyntaxException {
|
||||
assertError("var-register-zp-2", "Error! Address not on zeropage");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVarRegisterZp3() throws IOException, URISyntaxException {
|
||||
compileAndCompare("var-register-zp-3");
|
||||
|
@ -1,7 +0,0 @@
|
||||
// Test declaring a variable as register on a specific ZP address
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
main: {
|
||||
rts
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return
|
||||
to:@return
|
@ -1,203 +0,0 @@
|
||||
Identified constant variable (signed word*) SCREEN
|
||||
Identified constant variable (byte) main::i
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Culled Empty Block (label) @2
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
[4] phi()
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
// File Comments
|
||||
// Test declaring a variable as register on a specific ZP address
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [5] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 48 combination
|
||||
Uplifting [] best 48 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Test declaring a variable as register on a specific ZP address
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__b1:
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
main_from___b1:
|
||||
jsr main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [5] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __bend
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label __bbegin with __b1
|
||||
Removing instruction __bbegin:
|
||||
Removing instruction __b1_from___bbegin:
|
||||
Removing instruction main_from___b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __bend:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction __b1:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 6
|
||||
|
||||
// File Comments
|
||||
// Test declaring a variable as register on a specific ZP address
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
// @begin
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
// @1
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// main
|
||||
main: {
|
||||
// main::@return
|
||||
// }
|
||||
// [5] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -1,6 +0,0 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
Loading…
x
Reference in New Issue
Block a user