From 9078361a185990b30f6f08e63c071a5fc9d9e745 Mon Sep 17 00:00:00 2001 From: Rob Greene Date: Mon, 16 Jul 2018 22:16:59 -0500 Subject: [PATCH] Adding an optimization to shorten variable names to 1 or 2 characters. This allows more useful variable names in the program. --- .../bastools/api/Configuration.java | 3 + .../bastools/api/Directive.java | 10 +++ .../bastools/api/Optimization.java | 2 + .../directives/EmbeddedBinaryDirective.java | 2 +- .../api/directives/EmbeddedShapeTable.java | 8 +-- .../optimizations/ShortenVariableNames.java | 68 +++++++++++++++++++ .../bastools/tools/bt/Main.java | 1 + 7 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 api/src/main/java/io/github/applecommander/bastools/api/optimizations/ShortenVariableNames.java diff --git a/api/src/main/java/io/github/applecommander/bastools/api/Configuration.java b/api/src/main/java/io/github/applecommander/bastools/api/Configuration.java index 621ccec..d2c2020 100644 --- a/api/src/main/java/io/github/applecommander/bastools/api/Configuration.java +++ b/api/src/main/java/io/github/applecommander/bastools/api/Configuration.java @@ -4,6 +4,8 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; public class Configuration { @@ -11,6 +13,7 @@ public class Configuration { public final int startAddress; public final int maxLineLength; public final PrintStream debugStream; + public final MapvariableReplacements = new HashMap<>(); private Configuration(Builder b) { this.sourceFile = b.sourceFile; diff --git a/api/src/main/java/io/github/applecommander/bastools/api/Directive.java b/api/src/main/java/io/github/applecommander/bastools/api/Directive.java index bf715f0..77406b5 100644 --- a/api/src/main/java/io/github/applecommander/bastools/api/Directive.java +++ b/api/src/main/java/io/github/applecommander/bastools/api/Directive.java @@ -38,6 +38,16 @@ public abstract class Directive { this.parameterNames = new TreeSet<>(String::compareToIgnoreCase); this.parameterNames.addAll(Arrays.asList(parameterNames)); } + + /** Resolve the given variable name with any variable replacements that should occur. */ + public String resolve(String originalVariableName) { + if (config.variableReplacements.containsKey(originalVariableName)) { + String replacementVariableName = config.variableReplacements.get(originalVariableName); + config.debugStream.printf("Replacing '%s' with '%s'\n", originalVariableName, replacementVariableName); + return replacementVariableName; + } + return originalVariableName; + } public Optional optionalExpression(String paramName) { return Optional.ofNullable(parameters.get(paramName)); diff --git a/api/src/main/java/io/github/applecommander/bastools/api/Optimization.java b/api/src/main/java/io/github/applecommander/bastools/api/Optimization.java index 2c03c0e..4f922cc 100644 --- a/api/src/main/java/io/github/applecommander/bastools/api/Optimization.java +++ b/api/src/main/java/io/github/applecommander/bastools/api/Optimization.java @@ -3,6 +3,7 @@ package io.github.applecommander.bastools.api; import java.util.function.Function; import io.github.applecommander.bastools.api.optimizations.ExtractConstantValues; +import io.github.applecommander.bastools.api.optimizations.ShortenVariableNames; import io.github.applecommander.bastools.api.optimizations.MergeLines; import io.github.applecommander.bastools.api.optimizations.RemoveEmptyStatements; import io.github.applecommander.bastools.api.optimizations.RemoveRemStatements; @@ -15,6 +16,7 @@ import io.github.applecommander.bastools.api.optimizations.Renumber; public enum Optimization { REMOVE_EMPTY_STATEMENTS(RemoveEmptyStatements::new), REMOVE_REM_STATEMENTS(RemoveRemStatements::new), + SHORTEN_VARIABLE_NAMES(ShortenVariableNames::new), EXTRACT_CONSTANT_VALUES(ExtractConstantValues::new), MERGE_LINES(MergeLines::new), RENUMBER(Renumber::new); diff --git a/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedBinaryDirective.java b/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedBinaryDirective.java index fcb8da8..caf93fa 100644 --- a/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedBinaryDirective.java +++ b/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedBinaryDirective.java @@ -42,7 +42,7 @@ public class EmbeddedBinaryDirective extends Directive { variableName.ifPresent(var -> { builder.basic() - .assign(var, embeddedStart) + .assign(resolve(var), embeddedStart) .endStatement(); }); diff --git a/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedShapeTable.java b/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedShapeTable.java index 74658a1..d09a3d2 100644 --- a/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedShapeTable.java +++ b/api/src/main/java/io/github/applecommander/bastools/api/directives/EmbeddedShapeTable.java @@ -67,7 +67,7 @@ public class EmbeddedShapeTable extends Directive { // Setup common code if (poke) basic.POKEW(232, shapeTableStart).endStatement(); if (init) basic.ROT(0).endStatement().SCALE(1).endStatement(); - address.ifPresent(var -> basic.assign(var, shapeTableStart).endStatement()); + address.ifPresent(var -> basic.assign(resolve(var), shapeTableStart).endStatement()); // Inject src options assign.ifPresent(expr -> setupVariables(expr, basic, shapeTable)); @@ -85,7 +85,7 @@ public class EmbeddedShapeTable extends Directive { builder.generate(startAddress).writeTo(this.outputStream); } - + public void setupVariables(MapExpression expr, BasicBuilder basic, Optional shapeTableOptional) { ShapeTable st = shapeTableOptional.orElseThrow(() -> new RuntimeException("ShapeTable source not supplied")); expr.entrySet().forEach(e -> { @@ -93,7 +93,7 @@ public class EmbeddedShapeTable extends Directive { .map(SimpleExpression::asString) .orElseThrow(() -> new RuntimeException( String.format("Unexpected format of asignments for variable '%s'", e.getKey()))); - basic.assign(e.getKey(), st.findPositionByLabel(label)).endStatement(); + basic.assign(resolve(e.getKey()), st.findPositionByLabel(label)).endStatement(); }); } @@ -104,7 +104,7 @@ public class EmbeddedShapeTable extends Directive { ShapeTable st = shapeTableOptional.orElseThrow(() -> new RuntimeException("ShapeTable source not supplied")); for (int i=0; i existingVariables = collector.getVariableNames(); + + // Preassign all variable names + for (String originalName : existingVariables) { + String newName = originalName; + if (newName.replaceAll("[^\\p{Alnum}]","").length() > 2) { + String varType = newName.replaceAll("[\\p{Alnum}]",""); + do { + newName = variableGenerator.get().orElseThrow(() -> new RuntimeException("Ran out of variable names to assign")); + newName += varType; + } while (existingVariables.contains(newName)); + config.debugStream.printf("Replacing '%s' with '%s'\n", originalName, newName); + } + config.variableReplacements.put(originalName, newName); + } + // Continue walking the tree to replace the variables! + return super.visit(program); + } + + @Override + public Statement visit(Statement statement) { + if (statement.tokens.get(0).type == Type.DIRECTIVE) { + return statement; + } + return super.visit(statement); + } + + @Override + public Token visit(Token token) { + if (token.type == Type.IDENT) { + return Token.ident(token.line, config.variableReplacements.get(token.text)); + } + return super.visit(token); + } +} diff --git a/tools/bt/src/main/java/io/github/applecommander/bastools/tools/bt/Main.java b/tools/bt/src/main/java/io/github/applecommander/bastools/tools/bt/Main.java index 22328a9..d9c8650 100644 --- a/tools/bt/src/main/java/io/github/applecommander/bastools/tools/bt/Main.java +++ b/tools/bt/src/main/java/io/github/applecommander/bastools/tools/bt/Main.java @@ -79,6 +79,7 @@ public class Main implements Callable { "Enable specific optimizations.", "* @|green remove-empty-statements|@ - Strip out all '::'-like statements.", "* @|green remove-rem-statements|@ - Remove all REM statements.", + "* @|green shorten-variable-names|@ - Ensure all variables are 1 or 2 characters long.", "* @|green extract-constant-values|@ - Assign all constant values first.", "* @|green merge-lines|@ - Merge lines.", "* @|green renumber|@ - Renumber program."