From 1786d85ea5e2069a347b92156c798616ec956154 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Fri, 29 May 2020 21:57:19 +0200 Subject: [PATCH] Added support for var_model in .TGT-file. Closes #448 --- .../java/dk/camelot64/kickc/Compiler.java | 20 ++------- src/main/java/dk/camelot64/kickc/KickC.java | 4 +- .../camelot64/kickc/model/TargetPlatform.java | 15 +++++++ .../kickc/model/VariableBuilderConfig.java | 24 +++++------ .../kickc/parser/CTargetPlatformParser.java | 30 +++++++------ .../Pass0GenerateStatementSequence.java | 42 +++++++++---------- 6 files changed, 66 insertions(+), 69 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 028ac92d9..c1c42e999 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -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(); diff --git a/src/main/java/dk/camelot64/kickc/KickC.java b/src/main/java/dk/camelot64/kickc/KickC.java index bc8578eb0..9664292cb 100644 --- a/src/main/java/dk/camelot64/kickc/KickC.java +++ b/src/main/java/dk/camelot64/kickc/KickC.java @@ -329,8 +329,8 @@ public class KickC implements Callable { List 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; diff --git a/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java b/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java index d89e448ed..4a7f6f145 100644 --- a/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java +++ b/src/main/java/dk/camelot64/kickc/model/TargetPlatform.java @@ -39,8 +39,15 @@ public class TargetPlatform { /** Reserved zeropage addresses. */ private List 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 getReservedZps() { return reservedZps; } + + public VariableBuilderConfig getVariableBuilderConfig() { + return variableBuilderConfig; + } + + public void setVariableBuilderConfig(VariableBuilderConfig variableBuilderConfig) { + this.variableBuilderConfig = variableBuilderConfig; + } } diff --git a/src/main/java/dk/camelot64/kickc/model/VariableBuilderConfig.java b/src/main/java/dk/camelot64/kickc/model/VariableBuilderConfig.java index 6e541afc7..2583d79da 100644 --- a/src/main/java/dk/camelot64/kickc/model/VariableBuilderConfig.java +++ b/src/main/java/dk/camelot64/kickc/model/VariableBuilderConfig.java @@ -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 settings, StatementSource statementSource, CompileLog log) { + public static VariableBuilderConfig fromSettings(List 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 paramElements = new ArrayList<>(Arrays.asList(pragmaParam.split("_"))); List scopes = getScopes(paramElements); List types = getTypes(paramElements); diff --git a/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java b/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java index 9e5a11436..f691d08d1 100644 --- a/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/CTargetPlatformParser.java @@ -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 macroNames = defines.keySet(); - final LinkedHashMap 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 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; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 274576e95..13fe5a844 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -46,17 +46,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor 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 settingNodes = new ArrayList<>(ctx.NAME()); List 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(); } @@ -693,23 +691,23 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor getTypeDirectives() { + List getTypeDirectives() { return typeDirectives; } - public void setTypeDirectives(List directives) { + void setTypeDirectives(List 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 getDeclComments() { + List getDeclComments() { return declComments; } @@ -795,7 +793,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor declComments) { + void setDeclComments(List declComments) { this.declComments = declComments; } @@ -822,7 +820,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor effectiveDirectives = varDecl.getEffectiveDirectives(); final List 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