1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-14 09:30:57 +00:00

Merge remote-tracking branch 'origin/master' into 121-pointer-to-function

This commit is contained in:
jespergravgaard 2021-04-12 21:47:35 +02:00
commit e78cd72417
21 changed files with 134 additions and 156 deletions

View File

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

View File

@ -16,7 +16,7 @@ public class Initializers {
/** /**
* Create a statement that initializes a variable with the default (zero) value. The statement has to be added to the program by the caller. * Create a statement that initializes a variable with the default (zero) value. The statement has to be added to the program by the caller.
* *
* @param type The type of the variable * @param typeSpec The type of the variable
* @param statementSource The source line * @param statementSource The source line
* @return The new statement * @return The new statement
*/ */
@ -32,15 +32,15 @@ public class Initializers {
return new StructZero(typeStruct); return new StructZero(typeStruct);
} else if(typeSpec.getType() instanceof SymbolTypePointer) { } else if(typeSpec.getType() instanceof SymbolTypePointer) {
SymbolTypePointer typePointer = (SymbolTypePointer) typeSpec.getType(); SymbolTypePointer typePointer = (SymbolTypePointer) typeSpec.getType();
if(typeSpec.getArraySpec() == null) { if(typePointer.getArraySpec() == null) {
// Add an zero value initializer // Add an zero value initializer
return new ConstantPointer(0L, typePointer.getElementType()); return new ConstantPointer(0L, typePointer.getElementType());
} else { } else {
// Add an zero-filled array initializer // Add an zero-filled array initializer
if(typeSpec.getArraySpec().getArraySize() == null) { if(typePointer.getArraySpec().getArraySize() == null) {
throw new CompileError("Array has no declared size.", statementSource); throw new CompileError("Array has no declared size.", statementSource);
} }
return new ConstantArrayFilled(typePointer.getElementType(), typeSpec.getArraySpec().getArraySize()); return new ConstantArrayFilled(typePointer.getElementType(), typePointer.getArraySpec().getArraySize());
} }
} else { } else {
throw new CompileError("Default initializer not implemented for type " + typeSpec.getType().getTypeName(), statementSource); throw new CompileError("Default initializer not implemented for type " + typeSpec.getType().getTypeName(), statementSource);
@ -52,20 +52,14 @@ public class Initializers {
SymbolType type; SymbolType type;
ArraySpec arraySpec; public ValueTypeSpec(SymbolType type) {
public ValueTypeSpec(SymbolType type, ArraySpec arraySpec) {
this.type = type; this.type = type;
this.arraySpec = arraySpec;
} }
public SymbolType getType() { public SymbolType getType() {
return type; return type;
} }
public ArraySpec getArraySpec() {
return arraySpec;
}
} }
@ -88,16 +82,16 @@ public class Initializers {
final CastValue castValue = (CastValue) initValue; final CastValue castValue = (CastValue) initValue;
if(castValue.getValue() instanceof ValueList && castValue.getToType() instanceof SymbolTypeStruct) { if(castValue.getValue() instanceof ValueList && castValue.getToType() instanceof SymbolTypeStruct) {
final SymbolType toType = castValue.getToType(); final SymbolType toType = castValue.getToType();
final RValue constantSub = constantify(castValue.getValue(), new ValueTypeSpec(toType, null), program, source); final RValue constantSub = constantify(castValue.getValue(), new ValueTypeSpec(toType), program, source);
if(constantSub instanceof ConstantValue) { if(constantSub instanceof ConstantValue) {
return new ConstantCastValue(toType, (ConstantValue) constantSub); return new ConstantCastValue(toType, (ConstantValue) constantSub);
} }
} }
} else if(initValue instanceof ValueList) { } else if(initValue instanceof ValueList) {
ValueList initList = (ValueList) initValue; ValueList initList = (ValueList) initValue;
if(typeSpec.getType() instanceof SymbolTypePointer && typeSpec.getArraySpec() != null) { if(typeSpec.getType() instanceof SymbolTypePointer && ((SymbolTypePointer)typeSpec.getType()).getArraySpec() != null) {
// Type is an array // Type is an array
initValue = constantifyArray(initList, (SymbolTypePointer) typeSpec.getType(), typeSpec.getArraySpec(), program, source); initValue = constantifyArray(initList, (SymbolTypePointer) typeSpec.getType(), program, source);
} else if(typeSpec.getType() instanceof SymbolTypeStruct) { } else if(typeSpec.getType() instanceof SymbolTypeStruct) {
// Type is a struct // Type is a struct
initValue = constantifyStruct(initList, (SymbolTypeStruct) typeSpec.getType(), program, source); initValue = constantifyStruct(initList, (SymbolTypeStruct) typeSpec.getType(), program, source);
@ -145,7 +139,7 @@ public class Initializers {
boolean allConst = true; boolean allConst = true;
List<RValue> constantifiedList = new ArrayList<>(); List<RValue> constantifiedList = new ArrayList<>();
for(RValue elementValue : valueList.getList()) { for(RValue elementValue : valueList.getList()) {
RValue constantifiedElement = constantify(elementValue, new ValueTypeSpec(SymbolType.BYTE, null), program, source); RValue constantifiedElement = constantify(elementValue, new ValueTypeSpec(SymbolType.BYTE), program, source);
constantifiedList.add(constantifiedElement); constantifiedList.add(constantifiedElement);
if(!(constantifiedElement instanceof ConstantValue)) if(!(constantifiedElement instanceof ConstantValue))
allConst = false; allConst = false;
@ -163,7 +157,7 @@ public class Initializers {
boolean allConst = true; boolean allConst = true;
List<RValue> constantifiedList = new ArrayList<>(); List<RValue> constantifiedList = new ArrayList<>();
for(RValue elementValue : valueList.getList()) { for(RValue elementValue : valueList.getList()) {
RValue constantifiedElement = constantify(elementValue, new ValueTypeSpec(SymbolType.WORD, null), program, source); RValue constantifiedElement = constantify(elementValue, new ValueTypeSpec(SymbolType.WORD), program, source);
constantifiedList.add(constantifiedElement); constantifiedList.add(constantifiedElement);
if(!(constantifiedElement instanceof ConstantValue)) if(!(constantifiedElement instanceof ConstantValue))
allConst = false; allConst = false;
@ -209,7 +203,7 @@ public class Initializers {
for(int i = 0; i < size; i++) { for(int i = 0; i < size; i++) {
Variable memberDef = memberDefIt.next(); Variable memberDef = memberDefIt.next();
RValue memberValue = valueIt.next(); RValue memberValue = valueIt.next();
RValue constantifiedMemberValue = constantify(memberValue, new ValueTypeSpec(memberDef.getType(), memberDef.getArraySpec()), program, source); RValue constantifiedMemberValue = constantify(memberValue, new ValueTypeSpec(memberDef.getType()), program, source);
constantifiedList.add(constantifiedMemberValue); constantifiedList.add(constantifiedMemberValue);
if(constantifiedMemberValue instanceof ConstantValue) if(constantifiedMemberValue instanceof ConstantValue)
constMemberMap.put(memberDef.getRef(), (ConstantValue) constantifiedMemberValue); constMemberMap.put(memberDef.getRef(), (ConstantValue) constantifiedMemberValue);
@ -230,15 +224,15 @@ public class Initializers {
* *
* @param valueList The list of values * @param valueList The list of values
* @param arrayType The pointer type of the array * @param arrayType The pointer type of the array
* @param arraySpec The array spec holding the array size.
* @param program The program * @param program The program
* @param source The source line * @param source The source line
* @return The constantified value * @return The constantified value
*/ */
private static RValue constantifyArray(ValueList valueList, SymbolTypePointer arrayType, ArraySpec arraySpec, Program program, StatementSource source) { private static RValue constantifyArray(ValueList valueList, SymbolTypePointer arrayType, Program program, StatementSource source) {
ArraySpec arraySpec = arrayType.getArraySpec();
SymbolType elementType = arrayType.getElementType(); SymbolType elementType = arrayType.getElementType();
// TODO: Handle array of array // TODO: Handle array of array
ValueTypeSpec elementTypeSpec = new ValueTypeSpec(elementType, null); ValueTypeSpec elementTypeSpec = new ValueTypeSpec(elementType);
boolean allConst = true; boolean allConst = true;
List<RValue> constantifiedList = new ArrayList<>(); List<RValue> constantifiedList = new ArrayList<>();
for(RValue elementValue : valueList.getList()) { for(RValue elementValue : valueList.getList()) {

View File

@ -29,9 +29,6 @@ public class VariableBuilder {
/** The type of the variable. */ /** The type of the variable. */
private SymbolType type; private SymbolType type;
/** Non-null if the variable is an array. */
private ArraySpec arraySpec;
/** The directives of the variable declaration. */ /** The directives of the variable declaration. */
private List<Directive> directives; private List<Directive> directives;
@ -41,12 +38,11 @@ public class VariableBuilder {
/** Configuration of how to setup optimization/memory area for variables. */ /** Configuration of how to setup optimization/memory area for variables. */
private VariableBuilderConfig config; private VariableBuilderConfig config;
public VariableBuilder(String varName, Scope scope, boolean isParameter, SymbolType type, ArraySpec arraySpec, List<Directive> directives, String dataSegment, VariableBuilderConfig config) { public VariableBuilder(String varName, Scope scope, boolean isParameter, SymbolType type, List<Directive> directives, String dataSegment, VariableBuilderConfig config) {
this.varName = varName; this.varName = varName;
this.scope = scope; this.scope = scope;
this.isParameter = isParameter; this.isParameter = isParameter;
this.type = type; this.type = type;
this.arraySpec = arraySpec;
this.directives = directives; this.directives = directives;
this.dataSegment = dataSegment; this.dataSegment = dataSegment;
this.config = config; this.config = config;
@ -58,7 +54,7 @@ public class VariableBuilder {
* @return The variable * @return The variable
*/ */
public Variable build() { public Variable build() {
Variable variable = new Variable(varName, getKind(), type, scope, getMemoryArea(), dataSegment, arraySpec, null); Variable variable = new Variable(varName, getKind(), type, scope, getMemoryArea(), dataSegment, null);
variable.setNoModify(this.isNoModify()); variable.setNoModify(this.isNoModify());
variable.setVolatile(this.isVolatile()); variable.setVolatile(this.isVolatile());
variable.setExport(this.isExport()); variable.setExport(this.isExport());
@ -112,15 +108,6 @@ public class VariableBuilder {
return SymbolType.isInteger(type) || SymbolType.BOOLEAN.equals(type); return SymbolType.isInteger(type) || SymbolType.BOOLEAN.equals(type);
} }
/**
* Is the type is a pointer type.
*
* @return True if the type is a pointer type.
*/
public boolean isTypePointer() {
return type instanceof SymbolTypePointer;
}
/** /**
* Is the type is a struct type. * Is the type is a struct type.
* *
@ -130,6 +117,15 @@ public class VariableBuilder {
return type instanceof SymbolTypeStruct; return type instanceof SymbolTypeStruct;
} }
/**
* Is the type is a pointer type.
*
* @return True if the type is a pointer type.
*/
public boolean isTypePointer() {
return type instanceof SymbolTypePointer;
}
/** /**
* Is the variable a global variable * Is the variable a global variable
* *
@ -178,7 +174,7 @@ public class VariableBuilder {
* @return true if the variable is an array declaration * @return true if the variable is an array declaration
*/ */
public boolean isArray() { public boolean isArray() {
return arraySpec != null; return isTypePointer() && ((SymbolTypePointer)type).getArraySpec()!=null;
} }
/** /**

View File

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

View File

@ -103,9 +103,6 @@ public class Variable implements Symbol {
/** Comments preceding the procedure in the source code. [ALL] */ /** Comments preceding the procedure in the source code. [ALL] */
private List<Comment> comments; private List<Comment> comments;
/** Non-null if the variable is an array. [Only constants that are arrays] */
private ArraySpec arraySpec;
/** The initial compiletime-value of the variable. Null if no initial value present. [Constants, Arrays, global/local-static loadstore-variables ] */ /** The initial compiletime-value of the variable. Null if no initial value present. [Constants, Arrays, global/local-static loadstore-variables ] */
private ConstantValue initValue; private ConstantValue initValue;
@ -127,17 +124,15 @@ public class Variable implements Symbol {
* @param scope The scope * @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 dataSegment The data segment (in main memory)
* @param arraySpec The array specification of the variable (if it is an array)
* @param initValue The constant value of the variable (if it is constant) * @param initValue The constant value of the variable (if it is constant)
*/ */
public Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ArraySpec arraySpec, ConstantValue initValue) { public Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ConstantValue initValue) {
this.name = name; this.name = name;
this.kind = kind; this.kind = kind;
if(Kind.PHI_MASTER.equals(kind)) if(Kind.PHI_MASTER.equals(kind))
this.nextPhiVersionNumber = 0; this.nextPhiVersionNumber = 0;
this.type = type; this.type = type;
this.scope = scope; this.scope = scope;
this.arraySpec = arraySpec;
this.dataSegment = dataSegment; this.dataSegment = dataSegment;
this.memoryArea = memoryArea; this.memoryArea = memoryArea;
this.initValue = initValue; this.initValue = initValue;
@ -154,7 +149,7 @@ public class Variable implements Symbol {
* @return The new intermediate variable * @return The new intermediate variable
*/ */
public static Variable createIntermediate(String name, Scope scope, String dataSegment) { 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); return new Variable(name, Kind.INTERMEDIATE, SymbolType.VAR, scope, MemoryArea.ZEROPAGE_MEMORY, dataSegment, null);
} }
/** /**
@ -168,7 +163,7 @@ public class Variable implements Symbol {
* @return The new PHI-master variable * @return The new PHI-master variable
*/ */
public static Variable createLoadStore(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) { 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); return new Variable(name, Kind.LOAD_STORE, type, scope, memoryArea, dataSegment, null);
} }
/** /**
@ -182,7 +177,7 @@ public class Variable implements Symbol {
* @return The new PHI-master variable * @return The new PHI-master variable
*/ */
public static Variable createPhiMaster(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) { 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); return new Variable(name, Kind.PHI_MASTER, type, scope, memoryArea, dataSegment, null);
} }
/** /**
@ -194,7 +189,7 @@ public class Variable implements Symbol {
public static Variable createPhiVersion(Variable phiMaster, int versionNum) { public static Variable createPhiVersion(Variable phiMaster, int versionNum) {
if(!phiMaster.isKindPhiMaster()) if(!phiMaster.isKindPhiMaster())
throw new InternalError("Cannot version non-PHI variable " + phiMaster.toString()); 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(), null); Variable version = new Variable(phiMaster.getName() + "#" + versionNum, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment(), null);
version.setMemoryAlignment(phiMaster.getMemoryAlignment()); version.setMemoryAlignment(phiMaster.getMemoryAlignment());
version.setMemoryAddress(phiMaster.getMemoryAddress()); version.setMemoryAddress(phiMaster.getMemoryAddress());
version.setOptimize(phiMaster.isOptimize()); version.setOptimize(phiMaster.isOptimize());
@ -226,12 +221,11 @@ public class Variable implements Symbol {
* @param name The name * @param name The name
* @param type The type * @param type The type
* @param scope The scope * @param scope The scope
* @param arraySpec The array specification (if an array)
* @param constantValue The constant value * @param constantValue The constant value
* @param dataSegment The data segment (in main memory) * @param dataSegment The data segment (in main memory)
*/ */
public static Variable createConstant(String name, SymbolType type, Scope scope, ArraySpec arraySpec, ConstantValue constantValue, String dataSegment) { public static Variable createConstant(String name, SymbolType type, Scope scope, ConstantValue constantValue, String dataSegment) {
return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, arraySpec, constantValue); return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, constantValue);
} }
/** /**
@ -241,7 +235,7 @@ public class Variable implements Symbol {
* @param constantValue The constant value * @param constantValue The constant value
*/ */
public static Variable createConstant(Variable variable, ConstantValue constantValue) { public static Variable createConstant(Variable variable, ConstantValue constantValue) {
Variable constVar = new Variable(variable.getName(), Kind.CONSTANT, variable.getType(), variable.getScope(), MemoryArea.MAIN_MEMORY, variable.getDataSegment(), variable.getArraySpec(), constantValue); Variable constVar = new Variable(variable.getName(), Kind.CONSTANT, variable.getType(), variable.getScope(), MemoryArea.MAIN_MEMORY, variable.getDataSegment(), constantValue);
constVar.setMemoryAlignment(variable.getMemoryAlignment()); constVar.setMemoryAlignment(variable.getMemoryAlignment());
constVar.setMemoryAddress(variable.getMemoryAddress()); constVar.setMemoryAddress(variable.getMemoryAddress());
constVar.setOptimize(variable.isOptimize()); constVar.setOptimize(variable.isOptimize());
@ -264,7 +258,7 @@ public class Variable implements Symbol {
* @param original The original variable * @param original The original variable
*/ */
public static Variable createCopy(String name, Scope scope, Variable original) { 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.getInitValue()); Variable copy = new Variable(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment(), original.getInitValue());
copy.setMemoryAlignment(original.getMemoryAlignment()); copy.setMemoryAlignment(original.getMemoryAlignment());
copy.setMemoryAddress(original.getMemoryAddress()); copy.setMemoryAddress(original.getMemoryAddress());
copy.setOptimize(original.isOptimize()); copy.setOptimize(original.isOptimize());
@ -293,13 +287,14 @@ public class Variable implements Symbol {
Variable memberVariable; Variable memberVariable;
if(isParameter && memberDefinition.isArray()) { if(isParameter && memberDefinition.isArray()) {
// Array struct members are converted to pointers when unwound (use same kind as the struct variable) // 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); SymbolTypePointer arrayType = (SymbolTypePointer) memberDefinition.getType();
memberVariable = new Variable(name, structVar.getKind(), new SymbolTypePointer(arrayType.getElementType()), structVar.getScope(), memoryArea, structVar.getDataSegment(), null);
} else if(memberDefinition.isKindConstant()) { } else if(memberDefinition.isKindConstant()) {
// Constant members are unwound as constants // Constant members are unwound as constants
memberVariable = new Variable(name, Kind.CONSTANT, memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getArraySpec(), memberDefinition.getInitValue()); memberVariable = new Variable(name, Kind.CONSTANT, memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getInitValue());
} else { } else {
// For others the kind is preserved from the member definition // 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.getInitValue()); memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getInitValue());
} }
memberVariable.setVolatile(structVar.isVolatile()); memberVariable.setVolatile(structVar.isVolatile());
memberVariable.setNoModify(structVar.isNoModify()); memberVariable.setNoModify(structVar.isNoModify());
@ -390,7 +385,7 @@ public class Variable implements Symbol {
* @return True if the variable is an array. * @return True if the variable is an array.
*/ */
public boolean isArray() { public boolean isArray() {
return arraySpec != null; return (getType() instanceof SymbolTypePointer) && (((SymbolTypePointer) getType()).getArraySpec() != null);
} }
/** /**
@ -399,18 +394,17 @@ public class Variable implements Symbol {
* @return The size of the array if declared. Null if not an array or an array without a declared size. * @return The size of the array if declared. Null if not an array or an array without a declared size.
*/ */
public ConstantValue getArraySize() { public ConstantValue getArraySize() {
if(arraySpec != null) if(isArray())
return arraySpec.getArraySize(); return ((SymbolTypePointer) getType()).getArraySpec().getArraySize();
else else
return null; return null;
} }
public ArraySpec getArraySpec() { public ArraySpec getArraySpec() {
return arraySpec; if(isArray())
} return ((SymbolTypePointer) getType()).getArraySpec();
else
public void setArraySpec(ArraySpec arraySpec) { return null;
this.arraySpec = arraySpec;
} }
public boolean isStruct() { public boolean isStruct() {

View File

@ -1,5 +1,9 @@
package dk.camelot64.kickc.model.types; package dk.camelot64.kickc.model.types;
import dk.camelot64.kickc.model.symbols.ArraySpec;
import java.util.Objects;
/** A pointer */ /** A pointer */
public class SymbolTypePointer implements SymbolType { public class SymbolTypePointer implements SymbolType {
@ -8,8 +12,16 @@ public class SymbolTypePointer implements SymbolType {
private SymbolType elementType; private SymbolType elementType;
public SymbolTypePointer(SymbolType elementType) { /** If non-null the pointer is an array. */
private ArraySpec arraySpec;
public SymbolTypePointer(SymbolType elementType, ArraySpec arraySpec) {
this.elementType = elementType; this.elementType = elementType;
this.arraySpec = arraySpec;
}
public SymbolTypePointer(SymbolType elementType) {
this(elementType, null);
} }
public SymbolType getElementType() { public SymbolType getElementType() {
@ -20,6 +32,10 @@ public class SymbolTypePointer implements SymbolType {
this.elementType = elementType; this.elementType = elementType;
} }
public ArraySpec getArraySpec() {
return arraySpec;
}
@Override @Override
public String getTypeName() { public String getTypeName() {
return elementType.getTypeName() + "*"; return elementType.getTypeName() + "*";
@ -32,19 +48,15 @@ public class SymbolTypePointer implements SymbolType {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if(this == o) { if(this == o) return true;
return true; if(o == null || getClass() != o.getClass()) return false;
}
if(o == null || getClass() != o.getClass()) {
return false;
}
SymbolTypePointer that = (SymbolTypePointer) o; SymbolTypePointer that = (SymbolTypePointer) o;
return elementType != null ? elementType.equals(that.elementType) : that.elementType == null; return Objects.equals(elementType, that.elementType);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return elementType != null ? elementType.hashCode() : 0; return Objects.hash(elementType);
} }
@Override @Override

View File

@ -403,7 +403,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
scopeStack.push(procedure); scopeStack.push(procedure);
Variable returnVar = null; Variable returnVar = null;
if(!SymbolType.VOID.equals(type)) { if(!SymbolType.VOID.equals(type)) {
final VariableBuilder builder = new VariableBuilder("return", procedure, false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig()); final VariableBuilder builder = new VariableBuilder("return", procedure, false, varDecl.getEffectiveType(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
returnVar = builder.build(); returnVar = builder.build();
} }
varDecl.exitType(); varDecl.exitType();
@ -507,7 +507,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visit(declPointerContext); this.visit(declPointerContext);
} }
String varName = ctx.NAME().getText(); String varName = ctx.NAME().getText();
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), true, varDecl.getEffectiveType(), null, varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig()); VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), true, varDecl.getEffectiveType(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable param = varBuilder.build(); Variable param = varBuilder.build();
varDecl.exitType(); varDecl.exitType();
return param; return param;
@ -797,8 +797,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
static class VariableDeclType { static class VariableDeclType {
/** The type. */ /** The type. */
SymbolType type; SymbolType type;
/** The array specification (non-null if it is an array, also holds size) */
ArraySpec arraySpec;
/** Const / Volatile Directives if applied to the type */ /** Const / Volatile Directives if applied to the type */
List<Directive> typeDirectives; List<Directive> typeDirectives;
/** If the type is SymbolTypePointer this holds the declaration type of the elements. */ /** If the type is SymbolTypePointer this holds the declaration type of the elements. */
@ -816,10 +814,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return type; return type;
} }
public ArraySpec getArraySpec() {
return arraySpec;
}
List<Directive> getTypeDirectives() { List<Directive> getTypeDirectives() {
return typeDirectives; return typeDirectives;
} }
@ -832,10 +826,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.elementDeclType = elementDeclType; this.elementDeclType = elementDeclType;
} }
void setArraySpec(ArraySpec arraySpec) {
this.arraySpec = arraySpec;
}
VariableDeclType getElementDeclType() { VariableDeclType getElementDeclType() {
return elementDeclType; return elementDeclType;
} }
@ -853,10 +843,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return null; return null;
} }
ArraySpec getEffectiveArraySpec() {
return varDeclType != null ? varDeclType.getArraySpec() : declType.getArraySpec();
}
/** /**
* Set type-level directives. Splits directives into type-directives (const, volatile) and general directives (all other). * Set type-level directives. Splits directives into type-directives (const, volatile) and general directives (all other).
* *
@ -994,9 +980,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} }
final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType(); final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType();
VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType(); VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType();
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType())); arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType(), arraySpec));
arrayDeclType.setElementDeclType(elementDeclType); arrayDeclType.setElementDeclType(elementDeclType);
arrayDeclType.setArraySpec(arraySpec);
varDecl.setVarDeclType(arrayDeclType); varDecl.setVarDeclType(arrayDeclType);
return null; return null;
} }
@ -1049,11 +1034,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
try { try {
final boolean isStructMember = varDecl.isStructMember(); final boolean isStructMember = varDecl.isStructMember();
final SymbolType effectiveType = varDecl.getEffectiveType(); final SymbolType effectiveType = varDecl.getEffectiveType();
final ArraySpec effectiveArraySpec = varDecl.getEffectiveArraySpec();
final List<Directive> effectiveDirectives = varDecl.getEffectiveDirectives(); final List<Directive> effectiveDirectives = varDecl.getEffectiveDirectives();
final List<Comment> declComments = varDecl.getDeclComments(); final List<Comment> declComments = varDecl.getDeclComments();
varDecl.exitVar(); varDecl.exitVar();
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, effectiveType, effectiveArraySpec, effectiveDirectives, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig()); VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, effectiveType, effectiveDirectives, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable variable = varBuilder.build(); Variable variable = varBuilder.build();
if(isStructMember && (initializer != null)) if(isStructMember && (initializer != null))
throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), statementSource); throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), statementSource);
@ -1066,7 +1050,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(initializer != null) if(initializer != null)
PrePostModifierHandler.addPreModifiers(this, initializer, statementSource); PrePostModifierHandler.addPreModifiers(this, initializer, statementSource);
RValue initValue = (initializer == null) ? null : (RValue) visit(initializer); RValue initValue = (initializer == null) ? null : (RValue) visit(initializer);
initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(effectiveType, effectiveArraySpec), program, statementSource); initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(effectiveType), program, statementSource);
boolean isPermanent = ScopeRef.ROOT.equals(variable.getScope().getRef()) || variable.isPermanent(); boolean isPermanent = ScopeRef.ROOT.equals(variable.getScope().getRef()) || variable.isPermanent();
if(variable.isKindConstant() || (isPermanent && variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !isStructMember && variable.getRegister() == null)) { if(variable.isKindConstant() || (isPermanent && variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !isStructMember && variable.getRegister() == null)) {
// Set initial value // Set initial value
@ -1122,7 +1106,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} }
String varName = ctx.NAME().getText(); String varName = ctx.NAME().getText();
StatementSource statementSource = new StatementSource(ctx); StatementSource statementSource = new StatementSource(ctx);
if(!(this.varDecl.getEffectiveType() instanceof SymbolTypePointer) || varDecl.getEffectiveArraySpec() == null) { SymbolType effectiveType = this.varDecl.getEffectiveType();
if(!(effectiveType instanceof SymbolTypePointer) || ((SymbolTypePointer) effectiveType).getArraySpec() == null) {
throw new CompileError("KickAsm initializers only supported for arrays " + varDecl.getEffectiveType().getTypeName(), statementSource); throw new CompileError("KickAsm initializers only supported for arrays " + varDecl.getEffectiveType().getTypeName(), statementSource);
} }
// Add KickAsm statement // Add KickAsm statement
@ -1136,10 +1121,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(kasm.declaredClobber != null) { if(kasm.declaredClobber != null) {
throw new CompileError("KickAsm initializers does not support 'clobbers' directive.", statementSource); throw new CompileError("KickAsm initializers does not support 'clobbers' directive.", statementSource);
} }
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypePointer) varDecl.getEffectiveType()).getElementType(), kasm.kickAsmCode, kasm.uses, varDecl.getEffectiveArraySpec().getArraySize()); ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypePointer) varDecl.getEffectiveType()).getElementType(), kasm.kickAsmCode, kasm.uses, ((SymbolTypePointer) effectiveType).getArraySpec().getArraySize());
// Add a constant variable // Add a constant variable
Scope scope = getCurrentScope(); Scope scope = getCurrentScope();
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig()); VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, varDecl.getEffectiveType(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable variable = varBuilder.build(); Variable variable = varBuilder.build();
// Set constant value // Set constant value
variable.setInitValue(getConstInitValue(constantArrayKickAsm, null, statementSource)); variable.setInitValue(getConstInitValue(constantArrayKickAsm, null, statementSource));
@ -1683,7 +1668,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
String varName = ctx.NAME().getText(); String varName = ctx.NAME().getText();
Variable lValue; Variable lValue;
if(varType != null) { if(varType != null) {
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, varType, null, varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig()); VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, varType, varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
lValue = varBuilder.build(); lValue = varBuilder.build();
} else { } else {
lValue = getCurrentScope().findVariable(varName); lValue = getCurrentScope().findVariable(varName);
@ -1980,7 +1965,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Scope parentScope = getCurrentScope(); Scope parentScope = getCurrentScope();
while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope(); while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope();
for(Variable member : enumDefinition.getAllConstants(false)) { for(Variable member : enumDefinition.getAllConstants(false)) {
parentScope.add(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, null, member.getInitValue(), currentDataSegment)); parentScope.add(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, member.getInitValue(), currentDataSegment));
} }
varDecl.setDeclType(SymbolType.BYTE); varDecl.setDeclType(SymbolType.BYTE);
return null; return null;
@ -2015,7 +2000,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} }
} }
} }
currentEnum.add(Variable.createConstant(memberName, SymbolType.BYTE, getCurrentScope(), null, enumValue, currentDataSegment)); currentEnum.add(Variable.createConstant(memberName, SymbolType.BYTE, getCurrentScope(), enumValue, currentDataSegment));
return null; return null;
} }
@ -2054,9 +2039,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
type = elementType; type = elementType;
declType = elementDeclType; declType = elementDeclType;
} }
if(typeDefVariable.getArraySpec() != null)
varDecl.getDeclType().setArraySpec(typeDefVariable.getArraySpec());
if(typeDefVariable.isNoModify()) if(typeDefVariable.isNoModify())
varDecl.getDeclType().getTypeDirectives().add(new Directive.Const()); varDecl.getDeclType().getTypeDirectives().add(new Directive.Const());
if(typeDefVariable.isVolatile()) if(typeDefVariable.isVolatile())
@ -2105,14 +2087,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
visit(ctx.type()); visit(ctx.type());
final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType(); final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType();
final VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType(); final VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType();
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType()));
arrayDeclType.setElementDeclType(elementDeclType); ArraySpec arraySpec;
if(ctx.expr() != null) { if(ctx.expr() != null) {
RValue sizeVal = (RValue) visit(ctx.expr()); RValue sizeVal = (RValue) visit(ctx.expr());
arrayDeclType.setArraySpec(new ArraySpec((ConstantValue) sizeVal)); arraySpec = new ArraySpec((ConstantValue) sizeVal);
} else { } else {
arrayDeclType.setArraySpec(new ArraySpec()); arraySpec = new ArraySpec();
} }
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType(), arraySpec));
arrayDeclType.setElementDeclType(elementDeclType);
varDecl.setVarDeclType(arrayDeclType); varDecl.setVarDeclType(arrayDeclType);
return null; return null;
} else { } else {
@ -2140,7 +2125,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visit(declArrayContext); this.visit(declArrayContext);
} }
String typedefName = ctx.NAME().getText(); String typedefName = ctx.NAME().getText();
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig()); VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, varDecl.getEffectiveType(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
final Variable typeDefVar = varBuilder.build(); final Variable typeDefVar = varBuilder.build();
scopeStack.pop(); scopeStack.pop();
varDecl.exitType(); varDecl.exitType();

View File

@ -78,7 +78,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
} }
final long stringLength = constantString.getStringLength(); final long stringLength = constantString.getStringLength();
final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD); final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD);
Variable strConst = Variable.createConstant(name, new SymbolTypePointer(SymbolType.BYTE), blockScope, new ArraySpec(arraySize), constantString, blockScope.getSegmentData()); Variable strConst = Variable.createConstant(name, new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(arraySize)), blockScope, constantString, blockScope.getSegmentData());
blockScope.add(strConst); blockScope.add(strConst);
if(getLog().isVerbosePass1CreateSsa()) { if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\""); getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");

View File

@ -37,7 +37,7 @@ public class Pass1UnwindStructPrepare extends Pass2SsaOptimization {
RValue rValue = assignment.getrValue2(); RValue rValue = assignment.getrValue2();
if(!(rValue instanceof ConstantValue) && lValueType instanceof SymbolTypeStruct) { if(!(rValue instanceof ConstantValue) && lValueType instanceof SymbolTypeStruct) {
// TODO: Constantify all R-Values? // TODO: Constantify all R-Values?
Initializers.ValueTypeSpec lValueTypeSpec = new Initializers.ValueTypeSpec(lValueType, null); Initializers.ValueTypeSpec lValueTypeSpec = new Initializers.ValueTypeSpec(lValueType);
RValue rValueConstantified = Initializers.constantify(rValue, lValueTypeSpec, getProgram(), assignment.getSource()); RValue rValueConstantified = Initializers.constantify(rValue, lValueTypeSpec, getProgram(), assignment.getSource());
if(!rValue.equals(rValueConstantified)) { if(!rValue.equals(rValueConstantified)) {
assignment.setrValue2(rValueConstantified); assignment.setrValue2(rValueConstantified);

View File

@ -93,7 +93,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
String localName = getRootName(constantVars); String localName = getRootName(constantVars);
final long stringLength = constString.getStringLength(); final long stringLength = constString.getStringLength();
final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD); final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD);
Variable newRootConstant = Variable.createConstant(localName, new SymbolTypePointer(SymbolType.BYTE), rootScope, new ArraySpec(arraySize), constString, segmentData); Variable newRootConstant = Variable.createConstant(localName, new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(arraySize)), rootScope, constString, segmentData);
rootScope.add(newRootConstant); rootScope.add(newRootConstant);
rootConstant = newRootConstant; rootConstant = newRootConstant;
} }

View File

@ -606,7 +606,7 @@ public class Pass4CodeGeneration {
} else { } else {
// Zero-fill variable // Zero-fill variable
AsmDataChunk asmDataChunk = new AsmDataChunk(); AsmDataChunk asmDataChunk = new AsmDataChunk();
ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(variable.getType(), variable.getArraySpec()), null); ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(variable.getType()), null);
addChunkData(asmDataChunk, zeroValue, variable.getType(), variable.getArraySpec(), scopeRef); addChunkData(asmDataChunk, zeroValue, variable.getType(), variable.getArraySpec(), scopeRef);
asmDataChunk.addToAsm(AsmFormat.asmFix(variable.getAsmName()), asm); asmDataChunk.addToAsm(AsmFormat.asmFix(variable.getAsmName()), asm);
} }
@ -735,7 +735,7 @@ public class Pass4CodeGeneration {
} else { } else {
paddingBytesAsm = AsmFormat.getAsmConstant(program, paddingSizeVal, 99, scopeRef); paddingBytesAsm = AsmFormat.getAsmConstant(program, paddingSizeVal, 99, scopeRef);
} }
ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(elementType, null), null); ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(elementType), null);
if(zeroValue instanceof ConstantInteger | zeroValue instanceof ConstantPointer) { if(zeroValue instanceof ConstantInteger | zeroValue instanceof ConstantPointer) {
dataChunk.addDataZeroFilled(getNumericType(elementType), paddingBytesAsm, (int) paddingSize, getEncoding(zeroValue)); dataChunk.addDataZeroFilled(getNumericType(elementType), paddingBytesAsm, (int) paddingSize, getEncoding(zeroValue));
} else { } else {

View File

@ -43,8 +43,8 @@ public interface ValueSource {
SymbolType getSymbolType(); SymbolType getSymbolType();
/** /**
* Get the array nature of the value * Get the array nature of the type of the value
* @return The array nature of the value * @return The array nature
*/ */
ArraySpec getArraySpec(); ArraySpec getArraySpec();

View File

@ -1,8 +1,10 @@
package dk.camelot64.kickc.passes.unwinding; package dk.camelot64.kickc.passes.unwinding;
import dk.camelot64.kickc.model.symbols.ArraySpec;
import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.StructDefinition; import dk.camelot64.kickc.model.symbols.StructDefinition;
import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeStruct; import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.ConstantValue; import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.passes.utils.SizeOfConstants; import dk.camelot64.kickc.passes.utils.SizeOfConstants;
@ -39,6 +41,14 @@ public abstract class ValueSourceBase implements ValueSource {
return getArraySpec() != null ? getArraySpec().getArraySize() : SizeOfConstants.getSizeOfConstantVar(scope, getSymbolType()); return getArraySpec() != null ? getArraySpec().getArraySize() : SizeOfConstants.getSizeOfConstantVar(scope, getSymbolType());
} }
@Override
public ArraySpec getArraySpec() {
if(getSymbolType() instanceof SymbolTypePointer)
return ((SymbolTypePointer) getSymbolType()).getArraySpec();
else
return null;
}
@Override @Override
public List<String> getMemberNames(ProgramScope scope) { public List<String> getMemberNames(ProgramScope scope) {
if(getSymbolType() instanceof SymbolTypeStruct) { if(getSymbolType() instanceof SymbolTypeStruct) {

View File

@ -15,12 +15,10 @@ import java.util.ListIterator;
/** Unwinding a constant value. */ /** Unwinding a constant value. */
public class ValueSourceConstant extends ValueSourceBase { public class ValueSourceConstant extends ValueSourceBase {
private final SymbolType symbolType; private final SymbolType symbolType;
private final ArraySpec arraySpec;
private final ConstantValue value; private final ConstantValue value;
public ValueSourceConstant(SymbolType symbolType, ArraySpec arraySpec, ConstantValue value) { public ValueSourceConstant(SymbolType symbolType, ConstantValue value) {
this.symbolType = symbolType; this.symbolType = symbolType;
this.arraySpec = arraySpec;
this.value = value; this.value = value;
} }
@ -29,10 +27,6 @@ public class ValueSourceConstant extends ValueSourceBase {
return symbolType; return symbolType;
} }
@Override
public ArraySpec getArraySpec() {
return arraySpec;
}
@Override @Override
protected boolean isStructClassic() { protected boolean isStructClassic() {
@ -54,14 +48,12 @@ public class ValueSourceConstant extends ValueSourceBase {
ConstantStructValue constantStructValue = (ConstantStructValue) val; ConstantStructValue constantStructValue = (ConstantStructValue) val;
final Variable member = structDefinition.getMember(memberName); final Variable member = structDefinition.getMember(memberName);
final SymbolType type = member.getType(); final SymbolType type = member.getType();
final ArraySpec arraySpec = member.getArraySpec();
final ConstantValue memberValue = constantStructValue.getValue(member.getRef()); final ConstantValue memberValue = constantStructValue.getValue(member.getRef());
return new ValueSourceConstant(type, arraySpec, memberValue); return new ValueSourceConstant(type, memberValue);
} else if(val instanceof StructZero) { } else if(val instanceof StructZero) {
final SymbolType memberType = structDefinition.getMember(memberName).getType(); final SymbolType memberType = structDefinition.getMember(memberName).getType();
final ArraySpec memberArraySpec = structDefinition.getMember(memberName).getArraySpec(); final ConstantValue memberZeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(memberType), currentStmt.getSource());
final ConstantValue memberZeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(memberType, memberArraySpec), currentStmt.getSource()); return new ValueSourceConstant(memberType, memberZeroValue);
return new ValueSourceConstant(memberType, memberArraySpec, memberZeroValue);
} }
throw new InternalError("Not supported "+ val); throw new InternalError("Not supported "+ val);
} }
@ -74,7 +66,7 @@ public class ValueSourceConstant extends ValueSourceBase {
@Override @Override
public RValue getBulkRValue(ProgramScope scope) { public RValue getBulkRValue(ProgramScope scope) {
String constName = scope.allocateIntermediateVariableName(); String constName = scope.allocateIntermediateVariableName();
Variable constVar = Variable.createConstant(constName, symbolType, scope, getArraySpec(), value, Scope.SEGMENT_DATA_DEFAULT); Variable constVar = Variable.createConstant(constName, symbolType, scope, value, Scope.SEGMENT_DATA_DEFAULT);
scope.add(constVar); scope.add(constVar);
if(getArraySpec()!=null) { if(getArraySpec()!=null) {
final SymbolType elementType = ((SymbolTypePointer) getSymbolType()).getElementType(); final SymbolType elementType = ((SymbolTypePointer) getSymbolType()).getElementType();

View File

@ -55,7 +55,7 @@ public class ValueSourceFactory {
return new ValueSourceZero(((StructZero) value).getTypeStruct(), null); return new ValueSourceZero(((StructZero) value).getTypeStruct(), null);
} }
if(value instanceof ConstantValue) if(value instanceof ConstantValue)
return new ValueSourceConstant(((ConstantValue) value).getType(programScope), null, (ConstantValue) value); return new ValueSourceConstant(((ConstantValue) value).getType(programScope), (ConstantValue) value);
if(value instanceof PointerDereferenceSimple) if(value instanceof PointerDereferenceSimple)
return new ValueSourcePointerDereferenceSimple((PointerDereferenceSimple) value, valueType, null); return new ValueSourcePointerDereferenceSimple((PointerDereferenceSimple) value, valueType, null);
if(value instanceof PointerDereferenceIndexed) if(value instanceof PointerDereferenceIndexed)

View File

@ -36,11 +36,6 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase {
return valueType; return valueType;
} }
@Override
public ArraySpec getArraySpec() {
return valueArraySpec;
}
@Override @Override
protected boolean isStructClassic() { protected boolean isStructClassic() {
return getSymbolType() instanceof SymbolTypeStruct; return getSymbolType() instanceof SymbolTypeStruct;
@ -87,7 +82,7 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase {
if(pointerDereferenceIndexed.getIndex() instanceof ConstantValue) { if(pointerDereferenceIndexed.getIndex() instanceof ConstantValue) {
// Unwind to (elmType*)&struct + OFFSET_MEMBER + idx // Unwind to (elmType*)&struct + OFFSET_MEMBER + idx
ConstantBinary elmPointer = new ConstantBinary(memberPointer, Operators.PLUS, (ConstantValue) pointerDereferenceIndexed.getIndex()); ConstantBinary elmPointer = new ConstantBinary(memberPointer, Operators.PLUS, (ConstantValue) pointerDereferenceIndexed.getIndex());
return new ValueSourceConstant(new SymbolTypePointer(elementType), null, elmPointer); return new ValueSourceConstant(new SymbolTypePointer(elementType), elmPointer);
} else { } else {
// Unwind to (elmType*)&struct + OFFSET_MEMBER + idx // Unwind to (elmType*)&struct + OFFSET_MEMBER + idx
Scope scope = programScope.getScope(currentBlock.getScope()); Scope scope = programScope.getScope(currentBlock.getScope());

View File

@ -77,7 +77,7 @@ public class ValueSourcePointerDereferenceSimple extends ValueSourceBase {
// Calculate member address (elmtype*)&struct + OFFSET_MEMBER // Calculate member address (elmtype*)&struct + OFFSET_MEMBER
ConstantBinary memberPointer = new ConstantBinary(structTypedPointer, Operators.PLUS, memberOffsetConstant); ConstantBinary memberPointer = new ConstantBinary(structTypedPointer, Operators.PLUS, memberOffsetConstant);
// Unwind to (type*)&struct + OFFSET_MEMBER // Unwind to (type*)&struct + OFFSET_MEMBER
return new ValueSourceConstant(pointerToElementType, null, memberPointer); return new ValueSourceConstant(pointerToElementType, memberPointer);
} else { } else {
// Pointer to member type // Pointer to member type
ConstantCastValue structTypedPointer = new ConstantCastValue(new SymbolTypePointer(memberType), (ConstantValue) structPointer); ConstantCastValue structTypedPointer = new ConstantCastValue(new SymbolTypePointer(memberType), (ConstantValue) structPointer);

View File

@ -83,7 +83,7 @@ public class ValueSourceVariable extends ValueSourceBase {
// Calculate member address (elmtype*)&struct + OFFSET_MEMBER // Calculate member address (elmtype*)&struct + OFFSET_MEMBER
ConstantBinary memberArrayPointer = new ConstantBinary(structTypedPointer, Operators.PLUS, memberOffsetConstant); ConstantBinary memberArrayPointer = new ConstantBinary(structTypedPointer, Operators.PLUS, memberOffsetConstant);
// Unwind to (elmtype*)&struct + OFFSET_MEMBER // Unwind to (elmtype*)&struct + OFFSET_MEMBER
return new ValueSourceConstant(pointerToElementType, null, memberArrayPointer); return new ValueSourceConstant(pointerToElementType, memberArrayPointer);
} else { } else {
// Simple member value - unwind to value of member *((type*)&struct + OFFSET_MEMBER) // Simple member value - unwind to value of member *((type*)&struct + OFFSET_MEMBER)
// Pointer to member type // Pointer to member type

View File

@ -44,7 +44,7 @@ public class ValueSourceZero extends ValueSourceBase {
@Override @Override
public RValue getSimpleValue(ProgramScope programScope) { public RValue getSimpleValue(ProgramScope programScope) {
return Initializers.createZeroValue(new Initializers.ValueTypeSpec(getSymbolType(), getArraySpec()), null); return Initializers.createZeroValue(new Initializers.ValueTypeSpec(getSymbolType()), null);
} }
@Override @Override

View File

@ -26,7 +26,7 @@ public class SizeOfConstants {
if(typeSizeConstant == null) { if(typeSizeConstant == null) {
// Constant not found - create it // Constant not found - create it
long typeSize = type.getSizeBytes(); long typeSize = type.getSizeBytes();
typeSizeConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(typeSize&0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT); typeSizeConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, new ConstantInteger(typeSize&0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(typeSizeConstant); programScope.add(typeSizeConstant);
} }
return typeSizeConstant.getConstantRef(); return typeSizeConstant.getConstantRef();
@ -77,7 +77,7 @@ public class SizeOfConstants {
// Constant not found - create it // Constant not found - create it
Variable memberDef = structDefinition.getMember(memberName); Variable memberDef = structDefinition.getMember(memberName);
long memberByteOffset = structDefinition.getMemberByteOffset(memberDef, programScope); long memberByteOffset = structDefinition.getMemberByteOffset(memberDef, programScope);
memberOffsetConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT); memberOffsetConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
programScope.add(memberOffsetConstant); programScope.add(memberOffsetConstant);
} }
return memberOffsetConstant.getConstantRef(); return memberOffsetConstant.getConstantRef();

View File

@ -6808,13 +6808,13 @@ ASSEMBLER BEFORE OPTIMIZATION
// Find 2 entries that give 2020 when added together // Find 2 entries that give 2020 when added together
// And 3 entries that give 2020 when added together // And 3 entries that give 2020 when added together
// Upstart // Upstart
// Atari XL/XE executable XEX file with a single segment // Atari XL/XE executable XEX file with a single segment
// https://www.atarimax.com/jindroush.atari.org/afmtexe.html // https://www.atarimax.com/jindroush.atari.org/afmtexe.html
.plugin "dk.camelot64.kickass.xexplugin.AtariXex" .plugin "dk.camelot64.kickass.xexplugin.AtariXex"
.file [name="2020-01.xex", type="bin", segments="XexFile"] .file [name="2020-01.xex", type="bin", segments="XexFile"]
.segmentdef XexFile [segments="Program", modify="XexFormat", _RunAddr=main] .segmentdef XexFile [segments="Program", modify="XexFormat", _RunAddr=main]
.segmentdef Program [segments="Code, Data"] .segmentdef Program [segments="Code, Data"]
.segmentdef Code [start=$2000] .segmentdef Code [start=$2000]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
// Global Constants & labels // Global Constants & labels
.const SIZEOF_WORD = 2 .const SIZEOF_WORD = 2
@ -9782,13 +9782,13 @@ Score: 27696937
// Find 2 entries that give 2020 when added together // Find 2 entries that give 2020 when added together
// And 3 entries that give 2020 when added together // And 3 entries that give 2020 when added together
// Upstart // Upstart
// Atari XL/XE executable XEX file with a single segment // Atari XL/XE executable XEX file with a single segment
// https://www.atarimax.com/jindroush.atari.org/afmtexe.html // https://www.atarimax.com/jindroush.atari.org/afmtexe.html
.plugin "dk.camelot64.kickass.xexplugin.AtariXex" .plugin "dk.camelot64.kickass.xexplugin.AtariXex"
.file [name="2020-01.xex", type="bin", segments="XexFile"] .file [name="2020-01.xex", type="bin", segments="XexFile"]
.segmentdef XexFile [segments="Program", modify="XexFormat", _RunAddr=main] .segmentdef XexFile [segments="Program", modify="XexFormat", _RunAddr=main]
.segmentdef Program [segments="Code, Data"] .segmentdef Program [segments="Code, Data"]
.segmentdef Code [start=$2000] .segmentdef Code [start=$2000]
.segmentdef Data [startAfter="Code"] .segmentdef Data [startAfter="Code"]
// Global Constants & labels // Global Constants & labels
.const SIZEOF_WORD = 2 .const SIZEOF_WORD = 2