mirror of
https://github.com/AppleCommander/bastools.git
synced 2025-04-07 05:37:04 +00:00
Allowing tree rewrite to remove REM statements and renumber application.
Closes #1.
This commit is contained in:
parent
bbc6b29bda
commit
047591ec58
@ -3,11 +3,14 @@ package com.webcodepro.applecommander.util.applesoft;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Stack;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.webcodepro.applecommander.util.applesoft.Token.Type;
|
||||
|
||||
/**
|
||||
* This class presents all of the common Visitor implementations via builder patterns.
|
||||
* The number is currently small enough that all the builders and visitors are defined
|
||||
@ -49,6 +52,11 @@ public class Visitors {
|
||||
public static ByteVisitor byteVisitor(int address) {
|
||||
return new ByteVisitor(address);
|
||||
}
|
||||
|
||||
/** Rewrite the Program tree with the line number reassignments given. */
|
||||
public static ReassignmentVisitor reassignVisitor(Map<Integer,Integer> reassignments) {
|
||||
return new ReassignmentVisitor(reassignments);
|
||||
}
|
||||
|
||||
private static class PrettyPrintVisitor implements Visitor {
|
||||
private PrintStream printStream;
|
||||
@ -268,4 +276,64 @@ public class Visitors {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This is a mildly rewritable Visitor. */
|
||||
private static class ReassignmentVisitor implements Visitor {
|
||||
private Map<Integer,Integer> reassignments;
|
||||
|
||||
private ReassignmentVisitor(Map<Integer,Integer> reassignments) {
|
||||
this.reassignments = reassignments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
Program newProgram = new Program();
|
||||
program.lines.forEach(l -> {
|
||||
Line line = l.accept(this);
|
||||
newProgram.lines.add(line);
|
||||
});
|
||||
return newProgram;
|
||||
}
|
||||
@Override
|
||||
public Line visit(Line line) {
|
||||
Line newLine = new Line(line.lineNumber);
|
||||
line.statements.forEach(s -> {
|
||||
Statement statement = s.accept(this);
|
||||
newLine.statements.add(statement);
|
||||
});
|
||||
return newLine;
|
||||
}
|
||||
/**
|
||||
* We saw a trigger, reassign any numbers that follow.
|
||||
*
|
||||
* Trigger cases:
|
||||
* - GOSUB n
|
||||
* - GOTO n
|
||||
* - IF ... THEN n
|
||||
* - LIST n [ ,m ]
|
||||
* - ON x GOTO n, m, ...
|
||||
* - ON x GOSUB n, m, ...
|
||||
* - ONERR GOTO n
|
||||
* - RUN n
|
||||
*/
|
||||
@Override
|
||||
public Statement visit(Statement statement) {
|
||||
boolean next = false;
|
||||
Statement newStatement = new Statement();
|
||||
for (Token t : statement.tokens) {
|
||||
Token newToken = t;
|
||||
if (next) {
|
||||
if (t.type == Type.NUMBER && reassignments.containsKey(t.number.intValue())) {
|
||||
newToken = Token.number(t.line, reassignments.get(t.number.intValue()).doubleValue());
|
||||
}
|
||||
} else {
|
||||
next = t.keyword == ApplesoftKeyword.GOSUB || t.keyword == ApplesoftKeyword.GOTO
|
||||
|| t.keyword == ApplesoftKeyword.THEN || t.keyword == ApplesoftKeyword.RUN
|
||||
|| t.keyword == ApplesoftKeyword.LIST;
|
||||
}
|
||||
newStatement.tokens.add(newToken);
|
||||
}
|
||||
return newStatement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package io.github.applecommander.bastokenizer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.webcodepro.applecommander.util.applesoft.Line;
|
||||
import com.webcodepro.applecommander.util.applesoft.Program;
|
||||
import com.webcodepro.applecommander.util.applesoft.Statement;
|
||||
import com.webcodepro.applecommander.util.applesoft.Token;
|
||||
import com.webcodepro.applecommander.util.applesoft.Token.Type;
|
||||
import com.webcodepro.applecommander.util.applesoft.Visitor;
|
||||
import com.webcodepro.applecommander.util.applesoft.Visitors;
|
||||
|
||||
import picocli.CommandLine.ITypeConverter;
|
||||
|
||||
@ -51,12 +55,25 @@ public enum Optimization {
|
||||
private static class BaseVisitor implements Visitor {
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
Program newProgram = new Program();
|
||||
final Program newProgram = new Program();
|
||||
Map<Integer,Integer> reassignments = new HashMap<>();
|
||||
program.lines.forEach(l -> {
|
||||
Line line = l.accept(this);
|
||||
if (line != null && !line.statements.isEmpty()) newProgram.lines.add(line);
|
||||
boolean lineKept = line != null && !line.statements.isEmpty();
|
||||
if (lineKept) {
|
||||
newProgram.lines.add(line);
|
||||
reassignments.replaceAll((k,v) -> v == null ? l.lineNumber : v);
|
||||
} else {
|
||||
// Make a place-holder for the reassignment; we'll patch it in once we find a line that sticks around.
|
||||
reassignments.put(l.lineNumber, null);
|
||||
}
|
||||
});
|
||||
return newProgram;
|
||||
if (!reassignments.isEmpty()) {
|
||||
// Now, renumber based on our findings!
|
||||
return newProgram.accept(Visitors.reassignVisitor(reassignments));
|
||||
} else {
|
||||
return newProgram;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Line visit(Line line) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user