diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java b/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java index 4475605bc..0c327799d 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Variable.java @@ -32,18 +32,12 @@ public class Variable implements Symbol { PHI_MASTER, PHI_VERSION, INTERMEDIATE, LOAD_STORE, CONSTANT } - /** The storage strategy for the variable. */ + /** The kind of the variable. */ private Kind kind; /** True of the variable is a compile-time constant (previously ConstantVar) [ALL] */ private boolean isConstant; - /** Specifies that the variable is declared as const */ - private boolean declaredConst; - - /** Specifies that the variable is declared as __notconst */ - private boolean declaredNotConst; - /** The local name of the variable. [ALL] */ private String name; @@ -68,6 +62,12 @@ public class Variable implements Symbol { /** Specifies the register the variable must be put into during execution. [Only variables] */ private Registers.Register declaredRegister; + /** Specifies that the variable is declared as const */ + private boolean declaredConst; + + /** Specifies that the variable is declared as __notconst */ + private boolean declaredNotConst; + /** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only Variables]*/ private boolean declaredVolatile; @@ -174,7 +174,27 @@ public class Variable implements Symbol { this.setComments(phiMaster.getComments()); } - + /** + * Create a copy of a variable with a different name in a different scope + * + * @param name The name + * @param scope The scope + * @param original The original variable + */ + public Variable(String name, Scope scope, Variable original) { + this(name, scope, original.getType(), original.getKind(), original.getMemoryArea(), original.getDataSegment()); + this.setDeclaredAlignment(original.getDeclaredAlignment()); + this.setDeclaredAsRegister(original.isDeclaredAsRegister()); + this.setDeclaredNotRegister(original.isDeclaredAsNotRegister()); + this.setDeclaredConst(original.isDeclaredConst()); + this.setDeclaredNotConst(original.isDeclaredNotConst()); + this.setDeclaredVolatile(original.isDeclaredVolatile()); + this.setDeclaredExport(original.isDeclaredExport()); + this.setDeclaredRegister(original.getDeclaredRegister()); + this.setInferredVolatile(original.isInferredVolatile()); + this.setInferredType(original.isInferredType()); + this.setComments(original.getComments()); + } public Kind getKind() { return kind; @@ -289,6 +309,10 @@ public class Variable implements Symbol { return dataSegment; } + public void setDataSegment(String dataSegment) { + this.dataSegment = dataSegment; + } + @Override public String getLocalName() { return name; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java index 956c21c1d..fb472c0cb 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java @@ -300,19 +300,8 @@ public class Pass1ProcedureInline extends Pass1Base { if(procSymbol instanceof Variable) { Variable procVar = (Variable) procSymbol; String inlineVarName = getInlineSymbolName(procedure, procSymbol, serial); - Variable inlineVar = callScope.addVariablePhiMaster(inlineVarName, procSymbol.getType(), procVar.getMemoryArea(), procVar.getDataSegment()); - inlineVar.setInferredType(procVar.isInferredType()); - inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment()); - inlineVar.setDeclaredConst(procVar.isDeclaredConst()); - inlineVar.setDeclaredNotConst(procVar.isDeclaredNotConst()); - inlineVar.setDeclaredAsRegister(procVar.isDeclaredAsRegister()); - inlineVar.setDeclaredNotRegister(procVar.isDeclaredAsNotRegister()); - inlineVar.setDeclaredRegister(procVar.getDeclaredRegister()); - inlineVar.setKind(procVar.getKind()); - inlineVar.setMemoryArea(procVar.getMemoryArea()); - inlineVar.setDeclaredVolatile(procVar.isDeclaredVolatile()); - inlineVar.setInferredVolatile(procVar.isInferredVolatile()); - inlineVar.setDeclaredExport(procVar.isDeclaredExport()); + Variable inlineVar = new Variable(inlineVarName, callScope, procVar); + callScope.add(inlineVar); } else if(procSymbol instanceof Label) { String inlineLabelName = getInlineSymbolName(procedure, procSymbol, serial); callScope.addLabel(inlineLabelName); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindBlockScopes.java b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindBlockScopes.java index 5d84cb022..3183cbfbb 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindBlockScopes.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindBlockScopes.java @@ -75,22 +75,13 @@ public class Pass1UnwindBlockScopes extends Pass1Base { Variable variable = (Variable) symbol; if(variable.isKindPhiMaster() || variable.isKindConstant()) { String name = findLocalName(procedure, symbol); - Variable var = (Variable) symbol; - Variable unwound = procedure.addVariablePhiMaster(name, symbol.getType(), var.getMemoryArea(), var.getDataSegment()); - unwound.setDeclaredAlignment(var.getDeclaredAlignment()); - unwound.setDeclaredConst(var.isDeclaredConst()); - unwound.setDeclaredNotConst((var.isDeclaredNotConst())); - unwound.setDeclaredVolatile(var.isDeclaredVolatile()); - unwound.setInferredVolatile(var.isInferredVolatile()); - unwound.setDeclaredRegister((var.getDeclaredRegister())); - unwound.setDeclaredExport(var.isDeclaredExport()); + Variable unwound = new Variable(name, procedure, (Variable) symbol); + procedure.add(unwound); unwoundSymbols.put(symbol.getRef(), unwound.getRef()); - unwound.setKind(var.getKind()); - unwound.setMemoryArea(var.getMemoryArea()); } else if(variable.isKindIntermediate()) { - Variable unwound = procedure.addVariableIntermediate(); - unwound.setKind(variable.getKind()); - unwound.setMemoryArea(variable.getMemoryArea()); + String name = procedure.allocateIntermediateVariableName(); + Variable unwound = new Variable(name, procedure, (Variable) symbol); + procedure.add(unwound); unwoundSymbols.put(symbol.getRef(), unwound.getRef()); } else { throw new CompileError("ERROR! Unexpected symbol encountered in block scope " + symbol.toString(getProgram())); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java index 62b19fe37..02636ae15 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java @@ -210,28 +210,14 @@ public class Pass1UnwindStructValues extends Pass1Base { StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope()); StructUnwinding.VariableUnwinding variableUnwinding = structUnwinding.createVariableUnwinding(variable.getRef()); for(Variable member : structDefinition.getAllVariables(false)) { - Variable memberVariable; - if(variable.getRef().isIntermediate()) { - memberVariable = scope.add(new Variable( variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), Variable.Kind.INTERMEDIATE, variable.getMemoryArea(), variable.getDataSegment())); - } else { - if(member.getType() instanceof SymbolTypePointer) { - // Always put pointers in ZP memory area - memberVariable = scope.addVariablePhiMaster(variable.getLocalName() + "_" + member.getLocalName(), member.getType(), Variable.MemoryArea.ZEROPAGE_MEMORY, variable.getDataSegment()); - } else { - memberVariable = scope.addVariablePhiMaster(variable.getLocalName() + "_" + member.getLocalName(), member.getType(), member.getMemoryArea(), variable.getDataSegment()); - } - } + String name = variable.getLocalName() + "_" + member.getLocalName(); + Variable.MemoryArea memoryArea = (member.getType() instanceof SymbolTypePointer)?Variable.MemoryArea.ZEROPAGE_MEMORY:variable.getMemoryArea(); + Variable memberVariable = scope.add(new Variable(name, scope, member.getType(), variable.getKind(), memoryArea, variable.getDataSegment())); memberVariable.setDeclaredVolatile(variable.isDeclaredVolatile()); memberVariable.setInferredVolatile(variable.isInferredVolatile()); memberVariable.setDeclaredConst(variable.isDeclaredConst()); memberVariable.setDeclaredNotConst(variable.isDeclaredNotConst()); memberVariable.setDeclaredExport(variable.isDeclaredExport()); - memberVariable.setKind(variable.getKind()); - if(memberVariable.getType() instanceof SymbolTypePointer) { - memberVariable.setMemoryArea(Variable.MemoryArea.ZEROPAGE_MEMORY); - } else { - memberVariable.setMemoryArea(variable.getMemoryArea()); - } variableUnwinding.setMemberUnwinding(member.getLocalName(), memberVariable.getRef()); getLog().append("Created struct value member variable " + memberVariable.toString(getProgram())); } diff --git a/src/main/java/dk/camelot64/kickc/passes/utils/Unroller.java b/src/main/java/dk/camelot64/kickc/passes/utils/Unroller.java index 857e5fdde..afec5c69c 100644 --- a/src/main/java/dk/camelot64/kickc/passes/utils/Unroller.java +++ b/src/main/java/dk/camelot64/kickc/passes/utils/Unroller.java @@ -229,18 +229,10 @@ public class Unroller { Variable definedVar = program.getScope().getVariable(definedVarRef); Variable newVar; if(definedVarRef.isIntermediate()) { - newVar = definedVar.getScope().addVariableIntermediate(); - newVar.setType(definedVar.getType()); - newVar.setDeclaredAsRegister(definedVar.isDeclaredAsRegister()); - newVar.setDeclaredRegister(definedVar.getDeclaredRegister()); - newVar.setDeclaredNotRegister(definedVar.isDeclaredAsNotRegister()); - newVar.setKind(definedVar.getKind()); - newVar.setMemoryArea(definedVar.getMemoryArea()); - newVar.setDeclaredVolatile(definedVar.isDeclaredVolatile()); - newVar.setInferredVolatile(definedVar.isInferredVolatile()); - newVar.setDeclaredExport(definedVar.isDeclaredExport()); - newVar.setDeclaredAlignment(definedVar.getDeclaredAlignment()); - newVar.setInferredType(definedVar.isInferredType()); + Scope scope = definedVar.getScope(); + String name = scope.allocateIntermediateVariableName(); + newVar = new Variable(name, scope, definedVar); + scope.add(newVar); } else if(definedVarRef.isVersion()) { newVar = (definedVar).getVersionOf().createVersion(); } else {