1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-30 00:29:45 +00:00

Moved ArraySpec to SymbolTypePointer.

This commit is contained in:
Jesper Gravgaard 2021-04-12 20:57:46 +02:00
parent 66b3daa62f
commit 76edc3b8c8
21 changed files with 134 additions and 156 deletions

View File

@ -43,7 +43,7 @@ public class CallingConventionStack {
if(returnOffsetConstant == null) {
// Constant not found - create it
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);
}
return returnOffsetConstant.getConstantRef();
@ -62,7 +62,7 @@ public class CallingConventionStack {
if(paramOffsetConstant == null) {
// Constant not found - create it
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);
}
return paramOffsetConstant.getConstantRef();
@ -137,7 +137,7 @@ public class CallingConventionStack {
*/
public static ConstantRef getStackBaseConstant(ProgramScope programScope) {
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);
programScope.add(stackBase);
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.
*
* @param type The type of the variable
* @param typeSpec The type of the variable
* @param statementSource The source line
* @return The new statement
*/
@ -32,15 +32,15 @@ public class Initializers {
return new StructZero(typeStruct);
} else if(typeSpec.getType() instanceof SymbolTypePointer) {
SymbolTypePointer typePointer = (SymbolTypePointer) typeSpec.getType();
if(typeSpec.getArraySpec() == null) {
if(typePointer.getArraySpec() == null) {
// Add an zero value initializer
return new ConstantPointer(0L, typePointer.getElementType());
} else {
// 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);
}
return new ConstantArrayFilled(typePointer.getElementType(), typeSpec.getArraySpec().getArraySize());
return new ConstantArrayFilled(typePointer.getElementType(), typePointer.getArraySpec().getArraySize());
}
} else {
throw new CompileError("Default initializer not implemented for type " + typeSpec.getType().getTypeName(), statementSource);
@ -52,20 +52,14 @@ public class Initializers {
SymbolType type;
ArraySpec arraySpec;
public ValueTypeSpec(SymbolType type, ArraySpec arraySpec) {
public ValueTypeSpec(SymbolType type) {
this.type = type;
this.arraySpec = arraySpec;
}
public SymbolType getType() {
return type;
}
public ArraySpec getArraySpec() {
return arraySpec;
}
}
@ -88,16 +82,16 @@ public class Initializers {
final CastValue castValue = (CastValue) initValue;
if(castValue.getValue() instanceof ValueList && castValue.getToType() instanceof SymbolTypeStruct) {
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) {
return new ConstantCastValue(toType, (ConstantValue) constantSub);
}
}
} else if(initValue instanceof ValueList) {
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
initValue = constantifyArray(initList, (SymbolTypePointer) typeSpec.getType(), typeSpec.getArraySpec(), program, source);
initValue = constantifyArray(initList, (SymbolTypePointer) typeSpec.getType(), program, source);
} else if(typeSpec.getType() instanceof SymbolTypeStruct) {
// Type is a struct
initValue = constantifyStruct(initList, (SymbolTypeStruct) typeSpec.getType(), program, source);
@ -145,7 +139,7 @@ public class Initializers {
boolean allConst = true;
List<RValue> constantifiedList = new ArrayList<>();
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);
if(!(constantifiedElement instanceof ConstantValue))
allConst = false;
@ -163,7 +157,7 @@ public class Initializers {
boolean allConst = true;
List<RValue> constantifiedList = new ArrayList<>();
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);
if(!(constantifiedElement instanceof ConstantValue))
allConst = false;
@ -209,7 +203,7 @@ public class Initializers {
for(int i = 0; i < size; i++) {
Variable memberDef = memberDefIt.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);
if(constantifiedMemberValue instanceof ConstantValue)
constMemberMap.put(memberDef.getRef(), (ConstantValue) constantifiedMemberValue);
@ -230,15 +224,15 @@ public class Initializers {
*
* @param valueList The list of values
* @param arrayType The pointer type of the array
* @param arraySpec The array spec holding the array size.
* @param program The program
* @param source The source line
* @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();
// TODO: Handle array of array
ValueTypeSpec elementTypeSpec = new ValueTypeSpec(elementType, null);
ValueTypeSpec elementTypeSpec = new ValueTypeSpec(elementType);
boolean allConst = true;
List<RValue> constantifiedList = new ArrayList<>();
for(RValue elementValue : valueList.getList()) {

View File

@ -29,9 +29,6 @@ public class VariableBuilder {
/** The type of the variable. */
private SymbolType type;
/** Non-null if the variable is an array. */
private ArraySpec arraySpec;
/** The directives of the variable declaration. */
private List<Directive> directives;
@ -41,12 +38,11 @@ public class VariableBuilder {
/** Configuration of how to setup optimization/memory area for variables. */
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.scope = scope;
this.isParameter = isParameter;
this.type = type;
this.arraySpec = arraySpec;
this.directives = directives;
this.dataSegment = dataSegment;
this.config = config;
@ -58,7 +54,7 @@ public class VariableBuilder {
* @return The variable
*/
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.setVolatile(this.isVolatile());
variable.setExport(this.isExport());
@ -112,15 +108,6 @@ public class VariableBuilder {
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.
*
@ -130,6 +117,15 @@ public class VariableBuilder {
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
*
@ -178,7 +174,7 @@ public class VariableBuilder {
* @return true if the variable is an array declaration
*/
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) {
// Constant not found - create it
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);
}
return typeIdConstant.getConstantRef();

View File

@ -103,9 +103,6 @@ public class Variable implements Symbol {
/** Comments preceding the procedure in the source code. [ALL] */
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 ] */
private ConstantValue initValue;
@ -127,17 +124,15 @@ public class Variable implements Symbol {
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @param arraySpec The array specification of the variable (if it is an array)
* @param 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.kind = kind;
if(Kind.PHI_MASTER.equals(kind))
this.nextPhiVersionNumber = 0;
this.type = type;
this.scope = scope;
this.arraySpec = arraySpec;
this.dataSegment = dataSegment;
this.memoryArea = memoryArea;
this.initValue = initValue;
@ -154,7 +149,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);
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
*/
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
*/
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) {
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(), 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.setMemoryAddress(phiMaster.getMemoryAddress());
version.setOptimize(phiMaster.isOptimize());
@ -226,12 +221,11 @@ public class Variable implements Symbol {
* @param name The name
* @param type The type
* @param scope The scope
* @param arraySpec The array specification (if an array)
* @param constantValue The constant value
* @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, constantValue);
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, constantValue);
}
/**
@ -241,7 +235,7 @@ public class Variable implements Symbol {
* @param constantValue The constant value
*/
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.setMemoryAddress(variable.getMemoryAddress());
constVar.setOptimize(variable.isOptimize());
@ -264,7 +258,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.getInitValue());
Variable copy = new Variable(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment(), original.getInitValue());
copy.setMemoryAlignment(original.getMemoryAlignment());
copy.setMemoryAddress(original.getMemoryAddress());
copy.setOptimize(original.isOptimize());
@ -293,13 +287,14 @@ 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);
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()) {
// 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 {
// 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.setNoModify(structVar.isNoModify());
@ -390,7 +385,7 @@ public class Variable implements Symbol {
* @return True if the variable is an array.
*/
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.
*/
public ConstantValue getArraySize() {
if(arraySpec != null)
return arraySpec.getArraySize();
if(isArray())
return ((SymbolTypePointer) getType()).getArraySpec().getArraySize();
else
return null;
}
public ArraySpec getArraySpec() {
return arraySpec;
}
public void setArraySpec(ArraySpec arraySpec) {
this.arraySpec = arraySpec;
if(isArray())
return ((SymbolTypePointer) getType()).getArraySpec();
else
return null;
}
public boolean isStruct() {

View File

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

View File

@ -403,7 +403,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
scopeStack.push(procedure);
Variable returnVar = null;
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();
}
varDecl.exitType();
@ -507,7 +507,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visit(declPointerContext);
}
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();
varDecl.exitType();
return param;
@ -797,8 +797,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
static class VariableDeclType {
/** The 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 */
List<Directive> typeDirectives;
/** 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;
}
public ArraySpec getArraySpec() {
return arraySpec;
}
List<Directive> getTypeDirectives() {
return typeDirectives;
}
@ -832,10 +826,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.elementDeclType = elementDeclType;
}
void setArraySpec(ArraySpec arraySpec) {
this.arraySpec = arraySpec;
}
VariableDeclType getElementDeclType() {
return elementDeclType;
}
@ -853,10 +843,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
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).
*
@ -994,9 +980,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType();
VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType();
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType()));
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType(), arraySpec));
arrayDeclType.setElementDeclType(elementDeclType);
arrayDeclType.setArraySpec(arraySpec);
varDecl.setVarDeclType(arrayDeclType);
return null;
}
@ -1049,11 +1034,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
try {
final boolean isStructMember = varDecl.isStructMember();
final SymbolType effectiveType = varDecl.getEffectiveType();
final ArraySpec effectiveArraySpec = varDecl.getEffectiveArraySpec();
final List<Directive> effectiveDirectives = varDecl.getEffectiveDirectives();
final List<Comment> declComments = varDecl.getDeclComments();
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();
if(isStructMember && (initializer != null))
throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), statementSource);
@ -1066,7 +1050,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(initializer != null)
PrePostModifierHandler.addPreModifiers(this, initializer, statementSource);
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();
if(variable.isKindConstant() || (isPermanent && variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !isStructMember && variable.getRegister() == null)) {
// Set initial value
@ -1122,7 +1106,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
String varName = ctx.NAME().getText();
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);
}
// Add KickAsm statement
@ -1136,10 +1121,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(kasm.declaredClobber != null) {
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
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();
// Set constant value
variable.setInitValue(getConstInitValue(constantArrayKickAsm, null, statementSource));
@ -1683,7 +1668,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
String varName = ctx.NAME().getText();
Variable lValue;
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();
} else {
lValue = getCurrentScope().findVariable(varName);
@ -1980,7 +1965,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.getInitValue(), currentDataSegment));
parentScope.add(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, member.getInitValue(), currentDataSegment));
}
varDecl.setDeclType(SymbolType.BYTE);
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;
}
@ -2054,9 +2039,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
type = elementType;
declType = elementDeclType;
}
if(typeDefVariable.getArraySpec() != null)
varDecl.getDeclType().setArraySpec(typeDefVariable.getArraySpec());
if(typeDefVariable.isNoModify())
varDecl.getDeclType().getTypeDirectives().add(new Directive.Const());
if(typeDefVariable.isVolatile())
@ -2105,14 +2087,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
visit(ctx.type());
final VariableDeclaration.VariableDeclType elementDeclType = varDecl.getEffectiveDeclType();
final VariableDeclaration.VariableDeclType arrayDeclType = new VariableDeclaration.VariableDeclType();
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType()));
arrayDeclType.setElementDeclType(elementDeclType);
ArraySpec arraySpec;
if(ctx.expr() != null) {
RValue sizeVal = (RValue) visit(ctx.expr());
arrayDeclType.setArraySpec(new ArraySpec((ConstantValue) sizeVal));
arraySpec = new ArraySpec((ConstantValue) sizeVal);
} else {
arrayDeclType.setArraySpec(new ArraySpec());
arraySpec = new ArraySpec();
}
arrayDeclType.setType(new SymbolTypePointer(elementDeclType.getType(), arraySpec));
arrayDeclType.setElementDeclType(elementDeclType);
varDecl.setVarDeclType(arrayDeclType);
return null;
} else {
@ -2140,7 +2125,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visit(declArrayContext);
}
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();
scopeStack.pop();
varDecl.exitType();

View File

@ -78,7 +78,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
}
final long stringLength = constantString.getStringLength();
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);
if(getLog().isVerbosePass1CreateSsa()) {
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();
if(!(rValue instanceof ConstantValue) && lValueType instanceof SymbolTypeStruct) {
// 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());
if(!rValue.equals(rValueConstantified)) {
assignment.setrValue2(rValueConstantified);

View File

@ -93,7 +93,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
String localName = getRootName(constantVars);
final long stringLength = constString.getStringLength();
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);
rootConstant = newRootConstant;
}

View File

@ -606,7 +606,7 @@ public class Pass4CodeGeneration {
} else {
// Zero-fill variable
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);
asmDataChunk.addToAsm(AsmFormat.asmFix(variable.getAsmName()), asm);
}
@ -735,7 +735,7 @@ public class Pass4CodeGeneration {
} else {
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) {
dataChunk.addDataZeroFilled(getNumericType(elementType), paddingBytesAsm, (int) paddingSize, getEncoding(zeroValue));
} else {

View File

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

View File

@ -1,8 +1,10 @@
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.StructDefinition;
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.values.ConstantValue;
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());
}
@Override
public ArraySpec getArraySpec() {
if(getSymbolType() instanceof SymbolTypePointer)
return ((SymbolTypePointer) getSymbolType()).getArraySpec();
else
return null;
}
@Override
public List<String> getMemberNames(ProgramScope scope) {
if(getSymbolType() instanceof SymbolTypeStruct) {

View File

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

View File

@ -55,7 +55,7 @@ public class ValueSourceFactory {
return new ValueSourceZero(((StructZero) value).getTypeStruct(), null);
}
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)
return new ValueSourcePointerDereferenceSimple((PointerDereferenceSimple) value, valueType, null);
if(value instanceof PointerDereferenceIndexed)

View File

@ -36,11 +36,6 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase {
return valueType;
}
@Override
public ArraySpec getArraySpec() {
return valueArraySpec;
}
@Override
protected boolean isStructClassic() {
return getSymbolType() instanceof SymbolTypeStruct;
@ -87,7 +82,7 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase {
if(pointerDereferenceIndexed.getIndex() instanceof ConstantValue) {
// Unwind to (elmType*)&struct + OFFSET_MEMBER + idx
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 {
// Unwind to (elmType*)&struct + OFFSET_MEMBER + idx
Scope scope = programScope.getScope(currentBlock.getScope());

View File

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

View File

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

View File

@ -26,7 +26,7 @@ public class SizeOfConstants {
if(typeSizeConstant == null) {
// Constant not found - create it
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);
}
return typeSizeConstant.getConstantRef();
@ -77,7 +77,7 @@ public class SizeOfConstants {
// Constant not found - create it
Variable memberDef = structDefinition.getMember(memberName);
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);
}
return memberOffsetConstant.getConstantRef();

View File

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