From 6fc33136567cb4a0d63867f4e4a9e0e8c11820bb Mon Sep 17 00:00:00 2001 From: EgonOlsen Date: Fri, 26 Jul 2024 15:42:16 +0200 Subject: [PATCH] First try on a Python compile target --- src/main/java/com/sixtyfour/Loader.java | 22 +- .../cbmnative/powerscript/TransformerPs.java | 4 +- .../cbmnative/python/OptimizerPy.java | 73 ++ .../cbmnative/python/PlatformPy.java | 95 +++ .../cbmnative/python/Pythonizer.java | 115 +++ .../cbmnative/python/TransformerPy.java | 364 ++++++++++ .../cbmnative/python/generators/AbsPy.java | 12 + .../cbmnative/python/generators/AddPy.java | 13 + .../cbmnative/python/generators/AndPy.java | 13 + .../cbmnative/python/generators/AtnPy.java | 12 + .../cbmnative/python/generators/BrkPy.java | 25 + .../python/generators/CalculationPy.java | 44 ++ .../cbmnative/python/generators/CmpPy.java | 36 + .../python/generators/ComparisonPy.java | 42 ++ .../cbmnative/python/generators/CosPy.java | 12 + .../cbmnative/python/generators/DivPy.java | 13 + .../cbmnative/python/generators/EqPy.java | 13 + .../cbmnative/python/generators/ExpPy.java | 12 + .../python/generators/GeneratorBasePy.java | 88 +++ .../python/generators/GeneratorListPy.java | 84 +++ .../cbmnative/python/generators/GtPy.java | 13 + .../cbmnative/python/generators/GteqPy.java | 13 + .../cbmnative/python/generators/IntPy.java | 12 + .../cbmnative/python/generators/JePy.java | 31 + .../cbmnative/python/generators/JmpPy.java | 30 + .../cbmnative/python/generators/JnePy.java | 31 + .../cbmnative/python/generators/JsrPy.java | 37 + .../python/generators/JumpBasePy.java | 50 ++ .../generators/LineNumberGeneratorPy.java | 45 ++ .../cbmnative/python/generators/LogPy.java | 12 + .../cbmnative/python/generators/LtPy.java | 13 + .../cbmnative/python/generators/LteqPy.java | 13 + .../cbmnative/python/generators/MovPy.java | 120 ++++ .../cbmnative/python/generators/MovbPy.java | 106 +++ .../cbmnative/python/generators/MulPy.java | 13 + .../cbmnative/python/generators/NegPy.java | 13 + .../cbmnative/python/generators/NeqPy.java | 13 + .../cbmnative/python/generators/NopPy.java | 25 + .../cbmnative/python/generators/NotPy.java | 12 + .../cbmnative/python/generators/OrPy.java | 13 + .../cbmnative/python/generators/PopPy.java | 29 + .../cbmnative/python/generators/PowPy.java | 13 + .../cbmnative/python/generators/PushPy.java | 29 + .../cbmnative/python/generators/RndPy.java | 12 + .../cbmnative/python/generators/RtsPy.java | 28 + .../cbmnative/python/generators/SgnPy.java | 12 + .../cbmnative/python/generators/ShlPy.java | 13 + .../cbmnative/python/generators/ShrPy.java | 13 + .../cbmnative/python/generators/SinPy.java | 12 + .../cbmnative/python/generators/SqrPy.java | 12 + .../cbmnative/python/generators/SubPy.java | 13 + .../cbmnative/python/generators/TanPy.java | 12 + .../cbmnative/python/generators/XorPy.java | 13 + src/main/resources/subroutines.py | 665 ++++++++++++++++++ .../com/sixtyfour/test/TransformerJsTest.java | 435 ++++++------ .../com/sixtyfour/test/TransformerPsTest.java | 235 +++---- .../com/sixtyfour/test/TransformerPyTest.java | 79 +++ src/test/resources/transform/test23.bas | 6 +- 58 files changed, 2994 insertions(+), 344 deletions(-) create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/OptimizerPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/PlatformPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/Pythonizer.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/TransformerPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/AbsPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/AddPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/AndPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/AtnPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/BrkPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/CalculationPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/CmpPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/ComparisonPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/CosPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/DivPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/EqPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/ExpPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorBasePy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorListPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/GtPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/GteqPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/IntPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/JePy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/JmpPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/JnePy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/JsrPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/JumpBasePy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/LineNumberGeneratorPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/LogPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/LtPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/LteqPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/MovPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/MovbPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/MulPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/NegPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/NeqPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/NopPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/NotPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/OrPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/PopPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/PowPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/PushPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/RndPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/RtsPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/SgnPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/ShlPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/ShrPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/SinPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/SqrPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/SubPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/TanPy.java create mode 100644 src/main/java/com/sixtyfour/cbmnative/python/generators/XorPy.java create mode 100644 src/main/resources/subroutines.py create mode 100644 src/test/java/com/sixtyfour/test/TransformerPyTest.java diff --git a/src/main/java/com/sixtyfour/Loader.java b/src/main/java/com/sixtyfour/Loader.java index 16b797b4..3fa04761 100644 --- a/src/main/java/com/sixtyfour/Loader.java +++ b/src/main/java/com/sixtyfour/Loader.java @@ -78,12 +78,28 @@ public static byte[] loadBlob(InputStream is) { * @return the string[] the program splitted into it's lines */ public static String[] loadProgram(InputStream prg) { + return loadProgram(prg, false); + } + + /** + * Load a program from a text file into a String[] array. It assumes that the + * text is UTF-8 encoded. Line separator is \n. + * + * @param prg the program's input stream + * @param noTrim don't trim input + * @return the string[] the program splitted into it's lines + */ + public static String[] loadProgram(InputStream prg, boolean noTrim) { List lines = new ArrayList(); try (BufferedReader br = new BufferedReader(new InputStreamReader(prg, "UTF-8"))) { while (br.ready()) { String line = br.readLine(); - if (line != null && line.trim().length() > 0) { - lines.add(line.trim()); + if (noTrim) { + lines.add(line); + } else { + if (line != null && line.trim().length() > 0) { + lines.add(line.trim()); + } } } } catch (Exception e) { @@ -91,7 +107,7 @@ public static String[] loadProgram(InputStream prg) { } return lines.toArray(new String[lines.size()]); } - + /** * Load a program from a text file into a String[] array. It assumes that the * text is UTF-8 encoded. Line separator is \n. diff --git a/src/main/java/com/sixtyfour/cbmnative/powerscript/TransformerPs.java b/src/main/java/com/sixtyfour/cbmnative/powerscript/TransformerPs.java index 7b78a017..c69fb0a7 100644 --- a/src/main/java/com/sixtyfour/cbmnative/powerscript/TransformerPs.java +++ b/src/main/java/com/sixtyfour/cbmnative/powerscript/TransformerPs.java @@ -28,7 +28,7 @@ /** * The transformer for the Powerscript/-shell target platform. It generates * Powerscript code linked together with a Powerscript runtime. The result can - * either be run in a Powershell. + * be run in a Powershell. * * @author EgonOlsen * @@ -133,7 +133,7 @@ public List transform(CompilerConfig config, MemoryConfig memConfig, Mac return res; } - + private List replaceBrackets(List lines) { return lines.stream().map(p -> replaceInternal(p)).collect(Collectors.toList()); } diff --git a/src/main/java/com/sixtyfour/cbmnative/python/OptimizerPy.java b/src/main/java/com/sixtyfour/cbmnative/python/OptimizerPy.java new file mode 100644 index 00000000..2bc510f4 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/OptimizerPy.java @@ -0,0 +1,73 @@ +package com.sixtyfour.cbmnative.python; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.sixtyfour.cbmnative.Optimizer; +import com.sixtyfour.cbmnative.PlatformProvider; +import com.sixtyfour.cbmnative.ProgressListener; +import com.sixtyfour.config.CompilerConfig; + +/** + * An optimizer implementation for the Python target platform. + * Nothing in here for now... + * + * @author EgonOlsen + * + */ +public class OptimizerPy implements Optimizer { + + + @Override + public List optimize(CompilerConfig config, PlatformProvider platform, List code, + ProgressListener pg) { + List res = new ArrayList<>(); + Set globals = new HashSet<>(); + boolean inDef = false; + int insertAt = -1; + + for (String line:code) { + if (line.contains("\n")) { + res.addAll(Arrays.asList(line.split("\n"))); + } else { + res.add(line); + } + } + + code = res; + res = new ArrayList<>(); + + for (String line:code) { + if (line.startsWith("def ") || line.isEmpty()) { + if (inDef) { + if (insertAt!=-1) { + for (String global:globals) { + res.add(insertAt+1, global); + } + } + globals.clear(); + } + inDef = line.startsWith("def "); + if (inDef) { + insertAt = res.size(); + } else { + insertAt = -1; + } + } + if (inDef) { + if (line.trim().startsWith("global ")) { + globals.add(line); + } else { + res.add(line); + } + } else { + res.add(line); + } + } + return res; + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/PlatformPy.java b/src/main/java/com/sixtyfour/cbmnative/python/PlatformPy.java new file mode 100644 index 00000000..de2543c2 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/PlatformPy.java @@ -0,0 +1,95 @@ +package com.sixtyfour.cbmnative.python; + +import com.sixtyfour.cbmnative.Generator; +import com.sixtyfour.cbmnative.Optimizer; +import com.sixtyfour.cbmnative.PlatformProvider; +import com.sixtyfour.cbmnative.Transformer; +import com.sixtyfour.cbmnative.Unlinker; +import com.sixtyfour.config.CompilerConfig; + +/** + * A PlatformProvider implementation for the Python target platform. + * + * @author EgonOlsen + * + */ +public class PlatformPy implements PlatformProvider { + + @Override + public int getStackSize() { + return 100; + } + + @Override + public int getForStackSize() { + return 100; + } + + @Override + public Optimizer getOptimizer() { + return new OptimizerPy(); + } + + @Override + public Transformer getTransformer() { + return new TransformerPy(); + } + + @Override + public Unlinker getUnlinker() { + return null; + } + + @Override + public boolean useLooseTypes() { + return true; + } + + @Override + public int getMaxHeaderAddress() { + return 0; + } + + @Override + public int getBaseAddress() { + return 0; + } + + @Override + public void overrideConfig(CompilerConfig conf) { + conf.setLoopOptimizations(false); + conf.setIntOptimizations(false); + conf.setShiftOptimizations(false); + } + + @Override + public Generator getGenerator(String orgLine) { + return null; + } + + @Override + public int getBasicMemoryEndAddress() { + return 0; + } + + @Override + public int getBasicBufferAddress() { + return 0; + } + + @Override + public boolean supportsCompression() { + return false; + } + + @Override + public boolean supportsBigRam() { + return false; + } + + @Override + public boolean supportsVarRelocation() { + return false; + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/Pythonizer.java b/src/main/java/com/sixtyfour/cbmnative/python/Pythonizer.java new file mode 100644 index 00000000..856e5891 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/Pythonizer.java @@ -0,0 +1,115 @@ +package com.sixtyfour.cbmnative.python; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles indentions and other Python related shenanigans + * + * @author EgonOlsen + * + */ +public class Pythonizer { + + private int level=0; + + public Pythonizer() { + // + } + + public Pythonizer(int level) { + this.level=level; + } + + public void indent() { + level++; + } + + public void outdent() { + level--; + } + + public String process(String cmd) { + cmd = removeDollar(cmd); + StringBuilder sb = new StringBuilder(); + for (int i=0; i unifyIndentions(List code) { + List res = new ArrayList<>(); + for (String line:code) { + line=line.replace("\t", " "); + res.add(line); + } + return res; + } + + public String processGlobal(String cmd) { + cmd = removeDollar(cmd); + StringBuilder sb = new StringBuilder(); + if (!cmd.startsWith("def ")) { + for (int i=0; i transform(CompilerConfig config, MemoryConfig memConfig, Machine machine, + PlatformProvider platform, List code) { + Logger.log("Compiling into python code..."); + + addContinues(code); + + List res = new ArrayList<>(); + List consts = new ArrayList(); + List vars = new ArrayList(); + List mnems = new ArrayList(); + List subs = new ArrayList(); + List datas = new ArrayList(); + + subs.add("# *** SUBROUTINES ***"); + + List subys = Arrays.asList(Loader.loadProgram(this.getClass().getResourceAsStream("/subroutines.py"), true)); + subys = platform.getOptimizer().optimize(config, platform, subys, config.getProgressListener()); + subs.addAll(subys); + AbstractTransformer.addExtensionSubroutines(subs, "py"); + + + Pythonizer py = new Pythonizer(); + Pythonizer pyInd = new Pythonizer(1); + + res.add("import math"); + res.add("import random"); + res.add("import time"); + res.add("import keyboard"); + res.add("def INIT():"); + py.indent(); + res.add(py.processGlobal("X_REG=0.0")); + res.add(py.processGlobal("Y_REG=0.0")); + res.add(py.processGlobal("C_REG=0.0")); + res.add(py.processGlobal("D_REG=0.0")); + res.add(py.processGlobal("E_REG=0.0")); + res.add(py.processGlobal("F_REG=0.0")); + res.add(py.processGlobal("A_REG=0")); + res.add(py.processGlobal("B_REG=0")); + res.add(py.processGlobal("G_REG=0")); + res.add(py.processGlobal("CMD_NUM=0")); + res.add(py.processGlobal("CHANNEL=0")); + res.add(py.processGlobal("JUMP_TARGET=\"\"")); + res.add(py.processGlobal("USR_PARAM=0")); + res.add(py.processGlobal("_line=\"\"")); + res.add(py.processGlobal("_stack=[]")); + res.add(py.processGlobal("_forstack=[]")); + res.add(py.processGlobal("_memory=[0] * 65535")); + res.add(py.processGlobal("_zeroflag=0")); + res.add(py.processGlobal("_timeOffset=0")); + res.add(py.processGlobal("_time=0")); + res.add(py.processGlobal("_inputQueue=[]")); + + Map map = ConstantExtractor.getAllConstantMaps(); + for (Entry entry : map.entrySet()) { + res.add(py.processGlobal(entry.getKey() + "=" + entry.getValue())); + } + + int cnt = 0; + List strVars = new ArrayList(); + List strArrayVars = new ArrayList(); + Map name2label = new HashMap(); + + GeneratorContext context = new GeneratorContext(config, machine); + for (String line : code) { + String cmd = line; + String orgLine = line; + + int sp = line.indexOf(" "); + if (sp != -1) { + line = line.substring(sp).trim(); + } + + cnt = extractData(platform, machine, consts, vars, strVars, strArrayVars, name2label, cnt, line); + + Generator pm = GeneratorListPy.getGenerator(orgLine); + if (pm != null) { + pm.generateCode(context, orgLine, mnems, subs, name2label); + } else { + if (cmd.endsWith(":") || cmd.startsWith("CONT")) { + mnems.add(cmd); + } else { + mnems.add("# ignored: " + cmd); + } + } + } + + datas = createDatas(py, machine); + + // close the last function body + res.addAll(globalize(py, consts)); + res.addAll(datas); + vars.addAll(strVars); + vars.addAll(strArrayVars); + res.addAll(globalize(py, vars)); + py.outdent(); + res.addAll(globalize(pyInd, mnems)); + res.addAll(subs); + res = py.unifyIndentions(res); + + return res; + } + + + private List globalize(Pythonizer py, List lines) { + List res = new ArrayList<>(); + for (String line:lines) { + String sub = py.processGlobal(line); + String[] subs = sub.split("\n"); + if (subs.length>1) { + res.addAll(Arrays.asList(subs)); + } else { + res.add(sub); + } + } + return res; + } + + private List createDatas(Pythonizer py, Machine machine) { + DataStore datas = machine.getDataStore(); + List ret = new ArrayList(); + if (datas.size() > 0) { + String strDat = py.processGlobal("_datas=["); + ret.add(py.processGlobal("_dataPtr=0")); + + datas.restore(); + Object obj = null; + while ((obj = datas.read()) != null) { + Type type = Type.STRING; + if (VarUtils.isInteger(obj)) { + type = Type.INTEGER; + } else if (VarUtils.isFloat(obj) || VarUtils.isDouble(obj)) { + type = Type.REAL; + } + if (obj.toString().equals("\\0")) { + obj = ""; + } + + if (type == Type.INTEGER) { + strDat += obj.toString() + ","; + } else if (type == Type.REAL) { + strDat += obj.toString() + ","; + } else { + strDat += "\"" + obj.toString() + "\"" + ","; + } + } + strDat = strDat.substring(0, strDat.length() - 1) + "]"; + ret.add(strDat); + } + return ret; + } + + private void addContinues(List code) { + int cnt = 0; + int forCnt = 0; + for (int i = 0; i < code.size(); i++) { + String line = code.get(i); + if (line.equals("JSR GOSUB")) { + String cont = "GOSUBCONT" + cnt++; + int add = 2; + // Catch the NOP introduced by a gosub in a list of conditionals. + // It would be better to search for the first non-NOP instead, but I can't be + // bothered + if (code.get(i + 1).equals("NOP")) { + add = 3; + } + code.add(i + add, cont + ":"); + code.set(i, "JSR GOSUB(\"" + cont + "\")"); + } else if (line.equals("JSR INITFOR")) { + String cont = "FORLOOP" + forCnt++; + String var = code.get(i - 1); + var = var.substring(var.indexOf("(") + 1, var.lastIndexOf("{")); + code.add(i + 1, cont + ":"); + code.set(i, "JSR INITFOR(\"" + cont + "\",\"VAR_" + var + "\")"); + code.set(i - 1, "NOP"); + } else if (line.equals("JSR NEXT")) { + String var = code.get(i - 1); + if (var.contains("{}")) { + var = "VAR_" + var.substring(var.indexOf("(") + 1, var.indexOf("{")); + } else { + var = "0"; + } + code.set(i - 1, "NOP"); + code.set(i, "JSR NEXT(\"" + var + "\")"); + } + } + + } + + private int extractData(PlatformProvider platform, Machine machine, List consts, List vars, + List strVars, List strArrayVars, Map name2label, int cnt, String line) { + String[] parts = line.split(",", 2); + List tmp = new ArrayList(); + for (int p = 0; p < parts.length; p++) { + String part = parts[p]; + if (part.contains("{") && part.endsWith("}")) { + int pos = part.lastIndexOf("{"); + String name = part.substring(0, pos); + + Variable vary = machine.getVariable(name); + + name = name.replace("%", "_int"); + name = name.replace("[]", "_array"); + if (name.startsWith("#")) { + Type type = Type.valueOf(part.substring(pos + 1, part.length() - 1)); + String keyName = name; + if (type == Type.STRING) { + name = "$" + name.substring(1); + keyName = name; + } + + if (!name2label.containsKey(keyName)) { + String label = "CONST_" + (cnt++); + name2label.put(keyName, label); + name = name.substring(1); + + if (type == Type.INTEGER) { + consts.add(label + "=" + name + ""); + } else if (type == Type.REAL) { + consts.add(label + "=" + name + ""); + } else if (type == Type.STRING) { + consts.add(label + "=\"" + name + "\""); + } + } + } else { + if (!name2label.containsKey(name)) { + tmp.clear(); + String label = "VAR_" + name; + name2label.put(name, label); + + Type type = Type.valueOf(part.substring(pos + 1, part.length() - 1)); + if (name.endsWith("_array")) { + String init="[0]"; + if (type == Type.STRING) { + init="[\"\"]"; + } + tmp.add(label + "="+init+"*"+vary.elements()); + } else { + if (type == Type.INTEGER) { + tmp.add(label + "=0"); + } else if (type == Type.REAL) { + tmp.add(label + "=0.0"); + } else if (type == Type.STRING) { + tmp.add(label + "=\"\""); + } + } + if (name.contains("$")) { + if (name.endsWith("_array")) { + strArrayVars.addAll(tmp); + } else { + strVars.addAll(tmp); + } + } else { + vars.addAll(tmp); + } + } + } + } + } + + return cnt; + } + + @Override + public void setVariableStart(int variableStart) { + // + } + + @Override + public int getStringMemoryEnd() { + return 0; + } + + @Override + public void setStringMemoryEnd(int stringMemoryEnd) { + // + } + + @Override + public int getVariableStart() { + return 0; + } + + @Override + public int getStartAddress() { + return 0; + } + + @Override + public void setStartAddress(int addr) { + // + } + + @Override + public int getRuntimeStart() { + return 0; + } + + @Override + public void setRuntimeStart(int runtimeStart) { + // + } + + @Override + public boolean isOptimizedTempStorage() { + return false; + } + + @Override + public void setOptimizedTempStorage(boolean optimizedTemp) { + // + } + + @Override + public List createCaller(final String calleeName) { + return null; + } + + public boolean isOptimizedStringPointers() { + return false; + } + + @Override + public void setOptimizedStringPointers(boolean optimized) { + // + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/AbsPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/AbsPy.java new file mode 100644 index 00000000..6227a294 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/AbsPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class AbsPy extends CalculationPy { + + public AbsPy() { + super("ABS", "abs({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/AddPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/AddPy.java new file mode 100644 index 00000000..133bf29b --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/AddPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class AddPy extends CalculationPy { + + public AddPy() { + super("ADD", "{to}+{from}"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/AndPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/AndPy.java new file mode 100644 index 00000000..69843817 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/AndPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class AndPy extends CalculationPy { + + public AndPy() { + super("AND", "int({to}) and int({from})"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/AtnPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/AtnPy.java new file mode 100644 index 00000000..d587d8b7 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/AtnPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class AtnPy extends CalculationPy { + + public AtnPy() { + super("ATN", "math.atan({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/BrkPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/BrkPy.java new file mode 100644 index 00000000..f7e58d73 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/BrkPy.java @@ -0,0 +1,25 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; + +/** + * @author EgonOlsen + * + */ +public class BrkPy extends GeneratorBasePy { + + @Override + public String getMnemonic() { + return "BRK"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + nCode.add("raise Exception(\"break\")"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/CalculationPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/CalculationPy.java new file mode 100644 index 00000000..a8414fd0 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/CalculationPy.java @@ -0,0 +1,44 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.cbmnative.Operands; + +/** + * @author EgonOlsen + * + */ +public abstract class CalculationPy extends GeneratorBasePy { + + private String mnemonic; + private String calcString; + + CalculationPy(String mnemonic, String calcString) { + this.mnemonic = mnemonic; + this.calcString = calcString; + } + + @Override + public String getMnemonic() { + return mnemonic; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Operands ops = new Operands(line, name2label); + + Operand source = ops.getSource(); + Operand target = ops.getTarget(); + + String from = getOpName(source); + String to = getOpName(target); + nCode.add(to + "=" + calcString.replace("{to}", to).replace("{from}", from)); + truncInteger(nCode, target); + + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/CmpPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/CmpPy.java new file mode 100644 index 00000000..b2258fda --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/CmpPy.java @@ -0,0 +1,36 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.cbmnative.Operands; + +/** + * @author EgonOlsen + * + */ +public class CmpPy extends GeneratorBasePy { + + @Override + public String getMnemonic() { + return "CMP"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Operands ops = new Operands(line, name2label); + + Operand source = ops.getSource(); + Operand target = ops.getTarget(); + + String from = getOpName(source); + String to = getOpName(target); + + nCode.add("global _zeroflag"); + nCode.add("_zeroflag=(0 if " + to + "==" + from + " else 1)"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/ComparisonPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/ComparisonPy.java new file mode 100644 index 00000000..3a5a4fc5 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/ComparisonPy.java @@ -0,0 +1,42 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.cbmnative.Operands; + +/** + * @author EgonOlsen + * + */ +public abstract class ComparisonPy extends GeneratorBasePy { + + private String mnemonic; + private String operator; + + ComparisonPy(String mnemonic, String operator) { + this.mnemonic = mnemonic; + this.operator = operator; + } + + @Override + public String getMnemonic() { + return mnemonic; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Operands ops = new Operands(line, name2label); + + Operand source = ops.getSource(); + Operand target = ops.getTarget(); + + String from = getOpName(source); + String to = getOpName(target); + nCode.add(to + "= (-1 if " + to + operator + from + " else 0)"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/CosPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/CosPy.java new file mode 100644 index 00000000..f0e9a90b --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/CosPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class CosPy extends CalculationPy { + + public CosPy() { + super("COS", "math.cos({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/DivPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/DivPy.java new file mode 100644 index 00000000..07bfd4b5 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/DivPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class DivPy extends CalculationPy { + + public DivPy() { + super("DIV", "{to}/{from}"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/EqPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/EqPy.java new file mode 100644 index 00000000..627d7bc4 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/EqPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class EqPy extends ComparisonPy { + + EqPy() { + super("EQ", "=="); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/ExpPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/ExpPy.java new file mode 100644 index 00000000..6eaddae5 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/ExpPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class ExpPy extends CalculationPy { + + public ExpPy() { + super("EXP", "math.exp({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorBasePy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorBasePy.java new file mode 100644 index 00000000..b300128f --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorBasePy.java @@ -0,0 +1,88 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.Generator; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.elements.Type; +import com.sixtyfour.util.ConstantExtractor; + +public abstract class GeneratorBasePy implements Generator { + + protected boolean checkSpecialWriteVars(List nCode, Operand target, Operand source) { + if (target.getAddress().equals("VAR_TI$")) { + String val = source.isRegister() ? source.getRegisterName() : source.getAddress(); + nCode.add("WRITETID("+val + ")"); + return true; + } + return false; + } + + protected boolean checkSpecialReadVars(List nCode, Operand target, Operand source) { + if (source.getAddress() != null) { + if (source.getAddress().equals("VAR_ST")) { + nCode.add("READSTATUS()"); + return true; + } else if (source.getAddress().equals("VAR_TI")) { + nCode.add("READTI()"); + return true; + } else if (source.getAddress().equals("VAR_TI$")) { + nCode.add("READTID()"); + return true; + } + } + return false; + } + + protected String getOpName(Operand op) { + String name = op.isRegister() ? op.getRegisterName() + : op.getAddress().replace("%", "_int").replace("[]", "_array"); + if ((name.endsWith("_array") || name.endsWith("_int")) && !name.startsWith("VAR_")) { + name = "VAR_" + name; + } + + if (isRealNumber(name)) { + return name; + } + return name; + } + + protected boolean isNumber(String line) { + try { + parseInt(line); + return true; + } catch (Exception e) { + return false; + } + } + + protected boolean isRealNumber(String line) { + try { + Integer.parseInt(line); + return true; + } catch (Exception e) { + return false; + } + } + + protected int parseInt(String txt) { + try { + return Integer.parseInt(txt); + } catch (NumberFormatException e) { + Map constMap = ConstantExtractor.getAllConstantMaps(); + if (constMap.containsKey(txt)) { + return constMap.get(txt); + } + throw e; + } + } + + protected void truncInteger(List nCode, Operand target) { + if (target.getType() == Type.INTEGER && !target.isRegister()) { + String to = getOpName(target); + nCode.add(to + "=int(" + to + ")"); + } + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorListPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorListPy.java new file mode 100644 index 00000000..bad4dbb3 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/GeneratorListPy.java @@ -0,0 +1,84 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import com.sixtyfour.cbmnative.Generator; + +/** + * + * @author EgonOlsen + * + */ +public class GeneratorListPy { + + private static final Generator LINE_NUMBER_GENERATOR = new LineNumberGeneratorPy(); + + private final static List GENERATORS = Collections.unmodifiableList(new ArrayList() { + private static final long serialVersionUID = 1L; + { + this.add(new NopPy()); + this.add(new RtsPy()); + this.add(new JsrPy()); + this.add(new JmpPy()); + this.add(new JnePy()); + this.add(new JePy()); + this.add(new MovPy()); + this.add(new MovbPy()); + this.add(new AddPy()); + this.add(new SubPy()); + this.add(new MulPy()); + this.add(new DivPy()); + this.add(new PopPy()); + this.add(new PushPy()); + this.add(new ShrPy()); + this.add(new ShlPy()); + this.add(new EqPy()); + this.add(new LtPy()); + this.add(new GtPy()); + this.add(new NeqPy()); + this.add(new GteqPy()); + this.add(new LteqPy()); + this.add(new CmpPy()); + this.add(new AndPy()); + this.add(new IntPy()); + this.add(new AbsPy()); + this.add(new AtnPy()); + this.add(new CosPy()); + this.add(new SinPy()); + this.add(new NotPy()); + this.add(new TanPy()); + this.add(new RndPy()); + this.add(new SqrPy()); + this.add(new PowPy()); + this.add(new SgnPy()); + this.add(new BrkPy()); + this.add(new OrPy()); + this.add(new LogPy()); + this.add(new ExpPy()); + this.add(new XorPy()); + this.add(new NegPy()); + } + }); + + private final static Map NAME_2_GEN = new HashMap() { + private static final long serialVersionUID = 1L; + { + for (Generator gen : GENERATORS) { + this.put(gen.getMnemonic(), gen); + } + } + }; + + public static Generator getGenerator(String line) { + line = line.trim().split(" ")[0].toUpperCase(Locale.ENGLISH); + if (line.endsWith(":")) { + return LINE_NUMBER_GENERATOR; + } + return NAME_2_GEN.get(line); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/GtPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/GtPy.java new file mode 100644 index 00000000..4e0e0cc6 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/GtPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class GtPy extends ComparisonPy { + + GtPy() { + super("GT", ">"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/GteqPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/GteqPy.java new file mode 100644 index 00000000..0bd23eab --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/GteqPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class GteqPy extends ComparisonPy { + + GteqPy() { + super("GTEQ", ">="); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/IntPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/IntPy.java new file mode 100644 index 00000000..12226036 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/IntPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class IntPy extends CalculationPy { + + public IntPy() { + super("INT", "int({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/JePy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/JePy.java new file mode 100644 index 00000000..bb3fc314 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/JePy.java @@ -0,0 +1,31 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; + +/** + * @author EgonOlsen + * + */ +public class JePy extends JumpBasePy { + + public JePy() { + super("", null); + } + + @Override + public String getMnemonic() { + return "JE"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + String[] parts = line.split(" "); + nCode.add("global _zeroflag"); + nCode.add("if _zeroflag==0:"); + nCode.add(" return \"" + parts[1].trim() + "\""); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/JmpPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/JmpPy.java new file mode 100644 index 00000000..e01acca3 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/JmpPy.java @@ -0,0 +1,30 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; + +/** + * @author EgonOlsen + * + */ +public class JmpPy extends JumpBasePy { + + public JmpPy() { + super("", null); + } + + @Override + public String getMnemonic() { + return "JMP"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + String[] parts = line.split(" "); + String p1 = parts[1].trim(); + nCode.add(("return " + (isNumber(p1) ? p1 : ("\"" + p1 + "\""))).trim()); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/JnePy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/JnePy.java new file mode 100644 index 00000000..1d6557ef --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/JnePy.java @@ -0,0 +1,31 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; + +/** + * @author EgonOlsen + * + */ +public class JnePy extends JumpBasePy { + + public JnePy() { + super("", null); + } + + @Override + public String getMnemonic() { + return "JNE"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + String[] parts = line.split(" "); + nCode.add("global _zeroflag"); + nCode.add("if _zeroflag==1:"); + nCode.add(" return \"" + parts[1].trim() + "\""); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/JsrPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/JsrPy.java new file mode 100644 index 00000000..2e8c9118 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/JsrPy.java @@ -0,0 +1,37 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.elements.Type; + +/** + * @author EgonOlsen + * + */ +public class JsrPy extends JumpBasePy { + + public JsrPy() { + super("", null); + } + + @Override + public String getMnemonic() { + return "JSR"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + if (line.equals("JSR ARRAYACCESS") || line.equals("JSR ARRAYSTORE")) { + Type type = context.getLastMoveSource().getType(); + line += "_" + type.toString(); + super.generateCode(context, line, nCode, subCode, name2label); + } else if (line.equals("JSR COPYSTR")) { + // nCode.add(";ignored: JSR COPYSTR"); + } else { + super.generateCode(context, line, nCode, subCode, name2label); + } + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/JumpBasePy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/JumpBasePy.java new file mode 100644 index 00000000..baaf55cd --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/JumpBasePy.java @@ -0,0 +1,50 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; + +/** + * @author EgonOlsen + * + */ +public abstract class JumpBasePy extends GeneratorBasePy { + + protected static int CNT = 0; + protected String cmd = ""; + protected String antiCmd = ""; + + JumpBasePy(String cmd, String antiCmd) { + this.cmd = cmd; + this.antiCmd = antiCmd; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + String[] parts = line.split(" "); + String label = parts[1]; + if (label.equals("($JUMP)") && antiCmd != null) { + nCode.add(antiCmd + " R" + cmd + "_" + CNT); + nCode.add("global JUMP_TARGET"); + nCode.add("return JUMP_TARGET"); + nCode.add("R" + cmd + "_" + CNT + ":"); + CNT++; + } else { + String p1 = parts[1].trim(); + if (Character.isDigit(label.charAt(0)) || label.startsWith("SKIP") || label.startsWith("NSKIP")) { + nCode.add(("return " + parts[1].trim()).trim()); + } else { + String pre = ""; + if (p1.equals("RETURN")) { + pre = "return "; + } + if (p1.startsWith("$")) { + pre = "# "; + } + nCode.add(pre + (cmd + " " + p1 + ((cmd.isEmpty() && !p1.endsWith(")")) ? "()" : "")).trim()); + } + } + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/LineNumberGeneratorPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/LineNumberGeneratorPy.java new file mode 100644 index 00000000..1d864424 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/LineNumberGeneratorPy.java @@ -0,0 +1,45 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.Generator; +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.python.Pythonizer; + +public class LineNumberGeneratorPy implements Generator { + + @Override + public String getMnemonic() { + return ""; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Pythonizer py = new Pythonizer(0); + line = line.replace(":", ""); + if (!line.equals("PROGRAMSTART")) { + if (!nCode.get(nCode.size() - 1).startsWith("return") || nCode.get(nCode.size() - 1).contains("$JUMP")) { + nCode.add(py.process("return " + (isNumber(line) ? line : ("\"" + line + "\"")))); + } + } + py.outdent(); + nCode.add(py.process("#")); + String prefix = ""; + if (isNumber(line)) { + prefix = "line_"; + } + nCode.add(py.process("def " + prefix + line + "():")); + } + + private static boolean isNumber(String line) { + try { + Integer.parseInt(line); + return true; + } catch (Exception e) { + return false; + } + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/LogPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/LogPy.java new file mode 100644 index 00000000..f128b108 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/LogPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class LogPy extends CalculationPy { + + public LogPy() { + super("LOG", "math.log({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/LtPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/LtPy.java new file mode 100644 index 00000000..0cafb7a5 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/LtPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class LtPy extends ComparisonPy { + + LtPy() { + super("LT", "<"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/LteqPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/LteqPy.java new file mode 100644 index 00000000..d1e4e484 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/LteqPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class LteqPy extends ComparisonPy { + + LteqPy() { + super("LTEQ", "<="); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/MovPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/MovPy.java new file mode 100644 index 00000000..dbd5bcc8 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/MovPy.java @@ -0,0 +1,120 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.cbmnative.Operands; +import com.sixtyfour.elements.Type; + +/** + * @author EgonOlsen + * + */ +public class MovPy extends GeneratorBasePy { + + @Override + public String getMnemonic() { + return "MOV"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Operands ops = new Operands(line, name2label); + + Operand source = ops.getSource(); + Operand target = ops.getTarget(); + + context.setLastMoveSource(source); + context.setLastMoveTarget(target); + + if (!source.isIndexed() && !target.isIndexed()) { + if (source.getType() == Type.STRING) { + if (source.isArray()) { + sourceStringArray(nCode, source, target); + } else { + sourceString(nCode, source, target); + } + } else if (target.getType() == Type.STRING) { + targetString(nCode, source, target); + } else if (source.isArray()) { + noIndexArraySource(nCode, source, target); + } else { + if (source.getType() == Type.INTEGER) { + noIndexIntegerSource(nCode, source, target); + } else { + noIndexRealSource(nCode, source, target); + } + } + } else { + if (target.getType() == Type.INTEGER) { + indexedTargetInteger(nCode, source, target); + } else { + if (source.isIndexed() && source.isRegister()) { + indexedSourceTargetReal(nCode, source, target); + } else { + throw new RuntimeException("Invalid index mode: " + line); + } + } + } + + truncInteger(nCode, target); + } + + private void targetString(List nCode, Operand source, Operand target) { + if (!checkSpecialWriteVars(nCode, target, source)) { + String from = getOpName(source); + String to = getOpName(target); + nCode.add(to + "=" + from); + } + } + + private void sourceString(List nCode, Operand source, Operand target) { + if (!checkSpecialReadVars(nCode, target, source)) { + String from = getOpName(source); + String to = getOpName(target); + nCode.add(to + "=" + from); + } else { + String to = getOpName(target); + nCode.add(to + "=tmpy"); + } + } + + private void sourceStringArray(List nCode, Operand source, Operand target) { + sourceString(nCode, source, target); + } + + private void noIndexArraySource(List nCode, Operand source, Operand target) { + String from = getOpName(source); + String to = getOpName(target); + nCode.add(to + "=" + from); + } + + private void indexedTargetInteger(List nCode, Operand source, Operand target) { + String from = getOpName(source); + String to = getOpName(target); + nCode.add("_memory[" + to + "]" + "=" + from); + } + + private void indexedSourceTargetReal(List nCode, Operand source, Operand target) { + String from = getOpName(source); + String to = getOpName(target); + nCode.add(to + "=" + "_memory[" + from + "]"); + } + + private void noIndexRealSource(List nCode, Operand source, Operand target) { + if (!checkSpecialReadVars(nCode, target, source)) { + noIndexArraySource(nCode, source, target); + } else { + String to = getOpName(target); + nCode.add(to + "=tmpy"); + } + } + + private void noIndexIntegerSource(List nCode, Operand source, Operand target) { + noIndexArraySource(nCode, source, target); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/MovbPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/MovbPy.java new file mode 100644 index 00000000..7dae7f6c --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/MovbPy.java @@ -0,0 +1,106 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.cbmnative.Operands; +import com.sixtyfour.elements.Type; + +/** + * @author EgonOlsen + * + */ +public class MovbPy extends MovPy { + + @Override + public String getMnemonic() { + return "MOVB"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Operands ops = new Operands(line, name2label); + + Operand source = ops.getSource(); + Operand target = ops.getTarget(); + + context.setLastMoveSource(source); + context.setLastMoveTarget(target); + + if (!source.isIndexed() && !target.isIndexed()) { + if (source.getType() == Type.INTEGER) { + noIndexIntegerSource(nCode, source, target); + } else { + noIndexRealSource(nCode, source, target); + } + } else { + if (target.isIndexed() && source.isIndexed()) { + throw new RuntimeException("Invalid index mode (both sides are indexed!): " + line); + } + + if (!target.isRegister() || !source.isRegister()) { + if (target.isRegister() && source.isConstant()) { + indexedTargetWithConstant(nCode, source, target); + } else { + throw new RuntimeException( + "Invalid index mode (at least one side isn't a register and source isn't a constant value either!): " + + line); + } + } else { + if (target.isIndexed()) { + indexedTarget(nCode, source, target); + } else { + indexedSource(nCode, source, target); + } + } + } + } + + private void indexedTargetWithConstant(List nCode, Operand source, Operand target) { + String from = getOpName(source); + String to = getOpName(target); + nCode.add("_memory[int(" + to + ")]=int(" + from + ") and 255"); + } + + private void indexedSource(List nCode, Operand source, Operand target) { + String from = getOpName(source); + String to = getOpName(target); + nCode.add(to + "=_memory[int(" + from + ") and 65535];"); + } + + private void indexedTarget(List nCode, Operand source, Operand target) { + indexedTargetWithConstant(nCode, source, target); + } + + private void noIndexRealSource(List nCode, Operand source, Operand target) { + String from = getOpName(source); + String addr = target.getAddress(); + if (addr == null || !addr.contains(":")) { + fillMemory(nCode, target, from); + } else { + String[] as = addr.split(":"); + target.setAddress(as[0].trim()); + fillMemory(nCode, target, from); + target.setAddress(as[1].trim()); + fillMemory(nCode, target, from + " >> 8"); + } + } + + private void noIndexIntegerSource(List nCode, Operand source, Operand target) { + noIndexRealSource(nCode, source, target); + } + + private void fillMemory(List nCode, Operand target, String from) { + String to = getOpName(target); + if (isNumber(from)) { + from = "_memory[" + from + "]"; + } + if (isNumber(to)) { + to = "_memory[" + to + "]"; + } + nCode.add(to + "=int(" + from + ") and 255;"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/MulPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/MulPy.java new file mode 100644 index 00000000..e49168bb --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/MulPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class MulPy extends CalculationPy { + + public MulPy() { + super("MUL", "{to}*{from}"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/NegPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/NegPy.java new file mode 100644 index 00000000..f9eb4c6a --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/NegPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class NegPy extends CalculationPy { + + public NegPy() { + super("NEG", "-{from}"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/NeqPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/NeqPy.java new file mode 100644 index 00000000..edea7710 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/NeqPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class NeqPy extends ComparisonPy { + + NeqPy() { + super("NEQ", "!="); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/NopPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/NopPy.java new file mode 100644 index 00000000..772ec7df --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/NopPy.java @@ -0,0 +1,25 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; + +/** + * @author EgonOlsen + * + */ +public class NopPy extends GeneratorBasePy { + + @Override + public String getMnemonic() { + return "NOP"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + nCode.add("#"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/NotPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/NotPy.java new file mode 100644 index 00000000..aed0d5eb --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/NotPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class NotPy extends CalculationPy { + + public NotPy() { + super("NOT", "not {from}"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/OrPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/OrPy.java new file mode 100644 index 00000000..2699546f --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/OrPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class OrPy extends CalculationPy { + + public OrPy() { + super("OR", "int({to}) or int({from})"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/PopPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/PopPy.java new file mode 100644 index 00000000..04d4e85e --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/PopPy.java @@ -0,0 +1,29 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.cbmnative.Operands; + +/** + * @author EgonOlsen + * + */ +public class PopPy extends GeneratorBasePy { + @Override + public String getMnemonic() { + return "POP"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Operands ops = new Operands(line, name2label); + Operand target = ops.getTarget(); + String to = getOpName(target); + nCode.add("global _stack"); + nCode.add(to + "=_stack.pop()"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/PowPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/PowPy.java new file mode 100644 index 00000000..4874d946 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/PowPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class PowPy extends CalculationPy { + + public PowPy() { + super("POW", "math.pow({to},{from})"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/PushPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/PushPy.java new file mode 100644 index 00000000..3771c097 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/PushPy.java @@ -0,0 +1,29 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; +import com.sixtyfour.cbmnative.Operand; +import com.sixtyfour.cbmnative.Operands; + +/** + * @author EgonOlsen + * + */ +public class PushPy extends GeneratorBasePy { + @Override + public String getMnemonic() { + return "PUSH"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + Operands ops = new Operands(line, name2label); + Operand target = ops.getTarget(); + String from = getOpName(target); + nCode.add("global _stack"); + nCode.add("_stack.append(" + from + ")"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/RndPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/RndPy.java new file mode 100644 index 00000000..e9faa50c --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/RndPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class RndPy extends CalculationPy { + + public RndPy() { + super("RND", "random.random()"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/RtsPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/RtsPy.java new file mode 100644 index 00000000..98c97215 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/RtsPy.java @@ -0,0 +1,28 @@ +package com.sixtyfour.cbmnative.python.generators; + +import java.util.List; +import java.util.Map; + +import com.sixtyfour.cbmnative.GeneratorContext; + +/** + * @author EgonOlsen + * + */ +public class RtsPy extends GeneratorBasePy { + + @Override + public String getMnemonic() { + return "RTS"; + } + + @Override + public void generateCode(GeneratorContext context, String line, List nCode, List subCode, + Map name2label) { + if (nCode.get(nCode.size() - 1).startsWith("return")) { + return; + } + nCode.add("return"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/SgnPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/SgnPy.java new file mode 100644 index 00000000..90594fd0 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/SgnPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class SgnPy extends CalculationPy { + + public SgnPy() { + super("SGN", "signum({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/ShlPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/ShlPy.java new file mode 100644 index 00000000..7bd67ebd --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/ShlPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class ShlPy extends CalculationPy { + + public ShlPy() { + super("SHL", "{to}*pow(2,{from})"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/ShrPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/ShrPy.java new file mode 100644 index 00000000..8ec59e80 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/ShrPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class ShrPy extends CalculationPy { + + public ShrPy() { + super("SHR", "{to}/pow(2,{from})"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/SinPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/SinPy.java new file mode 100644 index 00000000..78c05d8f --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/SinPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class SinPy extends CalculationPy { + + public SinPy() { + super("SIN", "math.sin({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/SqrPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/SqrPy.java new file mode 100644 index 00000000..5c84bc43 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/SqrPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class SqrPy extends CalculationPy { + + public SqrPy() { + super("SQR", "math.sqrt({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/SubPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/SubPy.java new file mode 100644 index 00000000..d5dbf54c --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/SubPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class SubPy extends CalculationPy { + + public SubPy() { + super("SUB", "{to}-{from}"); + } + +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/TanPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/TanPy.java new file mode 100644 index 00000000..eb909779 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/TanPy.java @@ -0,0 +1,12 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class TanPy extends CalculationPy { + + public TanPy() { + super("TAN", "math.tan({from})"); + } +} diff --git a/src/main/java/com/sixtyfour/cbmnative/python/generators/XorPy.java b/src/main/java/com/sixtyfour/cbmnative/python/generators/XorPy.java new file mode 100644 index 00000000..6446a432 --- /dev/null +++ b/src/main/java/com/sixtyfour/cbmnative/python/generators/XorPy.java @@ -0,0 +1,13 @@ +package com.sixtyfour.cbmnative.python.generators; + +/** + * @author EgonOlsen + * + */ +public class XorPy extends CalculationPy { + + public XorPy() { + super("XOR", "int({to}) ^ int({from})"); + } + +} diff --git a/src/main/resources/subroutines.py b/src/main/resources/subroutines.py new file mode 100644 index 00000000..721b18cb --- /dev/null +++ b/src/main/resources/subroutines.py @@ -0,0 +1,665 @@ +restart = False +running = True +keyPressed = None +lineNumber = 0 +timeOut=0 +funcName = "PROGRAMSTART" +tymp=0 + +def getMemory(): + global _memory + return _memory + +def signum(value): + if value < 0: + return -1 + if value > 0: + return 1 + return 0 + +def isNumber(var): + if isinstance(var, (int, float)): + return True + if len(var)==0: + return False + try: + val = float(var) + return True + except ValueError: + return False + + +def registerKey(): + global _memory + global keyPressed + k = keyboard.read_key() + keyPressed=k + _memory[198]=1 + +def execute(): + global running + global restart + while True: + reinit() + while running: + executeLine() + if not restart: + break + +def reinit(): + global lineNumer + global funcName + global restart + global running + lineNumber = 0 + funcName = "PROGRAMSTART" + restart=False + running=True + +def executeLine(): + global funcName + global lineNumber + global JUMP_TARGET + global running + nextLine = globals()[funcName]() + if nextLine != None: + lineNumber = nextLine + if lineNumber == "($JUMP)": + lineNumber = JUMP_TARGET + if isNumber(lineNumber): + funcName = "line_" + str(lineNumber) + else: + funcName = lineNumber + else: + running = False + +def START(): + global _memory + INIT() + _memory[646]=14 + +def RUN(): + global running + global restart + running=False + restart=True + +def RESTARTPRG(): + global running + global restart + running=False + restart=True + +def END(): + pass + +def CLEARQUEUE(): + global _inputQueue + _inputQueue=[] + +def QUEUESIZE(): + global _inputQueue + global X_REG + X_REG=len(_inputQueue) + +def EXTRAIGNORED(): + out("?extra ignored!") + +def INPUTNUMBER(): + global Y_REG + global X_REG + inp=input() + if isNumber(inp): + Y_REG=float(inp) + X_REG=0 + else: + X_REG=-1 + +def INPUTSTR(): + global A_REG + A_REG=input() + +def GETSTR(): + global A_REG + A_REG=get() + +def GETNUMBER(): + global Y_REG + fk=get() + if isNumber(fk): + Y_REG=float(fk) + else: + out("?syntax error") + + +def isNaN(number): + return math.isnan(number) + +def isNumeric(number): + return isNumber(number) + +def parseFloat(number): + return float(number) + +def GOSUB(gosubCont): + global _forstack + _forstack.append(gosubCont) + _forstart.append(0) + +def pop(arr): + return arr.pop() + +def throw(txt): + raise Exception(txt) + +def RETURN(): + global _forstack + val = 0 + if len(_forstack)==0: + throw("RETURN without GOSUB error!") + while True: + val = _forstack.pop() + if val == 1: + forstack.pop() + forstack.pop() + forstack.pop() + forstack.pop() + if val==0: + break + val = _forstack.pop() + return val + +def adjustStack(variable): + global _forstack + i=len(_forstack) + while i>0: + type=_forstack[i-1] + if type == 0: + return + vary = _forstack[i-2] + addr = _forstack[i-3] + end = _forstack[i-4] + step = _forstack[i-5] + i=i-5 + if vary == variable: + _forstack=_forstack[0:i] + return + +def INITFOR(addr, variable): + global _stack + global _forstack + adjustStack(variable) + _forstack.append(_stack.pop()) + _forstack.append(_stack.pop()) + _forstack.append(addr) + _forstack.append(variable) + _forstack.append(1) + +def NEXT(variable): + global _forstack + global A_REG + global JUMP_TARGET + found = False + while True: + if len(_forstack)==0: + throw("NEXT without FOR error!") + type=_forstack.pop() + if type ==0: + throw("NEXT without FOR error!") + stvar=_forstack.pop() + addr=_forstack.pop() + end=_forstack.pop() + step=_forstack.pop() + found = (variable == "0" or variable == stvar) + if found: + break + globals()[stvar]+=step + vv = globals()[stvar] + if (step >= 0 and vv <= end) or (step >= 0 and vv <= end): + _forstack.append(step) + _forstack.append(end) + _forstack.append(addr) + _forstack.append(stvar) + _forstack.append(1) + A_REG = 0 + JUMP_TARGET = addr + return + A_REG = 1 + + +def ARRAYACCESS_REAL(): + global X_REG + global G_REG + X_REG = G_REG[int(X_REG)] + if X_REG == None: + X_REG = 0 + +def ARRAYACCESS_INTEGER(): + global X_REG + global G_REG + X_REG = G_REG[int(X_REG)] + if X_REG == None: + X_REG = 0 + X_REG=int(X_REG) + +def ARRAYACCESS_STRING(): + global G_REG + global A_REG + global X_REG + A_REG = G_REG[int(X_REG)] + if A_REG == None: + A_REG = "" + +def ARRAYSTORE_REAL(): + global G_REG + global Y_REG + global X_REG + G_REG[int(X_REG)] = Y_REG + +def ARRAYSTORE_INTEGER(): + global G_REG + global Y_REG + global X_REG + G_REG[int(X_REG)] = int(Y_REG) + +def ARRAYSTORE_STRING(): + global G_REG + global A_REG + global X_REG + G_REG[int(X_REG)] = A_REG + +def STR(): + global A_REG + global Y_REG + A_REG=str(Y_REG) + +def VAL(): + global B_REG + global X_REG + X_REG=float(B_REG.replace(" ","")) + +def LEN(): + global B_REG + global X_REG + X_REG=len(B_REG) + +def CHR(): + global A_REG + global Y_REG + A_REG=chr(int(Y_REG)) + + +def ASC(): + global B_REG + global X_REG + if len(B_REG)==0: + X_REG=0 + return + X_REG=ord(B_REG[0]) + +def POS(): + global X_REG + global _line + X_REG=len(_line) + +def TAB(): + global _line + global Y_REG + tb=int(Y_REG) + tb-=len(_line) + for i in range(0,tb): + _line+=" " + +def SPC(): + global _line + global Y_REG + tb=int(Y_REG) + for i in range(0,tb): + _line+=" " + +def FRE(): + global X_REG + X_REG=65535 + +def CONCAT(): + global B_REG + global A_REG + A_REG=A_REG+B_REG + +def MID(): + global D_REG + global C_REG + global B_REG + global A_REG + if C_REG > len(B_REG): + A_REG="" + return + end=C_REG-1 + D_REG + if D_REG==-1: + end=len(B_REG) + A_REG=B_REG[C_REG-1:end] + +def LEFT(): + global C_REG + global B_REG + global A_REG + if C_REG > len(B_REG): + A_REG=B_REG + return + if C_REG==0: + A_REG="" + return + A_REG=B_REG[:C_REG] + +def RIGHT(): + global C_REG + global B_REG + global A_REG + if C_REG > len(B_REG): + A_REG=B_REG + return + if C_REG==0: + A_REG="" + return + A_REG=B_REG[len(B_REG)-C_REG:] + +def SEQ(): + global X_REG + global B_REG + global A_REG + if A_REG == B_REG: + X_REG=-1 + else: + X_REG=0 + +def SNEQ(): + global X_REG + global B_REG + global A_REG + if A_REG == B_REG: + X_REG=0 + else: + X_REG=-1 + +def SGT(): + global X_REG + global B_REG + global A_REG + if A_REG > B_REG: + X_REG=-1 + else: + X_REG=0 + +def SLT(): + global X_REG + global B_REG + global A_REG + if A_REG < B_REG: + X_REG=-1 + else: + X_REG=0 + +def SGTEQ(): + global X_REG + global B_REG + global A_REG + if A_REG >= B_REG: + X_REG=-1 + else: + X_REG=0 + +def SLTEQ(): + global X_REG + global B_REG + global A_REG + if A_REG <= B_REG: + X_REG=-1 + else: + X_REG=0 + +def COMPACT(): + pass + +def COMPACTMAX(): + pass + +def SYSTEMCALLDYN(): + pass + +def APPENDSYSCHAR(): + pass + +def INPUTLENGTHCHECK(): + global _zeroflag + _zeroflag = 1 + +def SETUPMULTIPARS(): + pass + +def COPYSTRINGPAR(): + pass + +def COPYREALPAR(): + pass + +def ADDCOLON(): + pass + +def PULLDOWNMULTIPARS(): + pass + +def STROUT(): + global A_REG + out(A_REG) + +def QMARKOUT1(): + out("?") + +def CRSRRIGHT(): + out(" ") + +def QMARKOUT2(): + out("??") + +def REALOUT(): + global X_REG + out(X_REG) + +def INTOUT(): + global X_REG + out(X_REG) + +def CHECKCMD(): + pass + +def LINEBREAK(): + out("\n") + +def TABOUT(): + out("\t") + +def millis(): + return int(time.perf_counter() * 1000) + +def WRITETID(value): + global _time + global _timeOffset + _time = millis() + _timeOffset = int(value[0:2])* 1000 * 60 * 60 + int(value[2:4]) * 1000 * 60 + int(value[4:6]) * 1000 + +def READTI(): + global _time + global _timeOffset + global tmpy + t=millis() + t=int((t-_time+_timeOffset)/(1000.0/60.0)) + tmpy=t + +def READTID(): + global _time + global _timeOffset + global tmpy + t=millis() + t=t-_time+_timeOffset + h=int(t/(1000 * 60 * 60)) + m=int(((t-(h*(1000 * 60 * 60)))/(1000 * 60))) + s=int((t-(h*(1000 * 60 * 60))-m*(1000 * 60))/1000) + h=fill(h) + m=fill(m) + s=fill(s) + tmpy= h+m+s + +def fill(num): + num=str(num) + if len(num.length)==1: + num="0"+num + return num + +def READSTATUS(): + global tmpy + tmpy=0 + +def RESTORE(): + global _dataPtr + _dataPtr=0 + +def READSTR(): + global _dataPtr + global _datas + global A_REG + A_REG=_datas[_dataPtr] + _dataPtr+=1 + +def READNUMBER(): + global _dataPtr + global _datas + global Y_REG + num=_datas[_dataPtr] + _dataPtr+=1 + + if isinstance(num, str) and (num == "." or len(num) == 0): + num=0 + Y_REG=num + +def FINX(): + throw("Fast inc optimization not supported for target PY!") + +def FDEX(): + throw("Fast dec optimization not supported for target PY!") + +def FASTFOR(): + throw("Fast for optimization not supported for target PY!") + +def OPEN(): + out("[OPEN not supported for PY, call ignored!]") + +def CLOSE(): + out("[CLOSE not supported for PY, call ignored!]") + +def CMD(): + out("[CMD not supported for PY, call ignored!]") + +def REM(): + out("[inline assembly ignored!]") + +def LOCKCHANNEL(): + out("[ignored]") + +def UNLOCKCHANNEL(): + out("[ignored]") + +def STROUTCHANNEL(): + out("[PRINT# not supported for PY, redirected to normal PRINT]") + STROUT() + +def REALOUTCHANNEL(): + out("[PRINT# not supported for PY, redirected to normal PRINT]") + REALOUT() + +def LINEBREAKCHANNEL(): + out("[PRINT# not supported for PY, redirected to normal PRINT]") + LINEBREAK() + +def INTOUTCHANNEL(): + out("[PRINT# not supported for PY, redirected to normal PRINT]") + INTOUT() + +def INPUTNUMBERCHANNEL(): + global X_REG + out("[INPUT# not supported for PY, call ignored]") + X_REG=0 + +def INPUTSTRCHANNEL(): + global A_REG + out("[INPUT# not supported for PY, call ignored]") + A_REG="" + +def GETSTRCHANNEL(): + global A_REG + out("[GET# not supported for PY, call ignored]") + A_REG="" + +def GETNUMBERCHANNEL(): + global X_REG + out("[GET# not supported for PY, call ignored]") + X_REG=0 + +def TABOUTCHANNEL(): + out("[TAB not supported for PY in file mode, redirected to normal TAB]") + TAB() + +def SPCOUTCHANNEL(): + out("[SPC not supported for PY in file mode, redirected to normal SPC]") + SPC() + +def TABCHANNEL(): + out("[TAB not supported for PY in file mode, redirected to normal TAB]") + TAB() + +def SPCCHANNEL(): + out("[SPC not supported for PY in file mode, redirected to normal SPC]") + SPC() + +def LOAD(): + out("[LOAD not supported for PY in file mode, call ignored]") + +def SAVE(): + out("[SAVE not supported for PY in file mode, call ignored]") + +def VERIFY(): + out("[VERIFY not supported for PY in file mode, call ignored]") + +def USR(): + global _memory + global USR_PARAM + global X_REG + addr=_memory[785] + 256*_memory[786] + USR_PARAM=X_REG + callStr="$"+hex(addr) + out("[Calling user function named "+callStr+"]") + globals()[callStr]() + +def input(): + global _inputQueue + global _line + if len(_inputQueue)>0: + return _inputQueue.pop() + + inp=input(_line) + _line="" + parts=inp.split(",") + _inputQueue.append(parts) + +def get(): + return keyboard.read_key() + +def out(txt): + global _line + if isinstance(txt, str) and "\n" in txt: + _line += txt[0:len(txt)-1] + print(_line) + _line = "" + else: + _line += str(txt) + +execute() diff --git a/src/test/java/com/sixtyfour/test/TransformerJsTest.java b/src/test/java/com/sixtyfour/test/TransformerJsTest.java index 6fe5e67f..3eb226de 100644 --- a/src/test/java/com/sixtyfour/test/TransformerJsTest.java +++ b/src/test/java/com/sixtyfour/test/TransformerJsTest.java @@ -1,218 +1,217 @@ -package com.sixtyfour.test; - -import java.io.PrintWriter; -import java.util.List; - -import com.sixtyfour.Basic; -import com.sixtyfour.Loader; -import com.sixtyfour.cbmnative.NativeCompiler; -import com.sixtyfour.cbmnative.Transformer; -import com.sixtyfour.cbmnative.javascript.PlatformJs; -import com.sixtyfour.config.CompilerConfig; -import com.sixtyfour.config.LoopMode; -import com.sixtyfour.config.MemoryConfig; -import com.sixtyfour.extensions.x16.X16Extensions; - -public class TransformerJsTest { - - private static String path = "compiled/"; - - public static void main(String[] args) throws Exception { - test2(); - testPrime(); - testBeer(); - test9(); - test4(); - test16(); - testFractal(); - test22(); - test18(); - test15(); - testLevenshtein(); - testCmd(); - testOpen(); - testData(); - testLoad(); - test17(); - testRun(); - testBenchmark(); - testCharFractal(); - testX16(); - } - - private static void testX16() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/x16/vpoke.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++vpoke.js"); - } - - private static void testCharFractal() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/charfractal.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++charfractal.js"); - } - - private static void testBenchmark() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/js/benchmark2.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++benchmark2.js"); - } - - private static void testRun() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/testrun.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++testrun.js"); - } - - private static void test17() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test17.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test17.js"); - } - - private static void testLoad() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/testload.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++testload.js"); - } - - private static void testData() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test23.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++testdata.js"); - } - - private static void testOpen() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/testopen.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++testopen.js"); - } - - private static void testCmd() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/testcmd.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++testcmd.js"); - } - - private static void testLevenshtein() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/levenshtein.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++levenshtein.js"); - } - - private static void test2() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test2.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test2.js"); - } - - private static void test4() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test4.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test4.js"); - } - - private static void test9() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test9.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test9.js"); - } - - private static void test16() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test16.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test16.js"); - } - - private static void test22() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test22.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test22.js"); - } - - private static void test18() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test18.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test18.js"); - } - - private static void test15() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/test15.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++test15.js"); - } - - private static void testFractal() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/js/fractal.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++fractal.js"); - } - - private static void testPrime() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/prime_transform.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++prime.js"); - } - - private static void testBeer() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/beer_transform.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++beer.js"); - } - - private static List initTestEnvironment(String[] vary) { - CompilerConfig conf = new CompilerConfig(); - boolean opt = true; - conf.setConstantFolding(opt); - conf.setConstantPropagation(opt); - conf.setDeadStoreElimination(false); - conf.setDeadStoreEliminationOfStrings(false); - conf.setIntermediateLanguageOptimizations(opt); - conf.setNativeLanguageOptimizations(opt); - conf.setOptimizedLinker(opt); - conf.setLoopMode(LoopMode.REMOVE); - - // Disable these for JS-Target - conf.setLoopOptimizations(false); - conf.setIntOptimizations(false); - conf.setShiftOptimizations(false); - // conf.setCompactThreshold(3); - - Basic basic = new Basic(vary); - Basic.registerExtension(new X16Extensions()); - basic.compile(conf); - - List mCode = NativeCompiler.getCompiler().compileToPseudoCode(conf, basic); - System.out.println("------------------------------"); - for (String line : mCode) { - System.out.println(line); - } - System.out.println("------------------------------"); - - MemoryConfig memConfig = new MemoryConfig(); - basic = new Basic(vary); - List nCode = NativeCompiler.getCompiler().compile(conf, basic, memConfig, new PlatformJs()); - for (String line : nCode) { - System.out.println(line); - } - - return nCode; - } - - private static void write(List code, String file) { - System.out.println("Writing file: " + file); - Transformer trsn = new PlatformJs().getTransformer(); - try (PrintWriter pw = new PrintWriter(file); PrintWriter cpw = new PrintWriter(file.replace(".js", ".html"))) { - for (String line : code) { - pw.println(line); - } - String[] parts = file.replace("\\", "/").split("/"); - for (String line : trsn.createCaller(parts[parts.length - 1])) { - cpw.println(line); - } - } catch (Exception e) { - System.out.println("Failed to write file '" + file + "': " + e.getMessage()); - } - } - -} +package com.sixtyfour.test; + +import java.io.PrintWriter; +import java.util.List; + +import com.sixtyfour.Basic; +import com.sixtyfour.Loader; +import com.sixtyfour.cbmnative.NativeCompiler; +import com.sixtyfour.cbmnative.Transformer; +import com.sixtyfour.cbmnative.javascript.PlatformJs; +import com.sixtyfour.config.CompilerConfig; +import com.sixtyfour.config.LoopMode; +import com.sixtyfour.config.MemoryConfig; +import com.sixtyfour.extensions.x16.X16Extensions; + +public class TransformerJsTest { + + private static String path = "compiled/"; + + public static void main(String[] args) throws Exception { + test2(); + testPrime(); + testBeer(); + test9(); + test4(); + test16(); + testFractal(); + test22(); + test18(); + test15(); + testLevenshtein(); + testCmd(); + testOpen(); + testData(); + testLoad(); + test17(); + testRun(); + testBenchmark(); + testCharFractal(); + testX16(); + } + + private static void testX16() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/x16/vpoke.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++vpoke.js"); + } + + private static void testCharFractal() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/charfractal.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++charfractal.js"); + } + + private static void testBenchmark() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/js/benchmark2.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++benchmark2.js"); + } + + private static void testRun() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/testrun.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++testrun.js"); + } + + private static void test17() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test17.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test17.js"); + } + + private static void testLoad() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/testload.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++testload.js"); + } + + private static void testData() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test23.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++testdata.js"); + } + + private static void testOpen() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/testopen.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++testopen.js"); + } + + private static void testCmd() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/testcmd.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++testcmd.js"); + } + + private static void testLevenshtein() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/levenshtein.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++levenshtein.js"); + } + + private static void test2() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test2.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test2.js"); + } + + private static void test4() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test4.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test4.js"); + } + + private static void test9() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test9.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test9.js"); + } + + private static void test16() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test16.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test16.js"); + } + + private static void test22() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test22.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test22.js"); + } + + private static void test18() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test18.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test18.js"); + } + + private static void test15() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test15.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++test15.js"); + } + + private static void testFractal() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/js/fractal.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++fractal.js"); + } + + private static void testPrime() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/prime_transform.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++prime.js"); + } + + private static void testBeer() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/beer_transform.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++beer.js"); + } + + private static List initTestEnvironment(String[] vary) { + CompilerConfig conf = new CompilerConfig(); + boolean opt = true; + conf.setConstantFolding(opt); + conf.setConstantPropagation(opt); + conf.setDeadStoreElimination(false); + conf.setDeadStoreEliminationOfStrings(false); + conf.setIntermediateLanguageOptimizations(opt); + conf.setNativeLanguageOptimizations(opt); + conf.setOptimizedLinker(opt); + conf.setLoopMode(LoopMode.REMOVE); + + // Disable these for JS-Target + conf.setLoopOptimizations(false); + conf.setIntOptimizations(false); + conf.setShiftOptimizations(false); + // conf.setCompactThreshold(3); + + Basic basic = new Basic(vary); + basic.compile(conf); + + List mCode = NativeCompiler.getCompiler().compileToPseudoCode(conf, basic); + System.out.println("------------------------------"); + for (String line : mCode) { + System.out.println(line); + } + System.out.println("------------------------------"); + + MemoryConfig memConfig = new MemoryConfig(); + basic = new Basic(vary); + List nCode = NativeCompiler.getCompiler().compile(conf, basic, memConfig, new PlatformJs()); + for (String line : nCode) { + System.out.println(line); + } + + return nCode; + } + + private static void write(List code, String file) { + System.out.println("Writing file: " + file); + Transformer trsn = new PlatformJs().getTransformer(); + try (PrintWriter pw = new PrintWriter(file); PrintWriter cpw = new PrintWriter(file.replace(".js", ".html"))) { + for (String line : code) { + pw.println(line); + } + String[] parts = file.replace("\\", "/").split("/"); + for (String line : trsn.createCaller(parts[parts.length - 1])) { + cpw.println(line); + } + } catch (Exception e) { + System.out.println("Failed to write file '" + file + "': " + e.getMessage()); + } + } + +} diff --git a/src/test/java/com/sixtyfour/test/TransformerPsTest.java b/src/test/java/com/sixtyfour/test/TransformerPsTest.java index 6090d3ba..807e31e0 100644 --- a/src/test/java/com/sixtyfour/test/TransformerPsTest.java +++ b/src/test/java/com/sixtyfour/test/TransformerPsTest.java @@ -1,118 +1,117 @@ -package com.sixtyfour.test; - -import java.io.PrintWriter; -import java.util.List; - -import com.sixtyfour.Basic; -import com.sixtyfour.Loader; -import com.sixtyfour.cbmnative.NativeCompiler; -import com.sixtyfour.cbmnative.powerscript.PlatformPs; -import com.sixtyfour.config.CompilerConfig; -import com.sixtyfour.config.LoopMode; -import com.sixtyfour.config.MemoryConfig; -import com.sixtyfour.extensions.x16.X16Extensions; - -public class TransformerPsTest { - - private static String path = "compiled/"; - - public static void main(String[] args) throws Exception { - testPrime(); - testBeer(); - testLevenshtein(); - testCharFractal(); - testBenchmark2(); - testX16(); - } - - private static void testX16() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/x16/vpoke.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++vpoke.ps1"); - } - - private static void testLyrix() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/basic/lyrix_raw.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++lyrix.ps1"); - } - - private static void testBenchmark2() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/benchmark2.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++benchmark2.ps1"); - } - - private static void testCharFractal() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/charfractal.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++charfractal.ps1"); - } - - private static void testLevenshtein() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/levenshtein.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++levenshtein.ps1"); - } - - private static void testPrime() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/prime_transform.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++prime.ps1"); - } - - private static void testBeer() throws Exception { - String[] vary = Loader.loadProgram("src/test/resources/transform/beer_transform.bas"); - List js = initTestEnvironment(vary); - write(js, path + "++beer.ps1"); - } - - private static List initTestEnvironment(String[] vary) { - CompilerConfig conf = new CompilerConfig(); - boolean opt = true; - conf.setConstantFolding(opt); - conf.setConstantPropagation(opt); - conf.setDeadStoreElimination(false); - conf.setDeadStoreEliminationOfStrings(false); - conf.setIntermediateLanguageOptimizations(opt); - conf.setNativeLanguageOptimizations(opt); - conf.setOptimizedLinker(opt); - conf.setLoopMode(LoopMode.REMOVE); - - // Disable these for JS-Target - conf.setLoopOptimizations(false); - conf.setIntOptimizations(false); - conf.setShiftOptimizations(false); - - final Basic basic = new Basic(vary); - Basic.registerExtension(new X16Extensions()); - basic.compile(conf); - - List mCode = NativeCompiler.getCompiler().compileToPseudoCode(conf, basic); - System.out.println("------------------------------"); - for (String line : mCode) { - System.out.println(line); - } - System.out.println("------------------------------"); - - MemoryConfig memConfig = new MemoryConfig(); - List nCode = NativeCompiler.getCompiler().compile(conf, basic, memConfig, new PlatformPs()); - for (String line : nCode) { - System.out.println(line); - } - - return nCode; - } - - private static void write(List code, String file) { - System.out.println("Writing file: " + file); - try (PrintWriter pw = new PrintWriter(file)) { - for (String line : code) { - pw.println(line); - } - } catch (Exception e) { - System.out.println("Failed to write file '" + file + "': " + e.getMessage()); - } - } - -} +package com.sixtyfour.test; + +import java.io.PrintWriter; +import java.util.List; + +import com.sixtyfour.Basic; +import com.sixtyfour.Loader; +import com.sixtyfour.cbmnative.NativeCompiler; +import com.sixtyfour.cbmnative.powerscript.PlatformPs; +import com.sixtyfour.config.CompilerConfig; +import com.sixtyfour.config.LoopMode; +import com.sixtyfour.config.MemoryConfig; +import com.sixtyfour.extensions.x16.X16Extensions; + +public class TransformerPsTest { + + private static String path = "compiled/"; + + public static void main(String[] args) throws Exception { + testPrime(); + testBeer(); + testLevenshtein(); + testCharFractal(); + testBenchmark2(); + testX16(); + } + + private static void testX16() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/x16/vpoke.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++vpoke.ps1"); + } + + private static void testLyrix() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/basic/lyrix_raw.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++lyrix.ps1"); + } + + private static void testBenchmark2() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/benchmark2.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++benchmark2.ps1"); + } + + private static void testCharFractal() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/charfractal.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++charfractal.ps1"); + } + + private static void testLevenshtein() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/levenshtein.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++levenshtein.ps1"); + } + + private static void testPrime() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/prime_transform.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++prime.ps1"); + } + + private static void testBeer() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/beer_transform.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++beer.ps1"); + } + + private static List initTestEnvironment(String[] vary) { + CompilerConfig conf = new CompilerConfig(); + boolean opt = true; + conf.setConstantFolding(opt); + conf.setConstantPropagation(opt); + conf.setDeadStoreElimination(false); + conf.setDeadStoreEliminationOfStrings(false); + conf.setIntermediateLanguageOptimizations(opt); + conf.setNativeLanguageOptimizations(opt); + conf.setOptimizedLinker(opt); + conf.setLoopMode(LoopMode.REMOVE); + + // Disable these for PS-Target + conf.setLoopOptimizations(false); + conf.setIntOptimizations(false); + conf.setShiftOptimizations(false); + + final Basic basic = new Basic(vary); + basic.compile(conf); + + List mCode = NativeCompiler.getCompiler().compileToPseudoCode(conf, basic); + System.out.println("------------------------------"); + for (String line : mCode) { + System.out.println(line); + } + System.out.println("------------------------------"); + + MemoryConfig memConfig = new MemoryConfig(); + List nCode = NativeCompiler.getCompiler().compile(conf, basic, memConfig, new PlatformPs()); + for (String line : nCode) { + System.out.println(line); + } + + return nCode; + } + + private static void write(List code, String file) { + System.out.println("Writing file: " + file); + try (PrintWriter pw = new PrintWriter(file)) { + for (String line : code) { + pw.println(line); + } + } catch (Exception e) { + System.out.println("Failed to write file '" + file + "': " + e.getMessage()); + } + } + +} diff --git a/src/test/java/com/sixtyfour/test/TransformerPyTest.java b/src/test/java/com/sixtyfour/test/TransformerPyTest.java new file mode 100644 index 00000000..2ba3b80b --- /dev/null +++ b/src/test/java/com/sixtyfour/test/TransformerPyTest.java @@ -0,0 +1,79 @@ +package com.sixtyfour.test; + +import java.io.PrintWriter; +import java.util.List; + +import com.sixtyfour.Basic; +import com.sixtyfour.Loader; +import com.sixtyfour.cbmnative.NativeCompiler; +import com.sixtyfour.cbmnative.python.PlatformPy; +import com.sixtyfour.config.CompilerConfig; +import com.sixtyfour.config.LoopMode; +import com.sixtyfour.config.MemoryConfig; +import com.sixtyfour.extensions.x16.X16Extensions; + +public class TransformerPyTest { + + private static String path = "compiled/"; + + public static void main(String[] args) throws Exception { + testData(); + } + + private static void testData() throws Exception { + String[] vary = Loader.loadProgram("src/test/resources/transform/test23.bas"); + List js = initTestEnvironment(vary); + write(js, path + "++testdata.py"); + } + + + private static List initTestEnvironment(String[] vary) { + CompilerConfig conf = new CompilerConfig(); + boolean opt = true; + conf.setConstantFolding(opt); + conf.setConstantPropagation(opt); + conf.setDeadStoreElimination(false); + conf.setDeadStoreEliminationOfStrings(false); + conf.setIntermediateLanguageOptimizations(opt); + conf.setNativeLanguageOptimizations(opt); + conf.setOptimizedLinker(opt); + conf.setLoopMode(LoopMode.REMOVE); + + // Disable these for Py-Target + conf.setLoopOptimizations(false); + conf.setIntOptimizations(false); + conf.setShiftOptimizations(false); + // conf.setCompactThreshold(3); + + Basic basic = new Basic(vary); + basic.compile(conf); + + List mCode = NativeCompiler.getCompiler().compileToPseudoCode(conf, basic); + System.out.println("------------------------------"); + for (String line : mCode) { + System.out.println(line); + } + System.out.println("------------------------------"); + + MemoryConfig memConfig = new MemoryConfig(); + basic = new Basic(vary); + List nCode = NativeCompiler.getCompiler().compile(conf, basic, memConfig, new PlatformPy()); + for (String line : nCode) { + System.out.println(line); + } + + return nCode; + } + + private static void write(List code, String file) { + System.out.println("Writing file: " + file); + try (PrintWriter pw = new PrintWriter(file)) { + for (String line : code) { + pw.println(line); + } + } catch (Exception e) { + System.out.println("Failed to write file '" + file + "': " + e.getMessage()); + } + } + +} diff --git a/src/test/resources/transform/test23.bas b/src/test/resources/transform/test23.bas index 466371db..f80fed93 100644 --- a/src/test/resources/transform/test23.bas +++ b/src/test/resources/transform/test23.bas @@ -1,7 +1,7 @@ -10 for i=1to5:reada$:printa$:next +10 dim g%(2),g(2):for i=1to5:reada$:printa$:next 20 restore -30 read a$,a$,a,b,c -40 print "test:",a,b,c,a$ +30 read a$,a$,a,b,c:g%(1)=a:g(1)=b +40 print "test:",a,b,c,a$,g%(1),g(1) 1000 data hello,"world",13,4557.55,34