1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-26 18:29:54 +00:00

Working towards typedef with const/volatile directive handling and typedef arrays by introducing a varDecl stack in the parser. #375 #376 #377

This commit is contained in:
jespergravgaard 2020-03-30 00:12:03 +02:00
parent db6f8b5a36
commit 5a8654b0e7
7 changed files with 138 additions and 81 deletions

View File

@ -545,13 +545,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** The declared type (variable level) */
private VariableDeclType varDeclType;
public VariableDeclaration() {
this.declType = new VariableDeclType();
}
/**
* Exits the type layer (clears everything except struct information)
*/
void exitType() {
this.declDirectives = null;
this.declComments = null;
this.declType = null;
this.declType = new VariableDeclType();
this.varDeclType = null;
}
@ -573,11 +577,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** If the type is SymbolTypePointer this holds the declaration type of the elements. */
VariableDeclType elementDeclType;
public VariableDeclType(SymbolType type) {
this.type = type;
public VariableDeclType() {
this.typeDirectives = new ArrayList<>();
}
public void setType(SymbolType type) {
this.type = type;
}
public SymbolType getType() {
return type;
}
@ -683,7 +690,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
public void setDeclType(SymbolType type) {
this.declType = new VariableDeclType(type);
this.declType.setType(type);
}
public void setVarDeclType(VariableDeclType varDeclType) {
@ -704,8 +711,27 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
/** The current variable declaration. This is not on the stack. */
private VariableDeclaration varDecl = new VariableDeclaration();
/** The stack of variable type / directive declarataions being handled. Pushed/popped when entering into a nested type declaration (eg. struct member or a cast inside an initializer) */
private Deque<VariableDeclaration> varDeclStack = new LinkedList<>();
/**
* Push the current type declaration handler onto the stack and initialize a new empty current type declaration handler.
*/
void varDeclPush() {
varDeclStack.push(varDecl);
varDecl = new VariableDeclaration();
}
/**
* Discard the current type declaration handler and pop the last one fron the stack.
*/
void varDeclPop() {
this.varDecl = varDeclStack.pop();
}
@Override
public Object visitDeclPointer(KickCParser.DeclPointerContext ctx) {
// Detect char * const * x;
@ -714,7 +740,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
//};
// Create a var-level declaration type
final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType();
VariableDeclaration.VariableDeclType pointerDeclType = new VariableDeclaration.VariableDeclType(new SymbolTypePointer(elementDeclType.getType()));
VariableDeclaration.VariableDeclType pointerDeclType = new VariableDeclaration.VariableDeclType();
pointerDeclType.setType(new SymbolTypePointer(elementDeclType.getType()));
pointerDeclType.setElementDeclType(elementDeclType);
final List<Directive> typeDirectives = getDirectives(ctx.directive());
pointerDeclType.setTypeDirectives(typeDirectives);
@ -727,13 +754,16 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
// Handle array type declaration by updating the declared type and the array spec
ArraySpec arraySpec;
if(ctx.expr() != null) {
varDeclPush();
RValue sizeVal = (RValue) visit(ctx.expr());
varDeclPop();
arraySpec = new ArraySpec((ConstantValue) sizeVal);
} else {
arraySpec = new ArraySpec();
}
final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType();
VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType(new SymbolTypePointer(elementDeclType.getType()));
VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType();
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType()));
arrayDeclType.setElementDeclType(elementDeclType);
arrayDeclType.setArraySpec(arraySpec);
varDecl.setVarDeclType(arrayDeclType);
@ -748,10 +778,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
*/
@Override
public Object visitDeclType(KickCParser.DeclTypeContext ctx) {
List<KickCParser.DirectiveContext> directive = ctx.directive();
varDecl.exitType();
varDecl.setDeclType((SymbolType) visit(ctx.type()));
varDecl.setDeclDirectives(getDirectives(directive));
visit(ctx.type());
varDecl.setDeclDirectives(getDirectives(ctx.directive()));
varDecl.setDeclComments(getCommentsSymbol(ctx.getParent()));
return null;
}
@ -787,23 +816,30 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
StatementSource statementSource = new StatementSource(ctx);
StatementSource declSource = new StatementSource((ParserRuleContext) ctx.parent.parent);
try {
if(varDecl.isStructMember() && (initializer != null))
throw new CompileError("Initializer not supported inside structs " + varDecl.getEffectiveType().getTypeName(), statementSource);
final boolean isStructMember = varDecl.isStructMember();
final SymbolType effectiveType = varDecl.getEffectiveType();
final ArraySpec effectiveArraySpec = varDecl.getEffectiveArraySpec();
final List<Directive> effectiveDirectives = varDecl.getEffectiveDirectives();
final List<Comment> declComments = varDecl.getDeclComments();
varDecl.exitVar();
if(isStructMember && (initializer != null))
throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), statementSource);
if(initializer != null)
PrePostModifierHandler.addPreModifiers(this, initializer, statementSource);
RValue initValue = (initializer == null) ? null : (RValue) visit(initializer);
initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec()), program, statementSource);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, variableBuilderConfig);
initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(effectiveType, effectiveArraySpec), program, statementSource);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, effectiveType, effectiveArraySpec, effectiveDirectives, currentDataSegment, variableBuilderConfig);
Variable variable = varBuilder.build();
boolean isPermanent = ScopeRef.ROOT.equals(variable.getScope().getRef()) || variable.isPermanent();
if(variable.isKindConstant() || (isPermanent && variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !varDecl.isStructMember() && variable.getRegister() == null)) {
if(variable.isKindConstant() || (isPermanent && variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !isStructMember && variable.getRegister() == null)) {
// Set initial value
ConstantValue constInitValue = getConstInitValue(initValue, initializer, statementSource);
variable.setInitValue(constInitValue);
// Add comments to constant
variable.setComments(ensureUnusedComments(varDecl.getDeclComments()));
} else if(!variable.isKindConstant() && !varDecl.isStructMember()) {
Statement initStmt = new StatementAssignment(variable.getVariableRef(), initValue, true, statementSource, ensureUnusedComments(varDecl.getDeclComments()));
variable.setComments(ensureUnusedComments(declComments));
} else if(!variable.isKindConstant() && !isStructMember) {
Statement initStmt = new StatementAssignment(variable.getVariableRef(), initValue, true, statementSource, ensureUnusedComments(declComments));
sequence.addStatement(initStmt);
}
if(initializer != null)
@ -811,7 +847,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} catch(CompileError e) {
throw new CompileError(e.getMessage(), declSource);
}
varDecl.exitVar();
return null;
}
@ -1609,11 +1644,12 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
@Override
public SymbolType visitTypeSimple(KickCParser.TypeSimpleContext ctx) {
return SymbolType.get(ctx.getText());
public Object visitTypeSimple(KickCParser.TypeSimpleContext ctx) {
final SymbolType typeSimple = SymbolType.get(ctx.getText());
varDecl.setDeclType(typeSimple);
return null;
}
@Override
public Object visitStructDef(KickCParser.StructDefContext ctx) {
String structDefName;
@ -1624,13 +1660,16 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
StructDefinition structDefinition = program.getScope().addStructDefinition(structDefName);
scopeStack.push(structDefinition);
varDecl.setStructMember(true);
for(KickCParser.StructMembersContext memberCtx : ctx.structMembers()) {
varDeclPush();
varDecl.setStructMember(true);
visit(memberCtx);
}
varDecl.setStructMember(false);
varDeclPop();
}
scopeStack.pop();
return structDefinition.getType();
varDecl.setDeclType(structDefinition.getType());
return null;
}
@Override
@ -1640,12 +1679,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(structDefinition == null) {
throw new CompileError("Unknown struct type " + structDefName, new StatementSource(ctx));
}
return structDefinition.getType();
varDecl.setDeclType(structDefinition.getType());
return null;
}
@Override
public Object visitTypeEnumDef(KickCParser.TypeEnumDefContext ctx) {
return visit(ctx.enumDef());
visit(ctx.enumDef());
return null;
}
private EnumDefinition currentEnum = null;
@ -1672,7 +1713,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
for(Variable member : enumDefinition.getAllConstants(false)) {
parentScope.add(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, null, member.getInitValue(), currentDataSegment));
}
return SymbolType.BYTE;
varDecl.setDeclType(SymbolType.BYTE);
return null;
} catch(CompileError e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx));
}
@ -1710,7 +1752,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Object visitTypeEnumRef(KickCParser.TypeEnumRefContext ctx) {
return visit(ctx.enumRef());
visit(ctx.enumRef());
return null;
}
@Override
@ -1720,27 +1763,31 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(enumDefinition == null) {
throw new CompileError("Unknown enum " + enumDefName, new StatementSource(ctx));
}
return SymbolType.BYTE;
varDecl.setDeclType(SymbolType.BYTE);
return null;
}
@Override
public SymbolType visitTypeNamedRef(KickCParser.TypeNamedRefContext ctx) {
public Object visitTypeNamedRef(KickCParser.TypeNamedRefContext ctx) {
Scope typeDefScope = program.getScope().getTypeDefScope();
Variable typeDefVariable = typeDefScope.getVariable(ctx.getText());
if(typeDefVariable != null) {
if(typeDefVariable.getArraySpec() != null)
// TODO: Handle typedef array of array correctly
//varDecl.getDeclType().setArraySpec(typeDefVariable.getArraySpec());
throw new InternalError("Typedef with arrays not supported!");
return typeDefVariable.getType();
if(typeDefVariable.isNoModify() || typeDefVariable.isVolatile() || typeDefVariable.isToNoModify() || typeDefVariable.isToVolatile())
// TODO: Handle type directives correctly
throw new InternalError("Typedef with type directives not supported!");
varDecl.setDeclType(typeDefVariable.getType());
return null;
}
throw new CompileError("Unknown type " + ctx.getText(), new StatementSource(ctx));
}
@Override
public SymbolType visitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx) {
public Object visitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx) {
String signedness = ctx.getChild(0).getText();
String simpleTypeName;
if(ctx.SIMPLETYPE() != null) {
simpleTypeName = ctx.SIMPLETYPE().getText();
@ -1752,29 +1799,33 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(symbolType == null) {
throw new CompileError("Unknown type " + fullName, new StatementSource(ctx));
}
return symbolType;
varDecl.setDeclType(symbolType);
return null;
}
@Override
public SymbolType visitTypePar(KickCParser.TypeParContext ctx) {
return (SymbolType) visit(ctx.type());
public Object visitTypePar(KickCParser.TypeParContext ctx) {
visit(ctx.type());
return null;
}
@Override
public SymbolType visitTypeArray(KickCParser.TypeArrayContext ctx) {
public Object visitTypeArray(KickCParser.TypeArrayContext ctx) {
if(program.isWarnArrayType()) {
program.getLog().append("Non-standard array declaration.\n" + new StatementSource(ctx).toString());
SymbolType elementType = (SymbolType) visit(ctx.type());
visit(ctx.type());
final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType();
final VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType();
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType()));
arrayDeclType.setElementDeclType(elementDeclType);
if(ctx.expr() != null) {
RValue sizeVal = (RValue) visit(ctx.expr());
//varDecl.getDeclType().setArraySpec(new ArraySpec((ConstantValue) sizeVal));
//return new SymbolTypePointer(elementType);
throw new InternalError("Array types not supported!");
arrayDeclType.setArraySpec(new ArraySpec((ConstantValue) sizeVal));
} else {
//varDecl.getDeclType().setArraySpec(new ArraySpec());
//return new SymbolTypePointer(elementType);
throw new InternalError("Array types not supported!");
arrayDeclType.setArraySpec(new ArraySpec());
}
varDecl.setVarDeclType(arrayDeclType);
return null;
} else {
throw new CompileError("ERROR! Non-standard array declaration. Allow using commandline option -Warraytype", new StatementSource(ctx));
}
@ -1782,8 +1833,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Object visitTypeProcedure(KickCParser.TypeProcedureContext ctx) {
SymbolType returnType = (SymbolType) visit(ctx.type());
return new SymbolTypeProcedure(returnType);
visit(ctx.type());
SymbolType returnType = varDecl.getEffectiveType();
varDecl.setDeclType(new SymbolTypeProcedure(returnType));
return null;
}
@Override
@ -1956,7 +2009,11 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public SymbolType visitTypeSpecifierSimple(KickCParser.TypeSpecifierSimpleContext ctx) {
return (SymbolType) this.visit(ctx.type());
varDeclPush();
this.visit(ctx.type());
final SymbolType type = varDecl.getEffectiveType();
varDeclPop();
return type;
}
@Override

View File

@ -37,7 +37,6 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testMaCoalesceProblem() throws IOException, URISyntaxException {
compileAndCompare("ma_coalesce_problem");

View File

@ -7,13 +7,13 @@ typedef const char CC;
typedef char * P;
// Pointer to const typedef
typedef char * const PC;
typedef const char * PC;
// Const pointer typedef
typedef char * const CP;
// Pointer to const
char * const pc0 = 0x0400;
const char * pc0 = 0x0400;
CC *pc1 = 0x0400;
PC pc2 = 0x0400;
@ -23,7 +23,7 @@ CP cp1 = 0x0400;
const P cp2 = 0x0400;
// Const pointer to const
char * const const cpc0 = 0x0400;
const char * const cpc0 = 0x0400;
CC * const cpc1 = 0x0400;
const PC cpc2 = 0x0400;

View File

@ -2,8 +2,6 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Pointer to const
.label pc0 = $400
// Const pointer
.label cp0 = $400
.label cp2 = $400
@ -11,6 +9,8 @@
.label cpc0 = $400
.label cpc1 = $400
.label cpc2 = $400
// Pointer to const
.label pc0 = $400
.label pc1 = $400
.label pc2 = $400
.label cp1 = $400

View File

@ -10,13 +10,13 @@
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) SCREEN) ← *((const nomodify byte*) pc0)
[4] *((const byte*) SCREEN) ← *((const to_nomodify byte*) pc0)
[5] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) pc1)
[6] *((const byte*) SCREEN+(byte) 2) ← *((const byte*) pc2)
[7] *((const byte*) SCREEN+(byte) 3) ← *((const nomodify byte*) cp0)
[8] *((const byte*) SCREEN+(byte) 4) ← *((const byte*) cp1)
[9] *((const byte*) SCREEN+(byte) 5) ← *((const nomodify byte*) cp2)
[10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify byte*) cpc0)
[10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify to_nomodify byte*) cpc0)
[11] *((const byte*) SCREEN+(byte) 7) ← *((const nomodify byte*) cpc1)
[12] *((const byte*) SCREEN+(byte) 8) ← *((const nomodify byte*) cpc2)
to:main::@return

