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

Added support for var_model in .TGT-file. Closes #448

This commit is contained in:
jespergravgaard 2020-05-29 21:57:19 +02:00
parent 8fbe49f272
commit 1786d85ea5
6 changed files with 66 additions and 69 deletions

View File

@ -44,9 +44,6 @@ public class Compiler {
*/
private boolean enableLoopHeadConstant = false;
/** Variable optimization/memory area configuration to use (from command line parameter). */
private VariableBuilderConfig variableBuilderConfig;
/** The initial calling convention to use when compiling (from command line parameter). */
private Procedure.CallingConvention callingConvention;
@ -58,7 +55,7 @@ public class Compiler {
return program;
}
public void setDisableUplift(boolean disableUplift) {
void setDisableUplift(boolean disableUplift) {
this.disableUplift = disableUplift;
}
@ -66,14 +63,10 @@ public class Compiler {
program.setWarnFragmentMissing(warnFragmentMissing);
}
public void setWarnArrayType(boolean warnArrayType) {
void setWarnArrayType(boolean warnArrayType) {
program.setWarnArrayType(warnArrayType);
}
public void setVariableBuilderConfig(VariableBuilderConfig variableBuilderConfig) {
this.variableBuilderConfig = variableBuilderConfig;
}
public void setCallingConvention(Procedure.CallingConvention callingConvention) {
this.callingConvention = callingConvention;
}
@ -185,18 +178,11 @@ public class Compiler {
// Parse the files
KickCParser.FileContext cFileContext = cParser.getParser().file();
if(variableBuilderConfig == null) {
VariableBuilderConfig config = new VariableBuilderConfig();
VariableBuilderConfig.defaultPreConfig(config, getLog());
VariableBuilderConfig.defaultPostConfig(config, getLog());
this.variableBuilderConfig = config;
}
if(callingConvention == null) {
callingConvention = Procedure.CallingConvention.PHI_CALL;
}
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(cParser, cFileContext, program, variableBuilderConfig, callingConvention);
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(cParser, cFileContext, program, callingConvention);
pass0GenerateStatementSequence.generate();
StatementSequence sequence = program.getStatementSequence();

View File

@ -329,8 +329,8 @@ public class KickC implements Callable<Integer> {
List<String> settings = Arrays.asList(varModel.split(","));
settings = settings.stream().map(String::trim).collect(Collectors.toList());
try {
VariableBuilderConfig config = VariableBuilderConfig.fromSettings(settings, StatementSource.NONE, compiler.getLog());
compiler.setVariableBuilderConfig(config);
VariableBuilderConfig config = VariableBuilderConfig.fromSettings(settings, StatementSource.NONE);
program.getTargetPlatform().setVariableBuilderConfig(config);
} catch(CompileError e) {
System.err.println(e.getMessage());
return COMPILE_ERROR;

View File

@ -39,8 +39,15 @@ public class TargetPlatform {
/** Reserved zeropage addresses. */
private List<Integer> reservedZps = new ArrayList<>();
/** Configuration for the variable builder. */
private VariableBuilderConfig variableBuilderConfig;
public TargetPlatform(String name) {
this.name = name;
VariableBuilderConfig config = new VariableBuilderConfig();
VariableBuilderConfig.defaultPreConfig(config);
VariableBuilderConfig.defaultPostConfig(config);
this.variableBuilderConfig = config;
}
public String getName() {
@ -111,4 +118,12 @@ public class TargetPlatform {
public List<Integer> getReservedZps() {
return reservedZps;
}
public VariableBuilderConfig getVariableBuilderConfig() {
return variableBuilderConfig;
}
public void setVariableBuilderConfig(VariableBuilderConfig variableBuilderConfig) {
this.variableBuilderConfig = variableBuilderConfig;
}
}

View File

@ -47,7 +47,7 @@ public class VariableBuilderConfig {
* @param program The program log (used for error messages)
* @return A variable builder configuration
*/
public static VariableBuilderConfig fromSettings(List<String> settings, StatementSource statementSource, CompileLog log) {
public static VariableBuilderConfig fromSettings(List<String> settings, StatementSource statementSource) {
// Detect if the first setting is "full"
boolean full = false;
if(settings.size() > 0 && settings.get(0).equals(SETTING_FULL)) {
@ -56,13 +56,13 @@ public class VariableBuilderConfig {
}
VariableBuilderConfig config = new VariableBuilderConfig();
if(!full)
defaultPreConfig(config, log);
defaultPreConfig(config);
// Apply all settings
for(String setting : settings) {
config.addSetting(setting, log, statementSource);
config.addSetting(setting, statementSource);
}
if(!full)
defaultPostConfig(config, log);
defaultPostConfig(config);
return config;
}
@ -75,8 +75,8 @@ public class VariableBuilderConfig {
* @param config The variable builder configuration
* @param log The compile log
*/
public static void defaultPreConfig(VariableBuilderConfig config, CompileLog log) {
config.addSetting("ssa_zp", log, StatementSource.NONE);
public static void defaultPreConfig(VariableBuilderConfig config) {
config.addSetting("ssa_zp", StatementSource.NONE);
}
/**
@ -85,15 +85,15 @@ public class VariableBuilderConfig {
* @param config The variable builder configuration
* @param log The compile log
*/
public static void defaultPostConfig(VariableBuilderConfig config, CompileLog log) {
public static void defaultPostConfig(VariableBuilderConfig config) {
// Arrays are always load/store variables in main memory
config.addSetting("array_ma_mem", log, StatementSource.NONE);
config.addSetting("array_ma_mem", StatementSource.NONE);
// Global struct values are always load/store variables in main memory
config.addSetting("global_struct_ma_mem", log, StatementSource.NONE);
config.addSetting("global_struct_ma_mem", StatementSource.NONE);
// Parameters are always passed using single-static-assignment
config.addSetting("parameter_ssa", log, StatementSource.NONE);
config.addSetting("parameter_ssa", StatementSource.NONE);
// Pointers are always on zeropage
config.addSetting("pointer_zp", log, StatementSource.NONE);
config.addSetting("pointer_zp", StatementSource.NONE);
}
/** The different scopes. */
@ -170,7 +170,7 @@ public class VariableBuilderConfig {
this.settings = new HashMap<>();
}
public void addSetting(String pragmaParam, CompileLog log, StatementSource statementSource) {
public void addSetting(String pragmaParam, StatementSource statementSource) {
List<String> paramElements = new ArrayList<>(Arrays.asList(pragmaParam.split("_")));
List<Scope> scopes = getScopes(paramElements);
List<Type> types = getTypes(paramElements);

View File

@ -5,6 +5,8 @@ import dk.camelot64.kickc.SourceLoader;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.TargetCpu;
import dk.camelot64.kickc.model.TargetPlatform;
import dk.camelot64.kickc.model.VariableBuilderConfig;
import dk.camelot64.kickc.model.statements.StatementSource;
import javax.json.*;
import javax.json.stream.JsonParsingException;
@ -14,9 +16,9 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Parser for target platform files xxx.tgt.
@ -68,11 +70,11 @@ public class CTargetPlatformParser {
// A range of zeropage addresses
final int split = zpReserveStr.indexOf("..");
final String startStr = zpReserveStr.substring(0, split);
final String endStr = zpReserveStr.substring(split+2);
final Number startZp = NumberParser.parseLiteral(startStr);
final Number endZp = NumberParser.parseLiteral(endStr);
final String endStr = zpReserveStr.substring(split + 2);
final Number startZp = NumberParser.parseLiteral(startStr);
final Number endZp = NumberParser.parseLiteral(endStr);
int zp = startZp.intValue();
while(zp<=endZp.intValue()) {
while(zp <= endZp.intValue()) {
reservedZps.add(zp);
zp++;
}
@ -87,16 +89,12 @@ public class CTargetPlatformParser {
}
}
{
final JsonObject defines = platformJson.getJsonObject("defines");
if(defines != null) {
final Set<String> macroNames = defines.keySet();
final LinkedHashMap<String, String> macros = new LinkedHashMap<>();
for(String macroName : macroNames) {
final JsonValue jsonValue = defines.get(macroName);
final String macroBody = jsonValue.toString();
macros.put(macroName, macroBody);
}
targetPlatform.setDefines(macros);
final String varModel = platformJson.getString("var_model", null);
if(varModel != null) {
List<String> settings = Arrays.asList(varModel.split(","));
settings = settings.stream().map(String::trim).collect(Collectors.toList());
VariableBuilderConfig config = VariableBuilderConfig.fromSettings(settings, StatementSource.NONE);
targetPlatform.setVariableBuilderConfig(config);
}
}
return targetPlatform;

View File

@ -46,17 +46,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
private Stack<Scope> scopeStack;
/** The memory area used by default for variables. */
private Variable.MemoryArea defaultMemoryArea;
/** Configuration for the variable builder. */
private VariableBuilderConfig variableBuilderConfig;
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, VariableBuilderConfig variableBuilderConfig, Procedure.CallingConvention initialCallingConvention) {
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, Procedure.CallingConvention initialCallingConvention) {
this.cParser = cParser;
this.fileCtx = fileCtx;
this.program = program;
this.sequence = program.getStatementSequence();
this.scopeStack = new Stack<>();
this.defaultMemoryArea = Variable.MemoryArea.ZEROPAGE_MEMORY;
this.variableBuilderConfig = variableBuilderConfig;
this.currentCallingConvention = initialCallingConvention;
scopeStack.push(program.getScope());
}
@ -122,7 +119,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
public Object visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) {
List<TerminalNode> settingNodes = new ArrayList<>(ctx.NAME());
List<String> settings = settingNodes.stream().map(ParseTree::getText).collect(Collectors.toList());
this.variableBuilderConfig = VariableBuilderConfig.fromSettings(settings, new StatementSource(ctx), program.getLog());
final VariableBuilderConfig variableBuilderConfig = VariableBuilderConfig.fromSettings(settings, new StatementSource(ctx));
program.getTargetPlatform().setVariableBuilderConfig(variableBuilderConfig);
return null;
}
@ -372,7 +370,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, variableBuilderConfig);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), true, varDecl.getEffectiveType(), null, varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable param = varBuilder.build();
varDecl.exitType();
return param;
@ -645,7 +643,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** The declared type (variable level) */
private VariableDeclType varDeclType;
public VariableDeclaration() {
VariableDeclaration() {
this.declType = new VariableDeclType();
}
@ -677,7 +675,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/** If the type is SymbolTypePointer this holds the declaration type of the elements. */
VariableDeclType elementDeclType;
public VariableDeclType() {
VariableDeclType() {
this.typeDirectives = new ArrayList<>();
}
@ -693,23 +691,23 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return arraySpec;
}
public List<Directive> getTypeDirectives() {
List<Directive> getTypeDirectives() {
return typeDirectives;
}
public void setTypeDirectives(List<Directive> directives) {
void setTypeDirectives(List<Directive> directives) {
this.typeDirectives = directives;
}
public void setElementDeclType(VariableDeclType elementDeclType) {
void setElementDeclType(VariableDeclType elementDeclType) {
this.elementDeclType = elementDeclType;
}
public void setArraySpec(ArraySpec arraySpec) {
void setArraySpec(ArraySpec arraySpec) {
this.arraySpec = arraySpec;
}
public VariableDeclType getElementDeclType() {
VariableDeclType getElementDeclType() {
return elementDeclType;
}
}
@ -779,7 +777,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return dirs;
}
public List<Comment> getDeclComments() {
List<Comment> getDeclComments() {
return declComments;
}
@ -795,7 +793,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.declType.setType(type);
}
public void setVarDeclType(VariableDeclType varDeclType) {
void setVarDeclType(VariableDeclType varDeclType) {
this.varDeclType = varDeclType;
}
@ -803,7 +801,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
return varDeclType;
}
public void setDeclComments(List<Comment> declComments) {
void setDeclComments(List<Comment> declComments) {
this.declComments = declComments;
}
@ -822,7 +820,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/**
* Push the current type declaration handler onto the stack and initialize a new empty current type declaration handler.
*/
void varDeclPush() {
private void varDeclPush() {
varDeclStack.push(varDecl);
varDecl = new VariableDeclaration();
}
@ -830,7 +828,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
/**
* Discard the current type declaration handler and pop the last one fron the stack.
*/
void varDeclPop() {
private void varDeclPop() {
this.varDecl = varDeclStack.pop();
}
@ -924,7 +922,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
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, variableBuilderConfig);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, effectiveType, effectiveArraySpec, effectiveDirectives, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable variable = varBuilder.build();
if(isStructMember && (initializer != null))
throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), statementSource);
@ -1007,7 +1005,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
sequence.getStatements().remove(sequence.getStatements().size() - 1);
// Add a constant variable
Scope scope = getCurrentScope();
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, variableBuilderConfig);
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable variable = varBuilder.build();
// Set constant value
variable.setInitValue(getConstInitValue(constantArrayKickAsm, null, statementSource));
@ -1530,7 +1528,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, variableBuilderConfig);
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, varType, null, varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
lValue = varBuilder.build();
} else {
lValue = getCurrentScope().findVariable(varName);
@ -1984,7 +1982,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, variableBuilderConfig);
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, varDecl.getEffectiveType(), varDecl.getEffectiveArraySpec(), varDecl.getEffectiveDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
final Variable typeDefVar = varBuilder.build();
scopeStack.pop();
varDecl.exitType();