Beginning with variable report. Need to handle arrays yet. #10.

This commit is contained in:
Rob Greene 2018-05-17 21:02:13 -05:00
parent 8b8b26258a
commit 573c0cdbe9
4 changed files with 107 additions and 11 deletions

View File

@ -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 '(':

View File

@ -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);
}
}
}

View File

@ -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) {

View 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