1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-11 04:29:53 +00:00

Restructured Variable creation to make it more explicit what type is being created.

This commit is contained in:
jespergravgaard 2019-12-08 17:49:14 +01:00
parent 2bad8c915f
commit cff815f5d7
16 changed files with 171 additions and 111 deletions

View File

@ -79,12 +79,13 @@ public class AsmFragmentTemplate {
ProgramScope scope = new ProgramScope();
LinkedHashMap<String, Value> bindings = new LinkedHashMap<>();
{
Variable v1 = new Variable( "z1", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable v2 = new Variable( "z2", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable v3 = new Variable( "z3", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable v4 = new Variable( "z4", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable v5 = new Variable( "z5", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable v6 = new Variable( "z6", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable master = Variable.createPhiMaster("z", SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable v1 = Variable.createPhiVersion(master, 1); v1.setName("z1");
Variable v2 = Variable.createPhiVersion(master, 2); v2.setName("z2");
Variable v3 = Variable.createPhiVersion(master, 3); v3.setName("z3");
Variable v4 = Variable.createPhiVersion(master, 4); v4.setName("z4");
Variable v5 = Variable.createPhiVersion(master, 5); v5.setName("z5");
Variable v6 = Variable.createPhiVersion(master, 6); v6.setName("z6");
v1.setAllocation(new Registers.RegisterZpMem(2, 1));
v2.setAllocation(new Registers.RegisterZpMem(4, 1));
v3.setAllocation(new Registers.RegisterZpMem(6, 1));
@ -99,12 +100,12 @@ public class AsmFragmentTemplate {
if(signature.contains("z6")) bindings.put("z6", v6);
}
{
Variable v1 = new Variable( "m1", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v2 = new Variable( "m2", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v3 = new Variable( "m3", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v4 = new Variable( "m4", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v5 = new Variable( "m5", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v6 = new Variable( "m6", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v1 = Variable.createLoadStore("m1", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v2 = Variable.createLoadStore("m2", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v3 = Variable.createLoadStore("m3", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v4 = Variable.createLoadStore("m4", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v5 = Variable.createLoadStore("m5", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v6 = Variable.createLoadStore("m6", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
v1.setAllocation(new Registers.RegisterMainMem(v1.getVariableRef(), 1, null));
v2.setAllocation(new Registers.RegisterMainMem(v2.getVariableRef(), 1, null));
v3.setAllocation(new Registers.RegisterMainMem(v3.getVariableRef(), 1, null));

View File

@ -23,7 +23,7 @@ public class CallingConventionStack {
if(returnOffsetConstant == null) {
// Constant not found - create it
long returnByteOffset = getReturnByteOffset(procedure);
returnOffsetConstant = new Variable(returnOffsetConstantName, SymbolType.BYTE, null, procedure, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE));
returnOffsetConstant = Variable.createConstant(returnOffsetConstantName, SymbolType.BYTE, procedure, null, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
procedure.add(returnOffsetConstant);
}
return returnOffsetConstant.getConstantRef();
@ -42,7 +42,7 @@ public class CallingConventionStack {
if(paramOffsetConstant == null) {
// Constant not found - create it
long paramByteOffset = getParameterByteOffset(procedure, parameter);
paramOffsetConstant = new Variable(paramOffsetConstantName, SymbolType.BYTE, null, procedure, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(paramByteOffset & 0xff, SymbolType.BYTE));
paramOffsetConstant = Variable.createConstant(paramOffsetConstantName, SymbolType.BYTE, procedure, null, new ConstantInteger(paramByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
procedure.add(paramOffsetConstant);
}
return paramOffsetConstant.getConstantRef();
@ -123,7 +123,7 @@ public class CallingConventionStack {
*/
public static ConstantRef getStackBaseConstant(ProgramScope programScope) {
long STACK_BASE_ADDRESS = 0x103L;
Variable stackBase = new Variable("STACK_BASE", SymbolType.WORD, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(STACK_BASE_ADDRESS, SymbolType.WORD));
Variable stackBase = Variable.createConstant("STACK_BASE", SymbolType.WORD, programScope, null, new ConstantInteger(STACK_BASE_ADDRESS, SymbolType.WORD), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(stackBase);
return stackBase.getConstantRef();
}

View File

@ -42,7 +42,7 @@ public class OperatorSizeOf extends OperatorUnary {
if(typeSizeConstant == null) {
// Constant not found - create it
long typeSize = type.getSizeBytes();
typeSizeConstant = new Variable(typeConstName, SymbolType.BYTE, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(typeSize&0xff, SymbolType.BYTE));
typeSizeConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(typeSize&0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(typeSizeConstant);
}
return typeSizeConstant.getConstantRef();

View File

@ -47,7 +47,7 @@ public class OperatorTypeId extends OperatorUnary {
if(typeIdConstant == null) {
// Constant not found - create it
long typeSize = getTypeId(type);
typeIdConstant = new Variable(typeConstName, SymbolType.BYTE, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(typeSize));
typeIdConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(typeSize), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(typeIdConstant);
}
return typeIdConstant.getConstantRef();

View File

@ -100,17 +100,9 @@ public abstract class Scope implements Symbol, Serializable {
symbols.remove(symbol.getLocalName());
}
public Variable addVariable(Variable.Kind kind, String name, SymbolType type, Variable.MemoryArea memoryArea, String dataSegment) {
return add(new Variable( name, kind, type, this, memoryArea, dataSegment));
}
public Variable addVariablePhiMaster(String name, SymbolType type, Variable.MemoryArea memoryArea, String dataSegment) {
return add(new Variable( name, Variable.Kind.PHI_MASTER, type, this, memoryArea, dataSegment));
}
public Variable addVariableIntermediate() {
String name = allocateIntermediateVariableName();
return add(new Variable( name, Variable.Kind.INTERMEDIATE, SymbolType.VAR, this, Variable.MemoryArea.ZEROPAGE_MEMORY, getSegmentData()));
return add(Variable.createIntermediate( name, this, getSegmentData()));
}
/**

View File

@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.Registers;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.values.ConstantRef;
import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.model.values.SymbolVariableRef;
@ -19,7 +20,7 @@ public class Variable implements Symbol {
/**
* The kind of the variable. The kind is the most significant property of the variable since it drives most of the behavior.
*
* <p>
* The value depends on the directives memory/register/volatile/const - and on the compilers optimization decisions.
* <ul>
* <li>PHI_MASTER variables are turned into PHI-versions and PHI-nodes are used for them throughout the entire program. The PHI-master itself is only an information container and does not live in memory at runtime.</li>
@ -99,21 +100,26 @@ public class Variable implements Symbol {
}
/**
* Create a runtime variable
* Create a variable (or constant)
*
* @param name The name
* @param kind The storage strategy (PHI-master/PHI-version/Intermediate/load store/constant)
* @param type The type
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @param arraySpec The array specification of the variable (if it is an array)
* @param constantValue The constant value of the variable (if it is constant)
*/
public Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment) {
private Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ArraySpec arraySpec, ConstantValue constantValue) {
this.name = name;
this.kind = kind;
if(Kind.PHI_MASTER.equals(kind))
this.nextPhiVersionNumber = 0;
this.type = type;
this.scope = scope;
this.arraySpec = arraySpec;
this.constantValue = constantValue;
this.dataSegment = dataSegment;
this.memoryArea = memoryArea;
this.comments = new ArrayList<>();
@ -121,74 +127,132 @@ public class Variable implements Symbol {
}
/**
* Create a compile-time constant variable
* Create an intermediate variable. The type will initially be set to {@link SymbolType#VAR}.
*
* @param name The name
* @param type The type
* @param scope The scope
* @param dataSegment The data segment (in main memory)
* @param value The constant value
* @return The new intermediate variable
*/
public Variable(String name, SymbolType type, ArraySpec arraySpec, Scope scope, String dataSegment, ConstantValue value) {
this(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment);
this.arraySpec = arraySpec;
this.constantValue = value;
public static Variable createIntermediate(String name, Scope scope, String dataSegment) {
return new Variable(name, Kind.INTERMEDIATE, SymbolType.VAR, scope, MemoryArea.ZEROPAGE_MEMORY, dataSegment, null, null);
}
/**
* Create a constant version of a variable
* @param variable The variable to create a constant version of
* @param constVal The constant value
* Create a load/store variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @return The new PHI-master variable
*/
public Variable(Variable variable, ConstantValue constVal) {
this(variable.getName(),variable.getType(), variable.getArraySpec(), variable.getScope(), variable.getDataSegment(), constVal);
this.setDeclaredAlignment(variable.getDeclaredAlignment());
this.setDeclaredAsRegister(variable.isDeclaredAsRegister());
this.setDeclaredConst(variable.isDeclaredConst());
this.setDeclaredRegister(variable.getDeclaredRegister());
this.setDeclaredVolatile(variable.isDeclaredVolatile());
this.setDeclaredExport(variable.isDeclaredExport());
this.setInferredVolatile(variable.isInferredVolatile());
this.setComments(variable.getComments());
public static Variable createLoadStore(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Kind.LOAD_STORE, type, scope, memoryArea, dataSegment, null, null);
}
/**
* Create a PHI master variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @return The new PHI-master variable
*/
public static Variable createPhiMaster(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Kind.PHI_MASTER, type, scope, memoryArea, dataSegment, null, null);
}
/**
* Create a version of a PHI master variable
*
* @param phiMaster The PHI master variable.
* @param version The version number
* @param versionNum The version number
*/
private Variable(Variable phiMaster, int version) {
this(phiMaster.getName() + "#" + version, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment());
this.setArraySpec(phiMaster.getArraySpec());
this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
this.setDeclaredConst(phiMaster.isDeclaredConst());
this.setDeclaredRegister(phiMaster.getDeclaredRegister());
this.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
this.setDeclaredExport(phiMaster.isDeclaredExport());
this.setInferredVolatile(phiMaster.isInferredVolatile());
this.setComments(phiMaster.getComments());
public static Variable createPhiVersion(Variable phiMaster, int versionNum) {
Variable version = new Variable(phiMaster.getName() + "#" + versionNum, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment(), phiMaster.getArraySpec(), null);
version.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
version.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
version.setDeclaredConst(phiMaster.isDeclaredConst());
version.setDeclaredRegister(phiMaster.getDeclaredRegister());
version.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
version.setDeclaredExport(phiMaster.isDeclaredExport());
version.setInferredVolatile(phiMaster.isInferredVolatile());
version.setComments(phiMaster.getComments());
return version;
}
/**
* Create a compile-time constant variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param value The constant value
* @param dataSegment The data segment (in main memory)
*/
public static Variable createConstant(String name, SymbolType type, Scope scope, ArraySpec arraySpec, ConstantValue value, String dataSegment) {
return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, arraySpec, value);
}
/**
* Create a constant version of a variable. Used when a variable is determined to be constant during the compile.
*
* @param variable The variable to create a constant version of
* @param constVal The constant value
*/
public static Variable createConstant(Variable variable, ConstantValue constVal) {
Variable constVar = createConstant(variable.getName(), variable.getType(), variable.getScope(), variable.getArraySpec(), constVal, variable.getDataSegment());
constVar.setDeclaredAlignment(variable.getDeclaredAlignment());
constVar.setDeclaredAsRegister(variable.isDeclaredAsRegister());
constVar.setDeclaredConst(variable.isDeclaredConst());
constVar.setDeclaredRegister(variable.getDeclaredRegister());
constVar.setDeclaredVolatile(variable.isDeclaredVolatile());
constVar.setDeclaredExport(variable.isDeclaredExport());
constVar.setInferredVolatile(variable.isInferredVolatile());
constVar.setComments(variable.getComments());
return constVar;
}
/**
* Create a copy of a variable with a different name in a different scope
*
* @param name The name
* @param scope The scope
* @param name The name for the new variable
* @param scope The scope for the new variable
* @param original The original variable
*/
public Variable(String name, Scope scope, Variable original) {
this(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment());
this.setArraySpec(original.getArraySpec());
this.setDeclaredAlignment(original.getDeclaredAlignment());
this.setDeclaredAsRegister(original.isDeclaredAsRegister());
this.setDeclaredConst(original.isDeclaredConst());
this.setDeclaredVolatile(original.isDeclaredVolatile());
this.setDeclaredExport(original.isDeclaredExport());
this.setDeclaredRegister(original.getDeclaredRegister());
this.setInferredVolatile(original.isInferredVolatile());
this.setComments(original.getComments());
this.setConstantValue(original.getConstantValue());
public static Variable createCopy(String name, Scope scope, Variable original) {
Variable copy = new Variable(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment(), original.getArraySpec(), original.getConstantValue());
copy.setDeclaredAlignment(original.getDeclaredAlignment());
copy.setDeclaredAsRegister(original.isDeclaredAsRegister());
copy.setDeclaredConst(original.isDeclaredConst());
copy.setDeclaredVolatile(original.isDeclaredVolatile());
copy.setDeclaredExport(original.isDeclaredExport());
copy.setDeclaredRegister(original.getDeclaredRegister());
copy.setInferredVolatile(original.isInferredVolatile());
copy.setComments(original.getComments());
return copy;
}
/**
* Create a variable representing a single member of a struct variable.
* @param structVar The variable that holds a struct value.
* @param memberDefinition The definition of the struct member
* @return The new unwound variable representing the member of the struct
*/
public static Variable createStructMemberUnwound(Variable structVar, Variable memberDefinition) {
String name = structVar.getLocalName() + "_" + memberDefinition.getLocalName();
Variable.MemoryArea memoryArea = (memberDefinition.getType() instanceof SymbolTypePointer) ? Variable.MemoryArea.ZEROPAGE_MEMORY : structVar.getMemoryArea();
Variable memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), null, null);
memberVariable.setArraySpec(memberDefinition.getArraySpec());
memberVariable.setDeclaredVolatile(structVar.isDeclaredVolatile());
memberVariable.setInferredVolatile(structVar.isInferredVolatile());
memberVariable.setDeclaredConst(structVar.isDeclaredConst());
memberVariable.setDeclaredExport(structVar.isDeclaredExport());
return memberVariable;
}
public Kind getKind() {
@ -252,7 +316,7 @@ public class Variable implements Symbol {
public Variable createVersion() {
if(!isKindPhiMaster())
throw new InternalError("Cannot version non-PHI variable " + this.toString());
Variable version = new Variable(this, nextPhiVersionNumber++);
Variable version = Variable.createPhiVersion(this, nextPhiVersionNumber++);
getScope().add(version);
return version;
}

View File

@ -4,6 +4,7 @@ import dk.camelot64.kickc.NumberParser;
import dk.camelot64.kickc.SourceLoader;
import dk.camelot64.kickc.asm.AsmClobber;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.operators.*;
import dk.camelot64.kickc.model.statements.*;
@ -208,7 +209,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
Variable returnVar = null;
if(!SymbolType.VOID.equals(type)) {
returnVar = procedure.addVariablePhiMaster("return", type, defaultMemoryArea, procedure.getSegmentData());
returnVar = procedure.add(Variable.createPhiMaster("return", type, procedure, defaultMemoryArea, procedure.getSegmentData()));
}
List<Variable> parameterList = new ArrayList<>();
if(ctx.parameterListDecl() != null) {
@ -267,7 +268,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visitDeclTypes(ctx.declTypes());
SymbolType type = declVarType;
List<Directive> directives = declVarDirectives;
Variable param = new Variable( ctx.NAME().getText(), Variable.Kind.PHI_MASTER, type, getCurrentScope(), defaultMemoryArea, currentDataSegment);
Variable param = Variable.createPhiMaster( ctx.NAME().getText(), type, getCurrentScope(), defaultMemoryArea, currentDataSegment);
// Add directives
directiveContext.applyDirectives(param, true, false, directives, new StatementSource(ctx));
exitDeclTypes();
@ -577,14 +578,22 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
arraySpec = new ArraySpec(declArraySize);
}
Scope scope = getCurrentScope();
Variable constVar = new Variable(varName, declVarType, arraySpec, scope, currentDataSegment, initConstantValue);
Variable constVar = Variable.createConstant(varName, declVarType, scope, arraySpec, initConstantValue, currentDataSegment);
scope.add(constVar);
// Add comments to constant
constVar.setComments(ensureUnusedComments(declVarComments));
directiveContext.applyDirectives(constVar, false, declIsArray, declVarDirectives, statementSource);
} else {
// Create variable
Variable lValue = getCurrentScope().addVariable(kind, varName, declVarType, defaultMemoryArea, currentDataSegment);
Variable lValue;
if(kind.equals(Variable.Kind.PHI_MASTER)) {
lValue = Variable.createPhiMaster(varName, declVarType, getCurrentScope(), defaultMemoryArea, currentDataSegment);
} else if (kind.equals(Variable.Kind.LOAD_STORE)) {
lValue = Variable.createLoadStore(varName, declVarType, getCurrentScope(), defaultMemoryArea, currentDataSegment);
} else {
throw new InternalError("Unexpected variable kind! "+kind.name(), statementSource);
}
getCurrentScope().add(lValue);
// Add directives
directiveContext.applyDirectives(lValue, false, declIsArray, declVarDirectives, statementSource);
if(declVarStructMember) {
@ -715,7 +724,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
// Add a constant variable
Scope scope = getCurrentScope();
Variable constVar = new Variable(varName, declVarType, arraySpec, scope, currentDataSegment, constantArrayKickAsm);
Variable constVar = Variable.createConstant(varName, declVarType, scope, arraySpec, constantArrayKickAsm, currentDataSegment);
scope.add(constVar);
// Add comments to constant
constVar.setComments(ensureUnusedComments(declVarComments));
@ -1236,7 +1245,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Variable lValue;
if(varType != null) {
try {
lValue = getCurrentScope().addVariablePhiMaster(varName, varType, defaultMemoryArea, currentDataSegment);
lValue = getCurrentScope().add(Variable.createPhiMaster(varName, varType, getCurrentScope(), defaultMemoryArea, currentDataSegment));
} catch(CompileError e) {
throw new CompileError(e.getMessage(), statementSource);
}
@ -1542,7 +1551,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Scope parentScope = getCurrentScope();
while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope();
for(Variable member : enumDefinition.getAllConstants(false)) {
parentScope.add(new Variable(member.getLocalName(), SymbolType.BYTE, null, parentScope, currentDataSegment, member.getConstantValue()));
parentScope.add(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, null, member.getConstantValue(), currentDataSegment));
}
return SymbolType.BYTE;
} catch(CompileError e) {
@ -1576,7 +1585,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
}
}
currentEnum.add(new Variable(memberName, SymbolType.BYTE, null, getCurrentScope(), currentDataSegment, enumValue));
currentEnum.add(Variable.createConstant(memberName, SymbolType.BYTE, getCurrentScope(), null, enumValue, currentDataSegment));
return null;
}
@ -1661,7 +1670,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
scopeStack.push(typedefScope);
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
String typedefName = ctx.NAME().getText();
typedefScope.addVariablePhiMaster(typedefName, type, defaultMemoryArea, currentDataSegment);
typedefScope.add(Variable.createPhiMaster(typedefName, type, typedefScope, defaultMemoryArea, currentDataSegment));
scopeStack.pop();
return null;
}

View File

@ -120,7 +120,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
SymbolVariableRef variableRef = variable.getRef();
Scope scope = variable.getScope();
scope.remove(variable);
Variable constVar = new Variable(variable, constantValue);
Variable constVar = Variable.createConstant(variable, constantValue);
constVar.getComments().addAll(assignment.getComments());
SymbolVariableRef constRef = constVar.getRef();
aliases.put(variableRef, constRef);

View File

@ -74,7 +74,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
name = nameHint + nameHintIdx++;
}
}
Variable strConst = new Variable(name, SymbolType.STRING, new ArraySpec(), blockScope, blockScope.getSegmentData(), constantString);
Variable strConst = Variable.createConstant(name, SymbolType.STRING, blockScope, new ArraySpec(), constantString, blockScope.getSegmentData());
blockScope.add(strConst);
if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");

View File

@ -300,7 +300,7 @@ public class Pass1ProcedureInline extends Pass1Base {
if(procSymbol instanceof Variable) {
Variable procVar = (Variable) procSymbol;
String inlineVarName = getInlineSymbolName(procedure, procSymbol, serial);
Variable inlineVar = new Variable(inlineVarName, callScope, procVar);
Variable inlineVar = Variable.createCopy(inlineVarName, callScope, procVar);
callScope.add(inlineVar);
} else if(procSymbol instanceof Label) {
String inlineLabelName = getInlineSymbolName(procedure, procSymbol, serial);

View File

@ -72,17 +72,17 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
Variable variable = (Variable) symbol;
if(variable.isKindConstant()) {
String name = findLocalName(procedure, symbol);
Variable unwound = new Variable(name, procedure, (Variable) symbol);
Variable unwound = Variable.createCopy(name, procedure, (Variable) symbol);
procedure.add(unwound);
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
} else if(variable.isKindPhiMaster() || variable.isKindConstant()) {
String name = findLocalName(procedure, symbol);
Variable unwound = new Variable(name, procedure, (Variable) symbol);
Variable unwound = Variable.createCopy(name, procedure, (Variable) symbol);
procedure.add(unwound);
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
} else if(variable.isKindIntermediate()) {
String name = procedure.allocateIntermediateVariableName();
Variable unwound = new Variable(name, procedure, (Variable) symbol);
Variable unwound = Variable.createCopy(name, procedure, (Variable) symbol);
procedure.add(unwound);
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
} else {

View File

@ -207,14 +207,8 @@ public class Pass1UnwindStructValues extends Pass1Base {
StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope());
StructUnwinding.VariableUnwinding variableUnwinding = structUnwinding.createVariableUnwinding(variable.getRef());
for(Variable member : structDefinition.getAllVars(false)) {
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, variable.getKind(), member.getType(), scope, memoryArea, variable.getDataSegment()));
memberVariable.setArraySpec(member.getArraySpec());
memberVariable.setDeclaredVolatile(variable.isDeclaredVolatile());
memberVariable.setInferredVolatile(variable.isInferredVolatile());
memberVariable.setDeclaredConst(variable.isDeclaredConst());
memberVariable.setDeclaredExport(variable.isDeclaredExport());
Variable memberVariable = Variable.createStructMemberUnwound(variable, member);
scope.add(memberVariable);
variableUnwinding.setMemberUnwinding(member.getLocalName(), memberVariable.getRef());
getLog().append("Created struct value member variable " + memberVariable.toString(getProgram()));
}

View File

@ -71,7 +71,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
);
}
scope.remove(variable);
Variable constVar = new Variable(variable, constVal);
Variable constVar = Variable.createConstant(variable, constVal);
constVar.getComments().addAll(constVarVal.getAssignment().getComments());
scope.add(constVar);
constAliases.put(constRef, constVar.getRef());

View File

@ -93,7 +93,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
// Create a new root - and roll around again
ProgramScope rootScope = getScope();
String localName = getRootName(constantVars);
Variable newRootConstant = new Variable(localName, SymbolType.STRING, new ArraySpec(), rootScope, segmentData, constString);
Variable newRootConstant = Variable.createConstant(localName, SymbolType.STRING, rootScope, new ArraySpec(), constString, segmentData);
rootScope.add(newRootConstant);
rootConstant = newRootConstant;
}

View File

@ -133,7 +133,7 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
// Constant not found - create it
Variable memberDef = structDefinition.getMember(memberName);
long memberByteOffset = structDefinition.getMemberByteOffset(memberDef, programScope);
memberOffsetConstant = new Variable(typeConstName, SymbolType.BYTE, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE));
memberOffsetConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(memberOffsetConstant);
}
return memberOffsetConstant.getConstantRef();

View File

@ -231,7 +231,7 @@ public class Unroller {
if(definedVarRef.isIntermediate()) {
Scope scope = definedVar.getScope();
String name = scope.allocateIntermediateVariableName();
newVar = new Variable(name, scope, definedVar);
newVar = Variable.createCopy(name, scope, definedVar);
scope.add(newVar);
} else if(definedVarRef.isVersion()) {
newVar = (definedVar).getVersionOf().createVersion();