1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-10-04 20:55:00 +00:00

Working on new VariableBuilder.

This commit is contained in:
jespergravgaard 2019-12-16 22:51:59 +01:00
parent 3b297ef85d
commit 17a9e90f2b
18 changed files with 296 additions and 137 deletions

View File

@ -90,7 +90,7 @@ public class AsmFragmentInstance {
String constantValueAsm = AsmFormat.getAsmConstant(program, constantVar.getConstantRef(), 99, codeScopeRef);
boolean constantValueZp = SymbolType.BYTE.equals(constantVar.getType());
if(!constantValueZp) {
constantValueZp = isConstantValueZp(constantVar.getConstantValue());
constantValueZp = isConstantValueZp(constantVar.getInitValue());
}
return new AsmParameter(constantValueAsm, constantValueZp);
} else if(boundValue instanceof ConstantValue) {
@ -127,7 +127,7 @@ public class AsmFragmentInstance {
}
if(boundConst instanceof ConstantRef) {
Variable reffedConstant = program.getScope().getConstant((ConstantRef) boundConst);
return isConstantValueZp(reffedConstant.getConstantValue());
return isConstantValueZp(reffedConstant.getInitValue());
}
if(boundConst instanceof ConstantCastValue) {
SymbolType toType = ((ConstantCastValue) boundConst).getToType();

View File

@ -0,0 +1,233 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.ScopeRef;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.List;
/**
* Used for creating a {@link Variable} with the right properties based on the declaration incl. all directives and configuration.
*
* Holds information about the variable while it is being built.
*/
public class VariableBuilder {
/** The scope of the variable. */
private Scope scope;
/** The variable is a function parameter declaration. */
private boolean isParameter;
/** The type of the variable. */
private SymbolType type;
/** Tye variable is an array. */
private boolean isArray;
/** A compile-time constant (const keyword and no volatile keyword and initValue is a compile-time constant) */
private boolean isConstant;
/** Declared as global private (static keyword and global variable) */
private boolean isPrivate;
/** Declared as local permanent (static keyword and local variable) */
private boolean isPermanent;
/** Declared as volatile (volatile keyword) */
private boolean isVolatile;
/** Declared as no-modify (const keyword) */
private boolean isNoModify;
/** Declared as optimize (register keyword) */
private boolean isOptimize;
/** Declared as pointer to volatile (volatile* keyword) */
private boolean isToVolatile;
/** Declared as pointer to no-modify (const* keyword) */
private boolean isToNoModify;
/**
* Is the type is a simple integer type.
* @return True if the type is a simple integer type.
*/
boolean isTypeInteger() {
return SymbolType.isInteger(type) || SymbolType.BOOLEAN.equals(type);
}
/**
* Is the type is a pointer type.
* @return True if the type is a pointer type.
*/
boolean isTypePointer() {
return type instanceof SymbolTypePointer;
}
/**
* Is the type is a struct type.
* @return True if the type is a struct type.
*/
boolean isTypeStruct() {
return type instanceof SymbolTypeStruct;
}
/** The different scopes deciding directive defaults. */
public enum DirectiveScope {
GLOBAL, LOCAL, PARAMETER, MEMBER;
private static DirectiveScope getFor(Scope scope, boolean isParameter) {
if(isParameter) {
return PARAMETER;
}
if(ScopeRef.ROOT.equals(scope.getRef())) {
return GLOBAL;
} else if(scope instanceof Procedure) {
return LOCAL;
} else if(scope instanceof StructDefinition) {
return MEMBER;
} else if(scope instanceof BlockScope) {
return getFor(scope.getScope(), false);
} else {
throw new InternalError("Scope type not handled " + scope);
}
}
}
public VariableBuilder() {
}
/**
* Find the variable kind for a declared variable (not used for intermediates or PHI-versions)
*
* @param type The type of the variable
* @param scope The scope
* @param isParameter true if the variable is a procedure parameter
* @param sourceDirectives The directives in the source code
* @param source The source line (for exceptions)
* @return The variable kind
*/
public Variable.Kind getKind(SymbolType type, Scope scope, boolean isParameter, boolean isArray, List<Directive> sourceDirectives, StatementSource source) {
// Look for const without volatile
if(hasDirective(Directive.Const.class, sourceDirectives))
if(!hasDirective(Directive.Volatile.class, sourceDirectives))
return Variable.Kind.CONSTANT;
// Look for array (which is implicitly const
//DirectiveType directiveType = DirectiveType.getFor(type);
if(isArray)
return Variable.Kind.CONSTANT;
// It is not a constant - determine PHI_MASTER vs LOAD_STORE
if(hasDirective(Directive.FormSsa.class, sourceDirectives))
return Variable.Kind.PHI_MASTER;
if(hasDirective(Directive.FormMa.class, sourceDirectives))
return Variable.Kind.LOAD_STORE;
if(hasDirective(Directive.Register.class, sourceDirectives))
return Variable.Kind.PHI_MASTER;
if(hasDirective(Directive.NamedRegister.class, sourceDirectives))
return Variable.Kind.PHI_MASTER;
// TODO: Add strategy for selecting LOAD_STORE for global vars
return Variable.Kind.PHI_MASTER;
}
/**
* Applies directives to a variable.
*
* @param variable The variable to apply directives to
* @param sourceDirectives The directives found in the source code
* @param source The source line (for exceptions)
*/
public void applyDirectives(Variable variable, boolean isParameter, boolean isArray, List<Directive> sourceDirectives, StatementSource source) {
if(hasDirective(Directive.Const.class, sourceDirectives))
variable.setDeclaredConst(true);
if(isArray)
variable.setDeclaredConst(true);
if(hasDirective(Directive.Volatile.class, sourceDirectives))
variable.setDeclaredVolatile(true);
if(hasDirective(Directive.Export.class, sourceDirectives))
variable.setDeclaredExport(true);
if(hasDirective(Directive.Register.class, sourceDirectives)) {
variable.setMemoryArea(Variable.MemoryArea.ZEROPAGE_MEMORY);
variable.setDeclaredAsRegister(true);
}
if(isArray)
variable.setMemoryArea(Variable.MemoryArea.MAIN_MEMORY);
if(hasDirective(Directive.MemZp.class, sourceDirectives))
variable.setMemoryArea(Variable.MemoryArea.ZEROPAGE_MEMORY);
if(hasDirective(Directive.MemMain.class, sourceDirectives))
variable.setMemoryArea(Variable.MemoryArea.MAIN_MEMORY);
Directive.Address addressDirective = findDirective(Directive.Address.class, sourceDirectives);
if(addressDirective != null) {
Variable.MemoryArea memoryArea = (addressDirective.address < 0x100) ? Variable.MemoryArea.ZEROPAGE_MEMORY : Variable.MemoryArea.MAIN_MEMORY;
if(Variable.MemoryArea.ZEROPAGE_MEMORY.equals(memoryArea)) {
variable.setMemoryArea(Variable.MemoryArea.ZEROPAGE_MEMORY);
Registers.Register register = new Registers.RegisterZpMem(addressDirective.address.intValue(), -1, true);
variable.setDeclaredRegister(register);
} else {
variable.setMemoryArea(Variable.MemoryArea.MAIN_MEMORY);
Registers.Register register = new Registers.RegisterMainMem((VariableRef) variable.getRef(), -1, addressDirective.address);
variable.setDeclaredRegister(register);
}
}
Directive.NamedRegister registerDirective = findDirective(Directive.NamedRegister.class, sourceDirectives);
if(registerDirective != null) {
variable.setDeclaredAsRegister(true);
Registers.Register register = Registers.getRegister(registerDirective.name);
if(register == null) {
throw new CompileError("Error! Unknown register " + registerDirective.name, source);
}
variable.setDeclaredRegister(register);
}
Directive.Align alignDirective = findDirective(Directive.Align.class, sourceDirectives);
if(alignDirective != null) {
if(isArray) {
variable.setDeclaredAlignment(alignDirective.alignment);
} else {
throw new CompileError("Error! Cannot align variable that is not a string or an array " + variable.toString(), source);
}
}
// TODO: Add strategy for selecting main memory for non-pointer local variables
//DirectiveScope directiveScope = DirectiveScope.getFor(lValue.getScope(), isParameter);
}
/**
* Examines whether a specific directive is present in the source
*
* @param directiveClass The class of the type to look for
* @param directives The list of directives to search
* @param <DirectiveClass> The class of the type to look for
* @return true if the directive if found. false otherwise.
*/
private <DirectiveClass extends Directive> boolean hasDirective(Class<DirectiveClass> directiveClass, List<Directive> directives) {
return findDirective(directiveClass, directives) != null;
}
/**
* Look for a specific directive type in a list of directives
*
* @param directiveClass The class of the type to look for
* @param directives The list of directives to search
* @param <DirectiveClass> The class of the type to look for
* @return The directive if found. null if not found.
*/
private <DirectiveClass extends Directive> DirectiveClass findDirective(Class<DirectiveClass> directiveClass, List<Directive> directives) {
if(directives == null) return null;
for(Directive directive : directives) {
if(directiveClass.isInstance(directive)) {
return (DirectiveClass) directive;
}
}
// Not found!
return null;
}
}

View File

@ -11,61 +11,11 @@ import dk.camelot64.kickc.model.values.VariableRef;
import java.util.List;
/**
* The parser directive context is used for determining which directives to apply to a variable.
* Used for creating {@link Variable}s with the right properties based on all their directives
*/
public class DirectiveParserContext {
public class VariableBuilderContext {
/** The different scopes deciding directive defaults. */
public enum DirectiveScope {
GLOBAL, LOCAL, PARAMETER, MEMBER;
private static DirectiveScope getFor(Scope scope, boolean isParameter) {
if(isParameter) {
return PARAMETER;
}
if(ScopeRef.ROOT.equals(scope.getRef())) {
return GLOBAL;
} else if(scope instanceof Procedure) {
return LOCAL;
} else if(scope instanceof StructDefinition) {
return MEMBER;
} else if(scope instanceof BlockScope) {
return getFor(scope.getScope(), false);
} else {
throw new InternalError("Scope type not handled " + scope);
}
}
}
/** The different types deciding directive defaults. */
public enum DirectiveType {
INTEGER, POINTER, ARRAY, STRUCT;
/**
* Get a directive type from a variable type.
*
* @param type The variable type
* @return The directive type
*/
public static DirectiveType getFor(SymbolType type) {
if(SymbolType.isInteger(type)) {
return INTEGER;
} else if(SymbolType.BOOLEAN.equals(type)) {
return INTEGER;
} else if(SymbolType.STRING.equals(type)) {
return ARRAY;
} else if(type instanceof SymbolTypePointer) {
return POINTER;
} else if(type instanceof SymbolTypeStruct) {
return STRUCT;
} else {
throw new InternalError("Variable type not handled " + type);
}
}
}
public DirectiveParserContext() {
public VariableBuilderContext() {
}
/**
@ -84,7 +34,6 @@ public class DirectiveParserContext {
if(!hasDirective(Directive.Volatile.class, sourceDirectives))
return Variable.Kind.CONSTANT;
// Look for array (which is implicitly const
DirectiveType directiveType = DirectiveType.getFor(type);
if(isArray)
return Variable.Kind.CONSTANT;
// It is not a constant - determine PHI_MASTER vs LOAD_STORE
@ -108,7 +57,6 @@ public class DirectiveParserContext {
* @param source The source line (for exceptions)
*/
public void applyDirectives(Variable lValue, boolean isParameter, boolean isArray, List<Directive> sourceDirectives, StatementSource source) {
DirectiveType directiveType = DirectiveType.getFor(lValue.getType());
if(hasDirective(Directive.Const.class, sourceDirectives))
lValue.setDeclaredConst(true);
if(isArray)
@ -159,10 +107,7 @@ public class DirectiveParserContext {
throw new CompileError("Error! Cannot align variable that is not a string or an array " + lValue.toString(), source);
}
}
// TODO: Add strategy for selecting main memory for non-pointer local variables
//DirectiveScope directiveScope = DirectiveScope.getFor(lValue.getScope(), isParameter);
}
/**

View File

@ -608,21 +608,22 @@ public interface ProgramValue {
}
class ProgramValueConstantVar implements ProgramValue {
/** The initial value of a variable. */
class ProgramValueInitValue implements ProgramValue {
private final Variable constantVar;
ProgramValueConstantVar(Variable constantVar) {
ProgramValueInitValue(Variable constantVar) {
this.constantVar = constantVar;
}
@Override
public Value get() {
return constantVar.getConstantValue();
return constantVar.getInitValue();
}
@Override
public void set(Value val) {
constantVar.setConstantValue((ConstantValue) val);
constantVar.setInitValue((ConstantValue) val);
}
}

View File

@ -48,8 +48,8 @@ public class ProgramValueIterator {
* @param programValueHandler The programValueHandler to execute
*/
public static void execute(Variable variable, ProgramValueHandler programValueHandler) {
if(variable.isKindConstant()) {
execute(new ProgramValue.ProgramValueConstantVar(variable), programValueHandler, null, null, null);
if(variable.getInitValue()!=null) {
execute(new ProgramValue.ProgramValueInitValue(variable), programValueHandler, null, null, null);
}
if(variable.isArray()) {
execute(new ProgramValue.ProgramValueArraySize(variable), programValueHandler, null, null, null);

View File

@ -394,8 +394,8 @@ public abstract class Scope implements Symbol, Serializable {
}
}
}
if(symVar.isKindConstant() && symVar.getConstantValue()!=null) {
res.append(" = " + symVar.getConstantValue().toString(program));
if(symVar.getInitValue()!=null) {
res.append(" = " + symVar.getInitValue().toString(program));
}
res.append("\n");
}

View File

@ -18,8 +18,8 @@ import java.util.Objects;
/** A Variable symbol (can either be a runtime variable or a compile-time constant).
* <p>
* Array values are implemented as {@link Kind#CONSTANT}s with the array data in {@link #getConstantValue()} and the declared size in {@link #getArraySpec()}.
* Struct values are implemented as {@link Kind#LOAD_STORE}s with the initial data in {@link #getConstantValue()} and the strategy for accessing it in {@link #getStructStrategy()}.
* Array values are implemented as {@link Kind#CONSTANT}s with the array data in {@link #getInitValue()} and the declared size in {@link #getArraySpec()}.
* Struct values are implemented as {@link Kind#LOAD_STORE}s with the initial data in {@link #getInitValue()} or as {@link Kind#PHI_MASTER}s that will be unwound to member variables during compilation.
* </p>
**/
public class Variable implements Symbol {
@ -93,23 +93,12 @@ public class Variable implements Symbol {
/** The data segment to put the variable into (if it is allocated in memory). [Only variables stored in memory and arrays] */
private String dataSegment;
/** The constant value if the variable is a constant. Null otherwise. [Only constants] */
private ConstantValue constantValue;
/** The initial compiletime-value of the variable. Null if no initial value present. [Constants, Arrays, global/local-static loadstore-variables ] */
private ConstantValue initValue;
/** Non-null if the variable is an array. [Only constants that are arrays] */
private ArraySpec arraySpec;
/** Strategy for handling a struct variable during compilation. */
public enum StructStrategy {
/** The struct is stored in memory and accessed using OFFSET's */
CSTANDARD,
/** The struct is unwound and handled as if each member was a separate variable. */
UNWINDING
}
/** Non-null if the variable is a struct value. Strategy for how to handle the struct value. [Only constants that are structs] */
private StructStrategy structStrategy;
/** The number of the next version (only used for PHI masters) [Only PHI masters] */
private Integer nextPhiVersionNumber;
@ -126,9 +115,9 @@ public class Variable implements Symbol {
* @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)
* @param initValue The constant value of the variable (if it is constant)
*/
private Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ArraySpec arraySpec, StructStrategy structStrategy, ConstantValue constantValue) {
private Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ArraySpec arraySpec, ConstantValue initValue) {
this.name = name;
this.kind = kind;
if(Kind.PHI_MASTER.equals(kind))
@ -136,8 +125,7 @@ public class Variable implements Symbol {
this.type = type;
this.scope = scope;
this.arraySpec = arraySpec;
this.structStrategy = structStrategy;
this.constantValue = constantValue;
this.initValue = initValue;
this.dataSegment = dataSegment;
this.memoryArea = memoryArea;
this.comments = new ArrayList<>();
@ -153,7 +141,7 @@ public class Variable implements Symbol {
* @return The new intermediate variable
*/
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, null);
return new Variable(name, Kind.INTERMEDIATE, SymbolType.VAR, scope, MemoryArea.ZEROPAGE_MEMORY, dataSegment, null, null);
}
/**
@ -167,7 +155,7 @@ public class Variable implements Symbol {
* @return The new PHI-master variable
*/
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, null);
return new Variable(name, Kind.LOAD_STORE, type, scope, memoryArea, dataSegment, null, null);
}
/**
@ -181,7 +169,7 @@ public class Variable implements Symbol {
* @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, null);
return new Variable(name, Kind.PHI_MASTER, type, scope, memoryArea, dataSegment, null, null);
}
/**
@ -193,7 +181,7 @@ public class Variable implements Symbol {
public static Variable createPhiVersion(Variable phiMaster, int versionNum) {
if(!phiMaster.isKindPhiMaster())
throw new InternalError("Cannot version non-PHI variable " + phiMaster.toString());
Variable version = new Variable(phiMaster.getName() + "#" + versionNum, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment(), phiMaster.getArraySpec(), phiMaster.getStructStrategy(), null);
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());
@ -227,7 +215,7 @@ public class Variable implements Symbol {
* @param dataSegment The data segment (in main memory)
*/
public static Variable createConstant(String name, SymbolType type, Scope scope, ArraySpec arraySpec, ConstantValue constantValue, String dataSegment) {
return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, arraySpec, null, constantValue);
return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, arraySpec, constantValue);
}
/**
@ -257,7 +245,7 @@ public class Variable implements Symbol {
* @param original The original variable
*/
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.getStructStrategy(), original.getConstantValue());
Variable copy = new Variable(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment(), original.getArraySpec(), original.getInitValue());
copy.setDeclaredAlignment(original.getDeclaredAlignment());
copy.setDeclaredAsRegister(original.isDeclaredAsRegister());
copy.setDeclaredConst(original.isDeclaredConst());
@ -283,13 +271,13 @@ public class Variable implements Symbol {
Variable memberVariable;
if(isParameter && memberDefinition.isArray()) {
// Array struct members are converted to pointers when unwound (use same kind as the struct variable)
memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), null, null, null);
memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), null, null);
} else if(memberDefinition.isKindConstant()) {
// Constant members are unwound as constants
memberVariable = new Variable(name, Kind.CONSTANT, memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getArraySpec(), memberDefinition.getStructStrategy(), memberDefinition.getConstantValue());
memberVariable = new Variable(name, Kind.CONSTANT, memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getArraySpec(), memberDefinition.getInitValue());
} else {
// For others the kind is preserved from the member definition
memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getArraySpec(), memberDefinition.getStructStrategy(), memberDefinition.getConstantValue());
memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getArraySpec(), memberDefinition.getInitValue());
}
memberVariable.setDeclaredVolatile(structVar.isDeclaredVolatile());
memberVariable.setInferredVolatile(structVar.isInferredVolatile());
@ -395,14 +383,6 @@ public class Variable implements Symbol {
return type instanceof SymbolTypeStruct;
}
public StructStrategy getStructStrategy() {
return structStrategy;
}
public void setStructStrategy(StructStrategy structStrategy) {
this.structStrategy = structStrategy;
}
public Registers.Register getAllocation() {
return allocation;
}
@ -411,12 +391,12 @@ public class Variable implements Symbol {
this.allocation = allocation;
}
public ConstantValue getConstantValue() {
return constantValue;
public ConstantValue getInitValue() {
return initValue;
}
public void setConstantValue(ConstantValue value) {
this.constantValue = value;
public void setInitValue(ConstantValue value) {
this.initValue = value;
}
public String getDataSegment() {
@ -573,9 +553,9 @@ public class Variable implements Symbol {
public String toString(Program program) {
return new StringBuilder()
.append("(")
.append((constantValue != null) ? "const " : "")
.append((initValue != null) ? "const " : "")
.append(getType().getTypeName())
.append((constantValue == null && isKindIntermediate()) ? "~" : "")
.append((initValue == null && isKindIntermediate()) ? "~" : "")
.append(") ")
.append(getFullName()).toString();
}

View File

@ -23,7 +23,7 @@ public class ConstantRef extends SymbolVariableRef implements ConstantValue {
@Override
public ConstantLiteral calculateLiteral(ProgramScope scope) {
Variable constantVar = scope.getConstant(this);
ConstantValue constantVarValue = constantVar.getConstantValue();
ConstantValue constantVarValue = constantVar.getInitValue();
return constantVarValue.calculateLiteral(scope);
}
}

View File

@ -48,7 +48,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** The memory area used by default for variables. */
private Variable.MemoryArea defaultMemoryArea;
/** Context used for adding directives to variables. */
private DirectiveParserContext directiveContext;
private VariableBuilderContext directiveContext;
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program) {
this.cParser = cParser;
@ -57,7 +57,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.sequence = program.getStatementSequence();
this.scopeStack = new Stack<>();
this.defaultMemoryArea = Variable.MemoryArea.ZEROPAGE_MEMORY;
this.directiveContext = new DirectiveParserContext();
this.directiveContext = new VariableBuilderContext();
scopeStack.push(program.getScope());
}
@ -1551,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(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, null, member.getConstantValue(), currentDataSegment));
parentScope.add(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, null, member.getInitValue(), currentDataSegment));
}
return SymbolType.BYTE;
} catch(CompileError e) {
@ -1576,7 +1576,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
enumValue = new ConstantInteger(0L, SymbolType.BYTE);
} else {
Variable prevEnumMember = values.get(values.size() - 1);
ConstantValue prevValue = prevEnumMember.getConstantValue();
ConstantValue prevValue = prevEnumMember.getInitValue();
if(prevValue instanceof ConstantInteger) {
enumValue = new ConstantInteger(((ConstantInteger) prevValue).getInteger() + 1, SymbolType.BYTE);
} else {

View File

@ -63,7 +63,7 @@ public class Pass2ArrayInStructInlining extends Pass2SsaOptimization {
if(constantValue.getType(getProgram().getScope()).equals(SymbolType.STRING)) {
if(constantValue instanceof ConstantRef) {
Variable constantStringVar = getScope().getConstant((ConstantRef) constantValue);
inline.put((ConstantRef) constantValue, constantStringVar.getConstantValue());
inline.put((ConstantRef) constantValue, constantStringVar.getInitValue());
}
}
}

View File

@ -83,7 +83,7 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization
private ProcedureRef findConstProcedure(RValue procedurePointer) {
if(procedurePointer instanceof ConstantRef) {
Variable constant = getScope().getConstant((ConstantRef) procedurePointer);
return findConstProcedure(constant.getConstantValue());
return findConstProcedure(constant.getInitValue());
} else if(procedurePointer instanceof ConstantSymbolPointer) {
ConstantSymbolPointer pointer = (ConstantSymbolPointer) procedurePointer;
if(pointer.getToSymbol() instanceof ProcedureRef) {

View File

@ -75,7 +75,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
constVar.getComments().addAll(constVarVal.getAssignment().getComments());
scope.add(constVar);
constAliases.put(constRef, constVar.getRef());
getLog().append("Constant " + constVar.toString(getProgram()) + " = " + constVar.getConstantValue());
getLog().append("Constant " + constVar.toString(getProgram()) + " = " + constVar.getInitValue());
}
// Remove assignments to constants in the code
removeAssignments(getGraph(), constants.keySet());

View File

@ -92,8 +92,8 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
Collection<Variable> allConstants = getProgram().getScope().getAllConstants(true);
for(Variable constant : allConstants) {
if(constant.getRef().isIntermediate()) {
if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getConstantValue() instanceof ConstantArray)) {
unnamed.put(constant.getConstantRef(), constant.getConstantValue());
if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getInitValue() instanceof ConstantArray)) {
unnamed.put(constant.getConstantRef(), constant.getInitValue());
}
}
}
@ -110,14 +110,14 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
ProgramScope programScope = getProgram().getScope();
Collection<Variable> allConstants = programScope.getAllConstants(true);
for(Variable constant : allConstants) {
ConstantValue constantValue = constant.getConstantValue();
ConstantValue constantValue = constant.getInitValue();
if(constantValue instanceof ConstantRef) {
if(((ConstantRef) constantValue).isIntermediate()) {
// The value is an intermediate constant - replace all uses of the intermediate with uses of the referrer instead.
aliases.put((ConstantRef) constant.getConstantValue(), constant.getConstantRef());
constant.setConstantValue(programScope.getConstant((ConstantRef) constantValue).getConstantValue());
aliases.put((ConstantRef) constant.getInitValue(), constant.getConstantRef());
constant.setInitValue(programScope.getConstant((ConstantRef) constantValue).getInitValue());
} else {
aliases.put(constant.getConstantRef(), constant.getConstantValue());
aliases.put(constant.getConstantRef(), constant.getInitValue());
}
}
}
@ -142,13 +142,13 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
Collection<Symbol> scopeSymbols = constant.getScope().getAllSymbols();
for(Symbol symbol : scopeSymbols) {
if(symbol.getRef().isVersion() && symbol.getRef().getFullNameUnversioned().equals(baseName)) {
ConstantValue value = constant.getConstantValue();
ConstantValue value = constant.getInitValue();
if(symbol instanceof Variable && ((Variable) symbol).isVariable()) {
aliases.put(constant.getConstantRef(), value);
getLog().append("Inlining constant with var siblings " + constant);
break;
} else if(symbol instanceof Variable && ((Variable) symbol).isKindConstant()) {
ConstantValue otherValue = ((Variable) symbol).getConstantValue();
ConstantValue otherValue = ((Variable) symbol).getInitValue();
if(!otherValue.equals(value) && !(value instanceof ConstantString) && !(value instanceof ConstantArray) && !(otherValue instanceof ConstantRef)) {
aliases.put(constant.getConstantRef(), value);
getLog().append("Inlining constant with different constant siblings " + constant);

View File

@ -36,7 +36,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
// Build a map with all constant strings
Map<ConstantString, List<Variable>> constantStringMap = new LinkedHashMap<>();
for(Variable constVar : getScope().getAllConstants(true)) {
ConstantValue constVal = constVar.getConstantValue();
ConstantValue constVal = constVar.getInitValue();
if(constVal instanceof ConstantString) {
ConstantString constString = (ConstantString) constVal;
List<Variable> constantVars = constantStringMap.computeIfAbsent(constString, k -> new ArrayList<>());
@ -101,7 +101,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
// Modify all other constants to be references to the root constant
for(Variable constantVar : constantVars) {
if(!constantVar.equals(rootConstant)) {
constantVar.setConstantValue(new ConstantRef(rootConstant));
constantVar.setInitValue(new ConstantRef(rootConstant));
modified = true;
}
}

View File

@ -30,7 +30,7 @@ public class Pass3AssertArrayLengths extends Pass2SsaAssertion {
}
Integer declaredSizeInt = ((ConstantInteger) declaredSizeVal).getInteger().intValue();
// A constant size was found - Check that a value with the same size is present
ConstantValue constantValue = constantVar.getConstantValue();
ConstantValue constantValue = constantVar.getInitValue();
if(constantValue == null) {
throw new CompileError("Error! Array with a size not initialized " + constantVar.toString(getProgram()));
} else if(constantValue instanceof ConstantArrayFilled) {

View File

@ -300,7 +300,7 @@ public class Pass4CodeGeneration {
}
private boolean hasData(Variable constantVar) {
ConstantValue constantValue = constantVar.getConstantValue();
ConstantValue constantValue = constantVar.getInitValue();
if(constantValue instanceof ConstantArray) {
return true;
} else {
@ -400,9 +400,9 @@ public class Pass4CodeGeneration {
// Add any comments
generateComments(asm, constantVar.getComments());
// Ensure encoding is good
ensureEncoding(asm, constantVar.getConstantValue());
ensureEncoding(asm, constantVar.getInitValue());
// Find the constant value calculation
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getConstantValue(), 99, scopeRef);
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
if(constantVar.getType() instanceof SymbolTypePointer) {
// Must use a label for pointers
asm.addLabelDecl(AsmFormat.asmFix(asmName), asmConstant);
@ -482,7 +482,7 @@ public class Pass4CodeGeneration {
String alignment = AsmFormat.getAsmNumber(declaredAlignment);
asm.addDataAlignment(alignment);
}
ConstantValue constantValue = constantVar.getConstantValue();
ConstantValue constantValue = constantVar.getInitValue();
if(constantValue instanceof ConstantArray || constantValue instanceof ConstantString) {
AsmDataChunk asmDataChunk = new AsmDataChunk();
addChunkData(asmDataChunk, constantValue, constantVar.getType(), constantVar.getArraySpec(), scopeRef);

View File

@ -116,7 +116,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
}
}
for(Variable constantVar : scope.getAllConstants(false)) {
Registers.Register allocation = new Registers.RegisterConstant(constantVar.getConstantValue());
Registers.Register allocation = new Registers.RegisterConstant(constantVar.getInitValue());
shortenAsmName(shortNames, constantVar, allocation);
}
}

View File

@ -78,9 +78,9 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType());
programValue.set(new ConstantBinary((ConstantValue) arraySize, Operators.MULTIPLY, sizeOfConstantVar));
modified.set(true);
} else if(constant.getConstantValue() instanceof ConstantArrayList) {
} else if(constant.getInitValue() instanceof ConstantArrayList) {
getLog().append("Resolving array sizeof() " + unary.toString(getProgram()));
int size = ((ConstantArrayList) constant.getConstantValue()).getElements().size();
int size = ((ConstantArrayList) constant.getInitValue()).getElements().size();
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType());
programValue.set(new ConstantBinary(new ConstantInteger((long) size), Operators.MULTIPLY, sizeOfConstantVar));
modified.set(true);
@ -88,7 +88,7 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
// Try to calculate the literal to check if it is a string
ConstantLiteral stringLiteral = null;
try {
stringLiteral = constant.getConstantValue().calculateLiteral(getProgram().getScope());
stringLiteral = constant.getInitValue().calculateLiteral(getProgram().getScope());
} catch(ConstantNotLiteral e) {
// Ignore
}