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;
@ -14,12 +15,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/** A Variable symbol (can either be a runtime variable or a compile-time constant)*/
/** A Variable symbol (can either be a runtime variable or a compile-time constant) */
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>
@ -33,7 +34,7 @@ public class Variable implements Symbol {
PHI_MASTER, PHI_VERSION, INTERMEDIATE, LOAD_STORE, CONSTANT
}
/** The kind of the variable. */
/** The kind of the variable. */
private Kind kind;
/** The local name of the variable. [ALL] */
@ -42,13 +43,13 @@ public class Variable implements Symbol {
/** Full name of variable including scope (scope::name or name) [ALL] */
private String fullName;
/** A short name used for the variable in ASM code. If possible variable names of variables are shortened in ASM code. This is possible, when several versions of the var use the same register. [ALL]*/
/** A short name used for the variable in ASM code. If possible variable names of variables are shortened in ASM code. This is possible, when several versions of the var use the same register. [ALL] */
private String asmName;
/** The scope containing the variable. [ALL] */
private Scope scope;
/** The type of the variable. VAR means the type is unknown, and has not been inferred yet. [ALL]*/
/** The type of the variable. VAR means the type is unknown, and has not been inferred yet. [ALL] */
private SymbolType type;
/** Specifies that the variable must be aligned in memory. Only allowed for arrays & strings. [Only Variables in memory and arrays] */
@ -60,7 +61,7 @@ public class Variable implements Symbol {
/** Specifies that the variable is declared as const */
private boolean declaredConst;
/** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only Variables]*/
/** 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;
/** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only variables] TODO: Remove this */
@ -84,7 +85,7 @@ public class Variable implements Symbol {
/** The constant value if the variable is a constant. Null otherwise. [Only constants] */
private ConstantValue constantValue;
/** Non-null if the variable is an array. [Only constants that are arrays]*/
/** Non-null if the variable is an array. [Only constants that are arrays] */
private ArraySpec arraySpec;
/** The number of the next version (only used for PHI masters) [Only PHI masters] */
@ -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 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;
}
@ -271,7 +335,7 @@ public class Variable implements Symbol {
}
public boolean isArray() {
return arraySpec!=null;
return arraySpec != null;
}
public ArraySpec getArraySpec() {

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();