mirror of
https://github.com/AppleCommander/bastools.git
synced 2025-03-10 20:37:37 +00:00
Beginning with variable report. Need to handle arrays yet. #10.
This commit is contained in:
parent
8b8b26258a
commit
573c0cdbe9
@ -96,17 +96,25 @@ public class TokenReader {
|
||||
}
|
||||
return Optional.of(Token.comment(line, sb.toString()));
|
||||
}
|
||||
// Optional and exceptions don't play well. :-/
|
||||
if (opt.isPresent() && opt.get().parts.size() > 1) {
|
||||
// Pull next token and see if it is the 2nd part ("MID$" == "MID", "$"; checking for the "$")
|
||||
next(depth-1)
|
||||
.filter(t -> opt.get().parts.get(1).equals(t.text))
|
||||
.orElseThrow(() -> new IOException("Expecting: " + opt.get().parts));
|
||||
// If we found an Applesoft token, handle it special
|
||||
if (opt.isPresent()) {
|
||||
if (opt.get().parts.size() > 1) {
|
||||
// Pull next token and see if it is the 2nd part ("MID$" == "MID", "$"; checking for the "$")
|
||||
next(depth-1)
|
||||
.filter(t -> opt.get().parts.get(1).equals(t.text))
|
||||
.orElseThrow(() -> new IOException("Expecting: " + opt.get().parts));
|
||||
}
|
||||
return Optional.of(Token.keyword(line, opt.get()));
|
||||
} else {
|
||||
// Found an identifier. Need to find X, X%, X$, X(, X$(, X%( patterns.
|
||||
String sval = tokenizer.sval;
|
||||
tokenizer.nextToken();
|
||||
if (tokenizer.ttype == '%' || tokenizer.ttype == '$') {
|
||||
sval += (char)tokenizer.ttype;
|
||||
}
|
||||
tokenizer.pushBack();
|
||||
return Optional.of(Token.ident(line, sval));
|
||||
}
|
||||
return Optional.of(opt
|
||||
.map(kw -> Token.keyword(line, kw))
|
||||
.orElse(Token.ident(line, tokenizer.sval)));
|
||||
case '"':
|
||||
return Optional.of(Token.string(line, tokenizer.sval));
|
||||
case '(':
|
||||
|
@ -3,6 +3,10 @@ package com.webcodepro.applecommander.util.applesoft;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@ -57,6 +61,10 @@ public class Visitors {
|
||||
public static ReassignmentVisitor reassignVisitor(Map<Integer,Integer> reassignments) {
|
||||
return new ReassignmentVisitor(reassignments);
|
||||
}
|
||||
|
||||
public static Visitor variableReportVisitor() {
|
||||
return new VariableReportVisitor();
|
||||
}
|
||||
|
||||
private static class PrettyPrintVisitor implements Visitor {
|
||||
private PrintStream printStream;
|
||||
@ -336,4 +344,46 @@ public class Visitors {
|
||||
return newStatement;
|
||||
}
|
||||
}
|
||||
|
||||
private static class VariableReportVisitor implements Visitor {
|
||||
private Map<String,List<Integer>> refs = new HashMap<>();
|
||||
private int currentLineNumber = -1;
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
Program p = Visitor.super.visit(program);
|
||||
refs.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.forEach(this::print);
|
||||
return p;
|
||||
}
|
||||
private void print(Map.Entry<String,List<Integer>> e) {
|
||||
System.out.printf("%-8s ", e.getKey());
|
||||
int c = 0;
|
||||
for (int i : e.getValue()) {
|
||||
System.out.printf("%d, ", i);
|
||||
if (c++ > 10) {
|
||||
c = 0;
|
||||
System.out.printf("\n ");
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Line visit(Line line) {
|
||||
currentLineNumber = line.lineNumber;
|
||||
return Visitor.super.visit(line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token visit(Token token) {
|
||||
if (token.type == Type.IDENT) {
|
||||
refs.merge(token.text,
|
||||
new ArrayList<>(Arrays.asList(currentLineNumber)),
|
||||
(a,b) -> { a.addAll(b); return a; });
|
||||
}
|
||||
return Visitor.super.visit(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ public class Main implements Callable<Void> {
|
||||
@Option(names = { "-a", "--address" }, description = "Base address for program", showDefaultValue = Visibility.ALWAYS, converter = IntegerTypeConverter.class)
|
||||
private int address = 0x801;
|
||||
|
||||
@Option(names = { "--variables" }, description = "Generate a variable report")
|
||||
private boolean showVariableReport;
|
||||
|
||||
@Option(names = { "-p", "--pipe" }, description = "Pipe binary output to stdout.")
|
||||
private boolean pipeOutput;
|
||||
|
||||
@ -88,10 +91,10 @@ public class Main implements Callable<Void> {
|
||||
optimizations.clear();
|
||||
optimizations.addAll(Arrays.asList(Optimization.values()));
|
||||
}
|
||||
if (pipeOutput && (hexFormat || copyFormat || prettyPrint || listPrint || showTokens)) {
|
||||
if (pipeOutput && (hexFormat || copyFormat || prettyPrint || listPrint || showTokens || showVariableReport)) {
|
||||
System.err.println("The pipe option blocks any other stdout options.");
|
||||
return false;
|
||||
} else if (!(pipeOutput || hexFormat || copyFormat || prettyPrint || listPrint || showTokens || outputFile != null)) {
|
||||
} else if (!(pipeOutput || hexFormat || copyFormat || prettyPrint || listPrint || showTokens || showVariableReport || outputFile != null)) {
|
||||
System.err.println("What do you want to do?");
|
||||
return false;
|
||||
}
|
||||
@ -114,6 +117,9 @@ public class Main implements Callable<Void> {
|
||||
if (prettyPrint || listPrint) {
|
||||
program.accept(Visitors.printBuilder().prettyPrint(prettyPrint).build());
|
||||
}
|
||||
if (showVariableReport) {
|
||||
program.accept(Visitors.variableReportVisitor());
|
||||
}
|
||||
|
||||
byte[] data = Visitors.byteVisitor(address).dump(program);
|
||||
if (hexFormat) {
|
||||
|
32
src/test/resources/circles.bas
Normal file
32
src/test/resources/circles.bas
Normal file
@ -0,0 +1,32 @@
|
||||
TEXT
|
||||
NEW
|
||||
10 GOTO 100
|
||||
20 REM DRAW CIRCLE ROUTINE
|
||||
30 FOR A = 0 TO PT
|
||||
40 X = X(A) * SZ:Y = Y(A) * SZ
|
||||
50 HPLOT XO + X,YO + Y
|
||||
60 HPLOT XO - X,YO + Y
|
||||
70 HPLOT XO + X,YO - Y
|
||||
80 HPLOT XO - X,YO - Y
|
||||
90 NEXT A
|
||||
95 RETURN
|
||||
100 REM MAIN PROGRAM
|
||||
110 HGR
|
||||
115 C(0)=1:C(1)=2:C(2)=3:C(3)=5:C(4)=6:C(5)=7
|
||||
120 HOME : VTAB 21: INVERSE : PRINT "JUST A MOMENT": NORMAL
|
||||
130 PI = 3.14159
|
||||
140 PT = 30: DIM X(PT),Y(PT)
|
||||
150 FOR A = 0 TO PT
|
||||
160 B = PI * (A / (PT * 2))
|
||||
170 X(A) = SIN (B)
|
||||
180 Y(A) = COS (B)
|
||||
190 NEXT A
|
||||
200 HOME : VTAB 21
|
||||
210 FOR Q = 1 TO 100
|
||||
215 C = 6 * RND(1) : HCOLOR= C(C)
|
||||
220 SZ = 10 + (40 * RND (1))
|
||||
230 XO = (279 - SZ*2) * RND (1) + SZ
|
||||
240 YO = (159 - SZ*2) * RND (1) + SZ
|
||||
250 GOSUB 30
|
||||
260 NEXT Q
|
||||
RUN
|
Loading…
x
Reference in New Issue
Block a user