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:
parent
8fbe49f272
commit
1786d85ea5
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user