View File

@ -1,3 +1,4 @@
Identified constant variable (to_nomodify byte*) pc0
Identified constant variable (byte*) pc1
Identified constant variable (byte*) pc2
Identified constant variable (byte*) cp1
@ -10,7 +11,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
(byte) main::idx#0 ← (byte) 0
*((const byte*) SCREEN + (byte) main::idx#0) ← *((const nomodify byte*) pc0)
*((const byte*) SCREEN + (byte) main::idx#0) ← *((const to_nomodify byte*) pc0)
(byte) main::idx#1 ← ++ (byte) main::idx#0
*((const byte*) SCREEN + (byte) main::idx#1) ← *((const byte*) pc1)
(byte) main::idx#2 ← ++ (byte) main::idx#1
@ -22,7 +23,7 @@ main: scope:[main] from @1
(byte) main::idx#5 ← ++ (byte) main::idx#4
*((const byte*) SCREEN + (byte) main::idx#5) ← *((const nomodify byte*) cp2)
(byte) main::idx#6 ← ++ (byte) main::idx#5
*((const byte*) SCREEN + (byte) main::idx#6) ← *((const nomodify byte*) cpc0)
*((const byte*) SCREEN + (byte) main::idx#6) ← *((const nomodify to_nomodify byte*) cpc0)
(byte) main::idx#7 ← ++ (byte) main::idx#6
*((const byte*) SCREEN + (byte) main::idx#7) ← *((const nomodify byte*) cpc1)
(byte) main::idx#8 ← ++ (byte) main::idx#7
@ -48,7 +49,7 @@ SYMBOL TABLE SSA
(const nomodify byte*) cp0 = (byte*)(number) $400
(const byte*) cp1 = (byte*)(number) $400
(const nomodify byte*) cp2 = (byte*)(number) $400
(const nomodify byte*) cpc0 = (byte*)(number) $400
(const nomodify to_nomodify byte*) cpc0 = (byte*)(number) $400
(const nomodify byte*) cpc1 = (byte*)(number) $400
(const nomodify byte*) cpc2 = (byte*)(number) $400
(void()) main()
@ -64,7 +65,7 @@ SYMBOL TABLE SSA
(byte) main::idx#7
(byte) main::idx#8
(byte) main::idx#9
(const nomodify byte*) pc0 = (byte*)(number) $400
(const to_nomodify byte*) pc0 = (byte*)(number) $400
(const byte*) pc1 = (byte*)(number) $400
(const byte*) pc2 = (byte*)(number) $400
@ -81,7 +82,7 @@ Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Constant (const byte) main::idx#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (const byte) main::idx#0) ← *((const nomodify byte*) pc0)
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (const byte) main::idx#0) ← *((const to_nomodify byte*) pc0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (byte) main::idx#9 and assignment [17] (byte) main::idx#9 ← ++ (byte) main::idx#8
Successful SSA optimization PassNEliminateUnusedVars
@ -189,13 +190,13 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) SCREEN) ← *((const nomodify byte*) pc0)
[4] *((const byte*) SCREEN) ← *((const to_nomodify byte*) pc0)
[5] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) pc1)
[6] *((const byte*) SCREEN+(byte) 2) ← *((const byte*) pc2)
[7] *((const byte*) SCREEN+(byte) 3) ← *((const nomodify byte*) cp0)
[8] *((const byte*) SCREEN+(byte) 4) ← *((const byte*) cp1)
[9] *((const byte*) SCREEN+(byte) 5) ← *((const nomodify byte*) cp2)
[10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify byte*) cpc0)
[10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify to_nomodify byte*) cpc0)
[11] *((const byte*) SCREEN+(byte) 7) ← *((const nomodify byte*) cpc1)
[12] *((const byte*) SCREEN+(byte) 8) ← *((const nomodify byte*) cpc2)
to:main::@return
@ -220,8 +221,6 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
// Pointer to const
.label pc0 = $400
// Const pointer
.label cp0 = $400
.label cp2 = $400
@ -229,6 +228,8 @@ Target platform is c64basic / MOS6502X
.label cpc0 = $400
.label cpc1 = $400
.label cpc2 = $400
// Pointer to const
.label pc0 = $400
.label pc1 = $400
.label pc2 = $400
.label cp1 = $400
@ -249,7 +250,7 @@ __bend_from___b1:
__bend:
// main
main: {
// [4] *((const byte*) SCREEN) ← *((const nomodify byte*) pc0) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) SCREEN) ← *((const to_nomodify byte*) pc0) -- _deref_pbuc1=_deref_pbuc2
lda pc0
sta SCREEN
// [5] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) pc1) -- _deref_pbuc1=_deref_pbuc2
@ -267,7 +268,7 @@ main: {
// [9] *((const byte*) SCREEN+(byte) 5) ← *((const nomodify byte*) cp2) -- _deref_pbuc1=_deref_pbuc2
lda cp2
sta SCREEN+5
// [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify byte*) cpc0) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify to_nomodify byte*) cpc0) -- _deref_pbuc1=_deref_pbuc2
lda cpc0
sta SCREEN+6
// [11] *((const byte*) SCREEN+(byte) 7) ← *((const nomodify byte*) cpc1) -- _deref_pbuc1=_deref_pbuc2
@ -285,13 +286,13 @@ main: {
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) SCREEN) ← *((const nomodify byte*) pc0) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [4] *((const byte*) SCREEN) ← *((const to_nomodify byte*) pc0) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [5] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) pc1) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 2) ← *((const byte*) pc2) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 3) ← *((const nomodify byte*) cp0) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN+(byte) 4) ← *((const byte*) cp1) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN+(byte) 5) ← *((const nomodify byte*) cp2) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify byte*) cpc0) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify to_nomodify byte*) cpc0) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) 7) ← *((const nomodify byte*) cpc1) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN+(byte) 8) ← *((const nomodify byte*) cpc2) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
@ -310,8 +311,6 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
// Pointer to const
.label pc0 = $400
// Const pointer
.label cp0 = $400
.label cp2 = $400
@ -319,6 +318,8 @@ ASSEMBLER BEFORE OPTIMIZATION
.label cpc0 = $400
.label cpc1 = $400
.label cpc2 = $400
// Pointer to const
.label pc0 = $400
.label pc1 = $400
.label pc2 = $400
.label cp1 = $400
@ -339,7 +340,7 @@ __bend_from___b1:
__bend:
// main
main: {
// [4] *((const byte*) SCREEN) ← *((const nomodify byte*) pc0) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) SCREEN) ← *((const to_nomodify byte*) pc0) -- _deref_pbuc1=_deref_pbuc2
lda pc0
sta SCREEN
// [5] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) pc1) -- _deref_pbuc1=_deref_pbuc2
@ -357,7 +358,7 @@ main: {
// [9] *((const byte*) SCREEN+(byte) 5) ← *((const nomodify byte*) cp2) -- _deref_pbuc1=_deref_pbuc2
lda cp2
sta SCREEN+5
// [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify byte*) cpc0) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify to_nomodify byte*) cpc0) -- _deref_pbuc1=_deref_pbuc2
lda cpc0
sta SCREEN+6
// [11] *((const byte*) SCREEN+(byte) 7) ← *((const nomodify byte*) cpc1) -- _deref_pbuc1=_deref_pbuc2
@ -400,13 +401,13 @@ FINAL SYMBOL TABLE
(const nomodify byte*) cp0 = (byte*) 1024
(const byte*) cp1 = (byte*) 1024
(const nomodify byte*) cp2 = (byte*) 1024
(const nomodify byte*) cpc0 = (byte*) 1024
(const nomodify to_nomodify byte*) cpc0 = (byte*) 1024
(const nomodify byte*) cpc1 = (byte*) 1024
(const nomodify byte*) cpc2 = (byte*) 1024
(void()) main()
(label) main::@return
(byte) main::idx
(const nomodify byte*) pc0 = (byte*) 1024
(const to_nomodify byte*) pc0 = (byte*) 1024
(const byte*) pc1 = (byte*) 1024
(const byte*) pc2 = (byte*) 1024
@ -422,8 +423,6 @@ Score: 78
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
// Pointer to const
.label pc0 = $400
// Const pointer
.label cp0 = $400
.label cp2 = $400
@ -431,6 +430,8 @@ Score: 78
.label cpc0 = $400
.label cpc1 = $400
.label cpc2 = $400
// Pointer to const
.label pc0 = $400
.label pc1 = $400
.label pc2 = $400
.label cp1 = $400
@ -444,7 +445,7 @@ Score: 78
// main
main: {
// SCREEN[idx++] = *pc0
// [4] *((const byte*) SCREEN) ← *((const nomodify byte*) pc0) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) SCREEN) ← *((const to_nomodify byte*) pc0) -- _deref_pbuc1=_deref_pbuc2
lda pc0
sta SCREEN
// SCREEN[idx++] = *pc1
@ -468,7 +469,7 @@ main: {
lda cp2
sta SCREEN+5
// SCREEN[idx++] = *cpc0
// [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify byte*) cpc0) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 6) ← *((const nomodify to_nomodify byte*) cpc0) -- _deref_pbuc1=_deref_pbuc2
lda cpc0
sta SCREEN+6
// SCREEN[idx++] = *cpc1

View File

@ -5,13 +5,13 @@
(const nomodify byte*) cp0 = (byte*) 1024
(const byte*) cp1 = (byte*) 1024
(const nomodify byte*) cp2 = (byte*) 1024
(const nomodify byte*) cpc0 = (byte*) 1024
(const nomodify to_nomodify byte*) cpc0 = (byte*) 1024
(const nomodify byte*) cpc1 = (byte*) 1024
(const nomodify byte*) cpc2 = (byte*) 1024
(void()) main()
(label) main::@return
(byte) main::idx
(const nomodify byte*) pc0 = (byte*) 1024
(const to_nomodify byte*) pc0 = (byte*) 1024
(const byte*) pc1 = (byte*) 1024
(const byte*) pc2 = (byte*) 1024