mirror of
https://github.com/AppleCommander/bastools.git
synced 2026-10-22 03:02:37 +00:00
Two changes: (1) Refactored "proofreaders" into an input buffer-based proofreader and a tokenized proofreader along with code changes; (2) Checkit now handles "?" as "PRINT".
This commit is contained in:
1 parent
20d8d53b5a
commit
2c03a3c62d
18 files changed
+431
-321
No files matched your search
+35
@@ -0,0 +1,35 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.Visitor;
|
||||
import org.applecommander.bastools.api.Visitors;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* Standard interface for proofreaders that are evaluated as code is typed in.
|
||||
* That is, these evaluate the input buffer at $200 when a return is issued.
|
||||
*/
|
||||
public interface ApplesoftInputBufferProofReader {
|
||||
/**
|
||||
* Returns the configuration object to use. The configuration object includes the following details:
|
||||
* start address, number preservation settings, and file name.
|
||||
*/
|
||||
Configuration getConfiguration();
|
||||
/** Adds program by converting to text and using addProgramText. */
|
||||
default void addProgram(Program program) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PrintStream printStream = new PrintStream(outputStream);
|
||||
Visitor printVisitor = Visitors.printBuilder(getConfiguration()).printStream(printStream).print().build();
|
||||
printVisitor.visit(program);
|
||||
addProgramText(outputStream.toString());
|
||||
}
|
||||
/** Adds source code line-by-line using addLine. */
|
||||
default void addProgramText(String code) {
|
||||
code.lines().forEach(this::addLine);
|
||||
}
|
||||
/** Parses the line and adds to the current checksums. */
|
||||
void addLine(String line);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
import org.applecommander.bastools.api.visitors.ByteVisitor;
|
||||
|
||||
/**
|
||||
* Standard interface for proofreaders that evaluate a tokenized program.
|
||||
*/
|
||||
public interface ApplesoftTokenizedProofReader {
|
||||
/**
|
||||
* Returns the configuration object to use. The configuration object includes the following details:
|
||||
* start address, number preservation settings, and file name.
|
||||
*/
|
||||
Configuration getConfiguration();
|
||||
/** Convert the Program to a tokenized byte[] and then process with proofreader. */
|
||||
default void addProgram(Program program) {
|
||||
ByteVisitor byteVisitor = new ByteVisitor(getConfiguration());
|
||||
byteVisitor.visit(program);
|
||||
addBytes(byteVisitor.getBytes());
|
||||
}
|
||||
/** Parses the line and adds to the current checksums. */
|
||||
void addBytes(byte... tokenizedProgram);
|
||||
}
|
||||
+50
-27
@@ -1,34 +1,43 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.model.Line;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
|
||||
public class ComputeAutomaticProofreader extends LineOrientedProofReader {
|
||||
public class ComputeAutomaticProofreader implements ApplesoftInputBufferProofReader {
|
||||
private final Configuration config;
|
||||
private final Checksum checksum = new Checksum();
|
||||
|
||||
public ComputeAutomaticProofreader(Configuration config) {
|
||||
super(config);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
public Configuration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProgram(Program program) {
|
||||
System.out.println("Compute! Apple Automatic Proofreader, Copyright 1985");
|
||||
return super.visit(program);
|
||||
ApplesoftInputBufferProofReader.super.addProgram(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Line visit(Line line) {
|
||||
String text = toString(line);
|
||||
|
||||
int checksum = 0;
|
||||
for (int i=text.length()-1; i>=0; i--) {
|
||||
char ch = text.charAt(i);
|
||||
public void addLine(String line) {
|
||||
checksum.reset();
|
||||
for (int i=line.length()-1; i>=0; i--) {
|
||||
char ch = line.charAt(i);
|
||||
if (ch != ' ') {
|
||||
checksum = proofreader(checksum, ch|0x80);
|
||||
checksum.add(ch|0x80);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.printf("%02X | %s\n", checksum, text);
|
||||
return line;
|
||||
System.out.printf("%02X | %s\n", checksum.value(), line);
|
||||
}
|
||||
|
||||
// For testing purposes; only valid for the line
|
||||
protected int getChecksumValue() {
|
||||
return checksum.value();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,20 +52,34 @@ public class ComputeAutomaticProofreader extends LineOrientedProofReader {
|
||||
* </pre>
|
||||
* Generalized algorithm: <code>cksum = (cksum << 1) + (char|$80) + carry</code>
|
||||
*/
|
||||
public static int proofreader(int checksum, int value) {
|
||||
assert value >= 0 && value <= 0xff;
|
||||
checksum <<= 1;
|
||||
// Handle carry from ASL
|
||||
if (checksum > 0xff) {
|
||||
checksum++;
|
||||
checksum &= 0xff;
|
||||
public static class Checksum implements ProofReaderChecksum {
|
||||
private int checksum = 0;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.checksum = 0;
|
||||
}
|
||||
// Handle carry from first ADC
|
||||
checksum += value;
|
||||
if (checksum > 0xff) {
|
||||
checksum++;
|
||||
checksum &= 0xff;
|
||||
|
||||
@Override
|
||||
public void add(int value) {
|
||||
assert value >= 0 && value <= 0xff;
|
||||
checksum <<= 1;
|
||||
// Handle carry from ASL
|
||||
if (checksum > 0xff) {
|
||||
checksum++;
|
||||
checksum &= 0xff;
|
||||
}
|
||||
// Handle carry from first ADC
|
||||
checksum += value;
|
||||
if (checksum > 0xff) {
|
||||
checksum++;
|
||||
checksum &= 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int value() {
|
||||
return checksum;
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.Visitor;
|
||||
import org.applecommander.bastools.api.model.Line;
|
||||
import org.applecommander.bastools.api.model.Statement;
|
||||
import org.applecommander.bastools.api.model.Token;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
public abstract class LineOrientedProofReader implements Visitor {
|
||||
protected final Configuration config;
|
||||
|
||||
protected LineOrientedProofReader(Configuration config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String toString(Line line) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
pw.printf("%d ", line.lineNumber);
|
||||
boolean first = true;
|
||||
for (Statement statement : line.statements) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
pw.print(":");
|
||||
}
|
||||
for (Token token : statement.tokens) {
|
||||
switch (token.type()) {
|
||||
case EOL:
|
||||
pw.print("<EOL>");
|
||||
break;
|
||||
case COMMENT:
|
||||
pw.printf("REM %s", token.text());
|
||||
break;
|
||||
case DATA, IDENT, SYNTAX:
|
||||
pw.print(token.text());
|
||||
break;
|
||||
case STRING:
|
||||
pw.printf("\"%s\"", token.text());
|
||||
break;
|
||||
case KEYWORD:
|
||||
pw.printf(" %s ", token.keyword().text);
|
||||
break;
|
||||
case DIRECTIVE:
|
||||
pw.printf("%s ", token.text());
|
||||
break;
|
||||
case NUMBER:
|
||||
pw.print(config.numberToString(token));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sw.toString();
|
||||
}
|
||||
}
|
||||
+8
-11
@@ -1,9 +1,6 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.Visitor;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
import org.applecommander.bastools.api.visitors.ByteVisitor;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -44,19 +41,21 @@ import java.util.List;
|
||||
* 1710- 60 RTS
|
||||
* </pre>
|
||||
*/
|
||||
public class MicrosparcKeyPerfect2 implements Visitor {
|
||||
public class MicrosparcKeyPerfect2 implements ApplesoftTokenizedProofReader {
|
||||
private final Configuration config;
|
||||
private final ByteVisitor byteVisitor;
|
||||
|
||||
public MicrosparcKeyPerfect2(Configuration config) {
|
||||
this.config = config;
|
||||
this.byteVisitor = new ByteVisitor(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
byteVisitor.visit(program);
|
||||
ByteBuffer code = ByteBuffer.wrap(byteVisitor.getBytes());
|
||||
public Configuration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBytes(byte... tokenizedProgram) {
|
||||
ByteBuffer code = ByteBuffer.wrap(tokenizedProgram);
|
||||
code.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
System.out.println("Line# - Line# CODE-2.0");
|
||||
@@ -96,8 +95,6 @@ public class MicrosparcKeyPerfect2 implements Visitor {
|
||||
printLines(lines, lineChecksum);
|
||||
}
|
||||
printLine("PROGRAM TOTAL", programChecksum);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
public void printLines(List<Integer> lines, int lineChecksum) {
|
||||
|
||||
+18
-18
@@ -1,9 +1,6 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.Visitor;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
import org.applecommander.bastools.api.visitors.ByteVisitor;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -85,19 +82,21 @@ import java.util.List;
|
||||
* </pre>
|
||||
* ('@' replaced with ']' since Javadoc uses '@' for other purposes.)
|
||||
*/
|
||||
public class MicrosparcKeyPerfect4 implements Visitor {
|
||||
public class MicrosparcKeyPerfect4 implements ApplesoftTokenizedProofReader {
|
||||
private final Configuration config;
|
||||
private final ByteVisitor byteVisitor;
|
||||
|
||||
public MicrosparcKeyPerfect4(Configuration config) {
|
||||
this.config = config;
|
||||
this.byteVisitor = new ByteVisitor(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
byteVisitor.visit(program);
|
||||
ByteBuffer code = ByteBuffer.wrap(byteVisitor.getBytes());
|
||||
public Configuration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBytes(byte... tokenizedProgram) {
|
||||
ByteBuffer code = ByteBuffer.wrap(tokenizedProgram);
|
||||
code.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
System.out.println("Line# - Line# CODE-4.0");
|
||||
@@ -112,9 +111,9 @@ public class MicrosparcKeyPerfect4 implements Visitor {
|
||||
if (ptr == 0) break;
|
||||
// Line number always gets added to checksum and total
|
||||
int b1 = Byte.toUnsignedInt(code.get());
|
||||
checksum.addByte(b1);
|
||||
checksum.add(b1);
|
||||
int b2 = Byte.toUnsignedInt(code.get());
|
||||
checksum.addByte(b2);
|
||||
checksum.add(b2);
|
||||
programChecksum+= 2;
|
||||
lines.add(b2 << 8 | b1);
|
||||
// Process tokenized line...
|
||||
@@ -123,7 +122,7 @@ public class MicrosparcKeyPerfect4 implements Visitor {
|
||||
ch = Byte.toUnsignedInt(code.get());
|
||||
if (ch > 0x20 || ch == 0x04) {
|
||||
programChecksum++;
|
||||
checksum.addByte(ch);
|
||||
checksum.add(ch);
|
||||
}
|
||||
} while (ch > 0);
|
||||
|
||||
@@ -137,15 +136,13 @@ public class MicrosparcKeyPerfect4 implements Visitor {
|
||||
printLines(lines, checksum);
|
||||
}
|
||||
printLine("PROGRAM TOTAL", programChecksum);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
public void printLines(List<Integer> lines, Checksum checksum) {
|
||||
int firstLine = lines.getFirst();
|
||||
int lastLine = lines.getLast();
|
||||
String text = String.format("%5d - %5d", firstLine, lastLine);
|
||||
printLine(text, checksum.getChecksum());
|
||||
printLine(text, checksum.value());
|
||||
}
|
||||
|
||||
public static void printLine(String text, int checksum) {
|
||||
@@ -161,20 +158,23 @@ public class MicrosparcKeyPerfect4 implements Visitor {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static class Checksum {
|
||||
public static class Checksum implements ProofReaderChecksum {
|
||||
private int lineChecksum = 0; // low byte with has EOR, ROL, ADC
|
||||
private int lineCounter = 0; // high 2 bytes that just ADC on carry
|
||||
|
||||
public int getChecksum() {
|
||||
@Override
|
||||
public int value() {
|
||||
return lineCounter << 8 | lineChecksum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
lineChecksum = 0;
|
||||
lineCounter = 0;
|
||||
}
|
||||
|
||||
public void addByte(int code) {
|
||||
@Override
|
||||
public void add(int code) {
|
||||
int acc = lineChecksum ^ code;
|
||||
acc <<= 1;
|
||||
if (acc > 0xff) {
|
||||
|
||||
+23
-24
@@ -1,11 +1,7 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.Visitor;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
import org.applecommander.bastools.api.visitors.ByteVisitor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
@@ -110,19 +106,21 @@ import java.util.List;
|
||||
* </pre>
|
||||
* ('@' replaced with ']' since Javadoc uses '@' for other purposes.)
|
||||
*/
|
||||
public class MicrosparcKeyPerfect5 implements Visitor {
|
||||
public class MicrosparcKeyPerfect5 implements ApplesoftTokenizedProofReader {
|
||||
private final Configuration config;
|
||||
private final ByteVisitor byteVisitor;
|
||||
|
||||
public MicrosparcKeyPerfect5(Configuration config) {
|
||||
this.config = config;
|
||||
this.byteVisitor = new ByteVisitor(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
byteVisitor.visit(program);
|
||||
ByteBuffer code = ByteBuffer.wrap(byteVisitor.getBytes());
|
||||
public Configuration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBytes(byte... tokenizedProgram) {
|
||||
ByteBuffer code = ByteBuffer.wrap(tokenizedProgram);
|
||||
code.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
System.out.println("Line# - Line# CODE-5.0");
|
||||
@@ -136,11 +134,11 @@ public class MicrosparcKeyPerfect5 implements Visitor {
|
||||
if (ptr == 0) break;
|
||||
// Line number always gets added to checksum and total
|
||||
int b1 = Byte.toUnsignedInt(code.get());
|
||||
lineChecksum.addByte(b1);
|
||||
pgmChecksum.addByte(b1);
|
||||
lineChecksum.add(b1);
|
||||
pgmChecksum.add(b1);
|
||||
int b2 = Byte.toUnsignedInt(code.get());
|
||||
lineChecksum.addByte(b2);
|
||||
pgmChecksum.addByte(b2);
|
||||
lineChecksum.add(b2);
|
||||
pgmChecksum.add(b2);
|
||||
lines.add(b2 << 8 | b1);
|
||||
// Process tokenized line...
|
||||
boolean inComment = false;
|
||||
@@ -149,8 +147,8 @@ public class MicrosparcKeyPerfect5 implements Visitor {
|
||||
ch = Byte.toUnsignedInt(code.get());
|
||||
if (ch == 0xb2) {
|
||||
inComment = true;
|
||||
lineChecksum.addByte(ch);
|
||||
pgmChecksum.addByte(ch);
|
||||
lineChecksum.add(ch);
|
||||
pgmChecksum.add(ch);
|
||||
}
|
||||
else if (inComment) {
|
||||
// do not add to checksum
|
||||
@@ -159,8 +157,8 @@ public class MicrosparcKeyPerfect5 implements Visitor {
|
||||
if (ch >= 0x60 && ch < 0x80) {
|
||||
ch -= 0x20; // Force characters to uppercase
|
||||
}
|
||||
lineChecksum.addByte(ch);
|
||||
pgmChecksum.addByte(ch);
|
||||
lineChecksum.add(ch);
|
||||
pgmChecksum.add(ch);
|
||||
}
|
||||
} while (ch > 0);
|
||||
|
||||
@@ -174,8 +172,6 @@ public class MicrosparcKeyPerfect5 implements Visitor {
|
||||
printLines(lines, lineChecksum);
|
||||
}
|
||||
printLine("PROGRAM TOTAL", pgmChecksum);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
public void printLines(List<Integer> lines, Checksum checksum) {
|
||||
@@ -186,24 +182,27 @@ public class MicrosparcKeyPerfect5 implements Visitor {
|
||||
}
|
||||
|
||||
public static void printLine(String text, Checksum checksum) {
|
||||
System.out.printf("%-13.13s %08X\n", text, checksum.getChecksum());
|
||||
System.out.printf("%-13.13s %08X\n", text, checksum.value());
|
||||
}
|
||||
|
||||
public static class Checksum {
|
||||
public static class Checksum implements ProofReaderChecksum {
|
||||
/**
|
||||
* Checksum is 4 bytes, long is 8 so we don't get surprised by negativity.
|
||||
*/
|
||||
private long checksum = 0xffffffffL;
|
||||
|
||||
public int getChecksum() {
|
||||
@Override
|
||||
public int value() {
|
||||
return (int)checksum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
checksum = 0xffffffffL;
|
||||
}
|
||||
|
||||
public void addByte(int code) {
|
||||
@Override
|
||||
public void add(int code) {
|
||||
assert code >= 0 && code <= 0xff;
|
||||
// Combines the CHKSUM_V5_1 effort
|
||||
int idx = (int)(checksum >> 24 & 0xff) ^ code;
|
||||
|
||||
+69
-60
@@ -1,70 +1,64 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.Visitor;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
import org.applecommander.bastools.api.visitors.ByteVisitor;
|
||||
|
||||
public class NibbleAppleChecker implements Visitor {
|
||||
public class NibbleAppleChecker implements ApplesoftTokenizedProofReader {
|
||||
private final Configuration config;
|
||||
private final ByteVisitor byteVisitor;
|
||||
private int length;
|
||||
private final Checksum checksum = new Checksum();
|
||||
|
||||
public NibbleAppleChecker(Configuration config) {
|
||||
this.config = config;
|
||||
this.byteVisitor = new ByteVisitor(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
byteVisitor.visit(program);
|
||||
byte[] code = byteVisitor.getBytes();
|
||||
Checksum checksum = new Checksum();
|
||||
checksum.compute(code, config.startAddress);
|
||||
public Configuration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProgram(Program program) {
|
||||
ApplesoftTokenizedProofReader.super.addProgram(program);
|
||||
|
||||
System.out.printf("On: %s\n", config.sourceFile.getName());
|
||||
System.out.println("Type: A");
|
||||
System.out.println();
|
||||
System.out.printf("Length: %04X\n", checksum.getLength());
|
||||
System.out.printf("Checksum: %02X\n", checksum.getChecksum());
|
||||
return program;
|
||||
System.out.printf("Length: %04X\n", length);
|
||||
System.out.printf("Checksum: %02X\n", checksum.value());
|
||||
}
|
||||
|
||||
public static class Checksum {
|
||||
private int length;
|
||||
private int checksum;
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
@Override
|
||||
public void addBytes(byte... tokenizedProgram) {
|
||||
// Length is less 2 for Applesoft
|
||||
length = tokenizedProgram.length+1 - 2;
|
||||
// Zero out the next line links
|
||||
int nextAddr = config.startAddress;
|
||||
while (nextAddr >= 0 && nextAddr < tokenizedProgram.length) {
|
||||
nextAddr = (tokenizedProgram[nextAddr+1]<<8 | tokenizedProgram[nextAddr]) - config.startAddress;
|
||||
tokenizedProgram[nextAddr] = 0;
|
||||
tokenizedProgram[nextAddr+1] = 0;
|
||||
}
|
||||
public int getChecksum() {
|
||||
return checksum;
|
||||
}
|
||||
|
||||
public void compute(byte[] code, int startAddress) {
|
||||
// Length is less 2 for Applesoft
|
||||
length = code.length+1 - 2;
|
||||
// Zero out the next line links
|
||||
int nextAddr = startAddress;
|
||||
while (nextAddr >= 0 && nextAddr < code.length) {
|
||||
nextAddr = (code[nextAddr+1]<<8 | code[nextAddr]) - startAddress;
|
||||
code[nextAddr] = 0;
|
||||
code[nextAddr+1] = 0;
|
||||
}
|
||||
// Compute checksum
|
||||
this.checksum = 0;
|
||||
for (int i=0; i<code.length; i++) {
|
||||
int acc = Byte.toUnsignedInt(code[i]);
|
||||
if (acc >= 0x21 || acc == 0x04) {
|
||||
this.checksum = checksum(this.checksum, acc);
|
||||
}
|
||||
else {
|
||||
// We skip _and_ reduce the length by 1
|
||||
this.length--;
|
||||
}
|
||||
// Compute checksum
|
||||
checksum.reset();
|
||||
for (byte b : tokenizedProgram) {
|
||||
int acc = Byte.toUnsignedInt(b);
|
||||
if (acc >= 0x21 || acc == 0x04) {
|
||||
checksum.add(acc);
|
||||
} else {
|
||||
// We skip _and_ reduce the length by 1
|
||||
this.length--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
public int getChecksumValue() {
|
||||
return checksum.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a single iteration of the checksum. Broken out for testing purposes.
|
||||
* <pre>
|
||||
@@ -76,23 +70,38 @@ public class NibbleAppleChecker implements Visitor {
|
||||
* STA CKCD
|
||||
* </pre>
|
||||
*/
|
||||
public static int checksum(int checksum, int acc) {
|
||||
// EOR CKCD
|
||||
acc ^= checksum;
|
||||
// ROL A
|
||||
acc <<= 1;
|
||||
// ADC CKCD
|
||||
if (acc >= 0xff) {
|
||||
checksum++;
|
||||
acc &= 0xff;
|
||||
public static class Checksum implements ProofReaderChecksum {
|
||||
private int checksum;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.checksum = 0;
|
||||
}
|
||||
acc += checksum;
|
||||
// ADC #0
|
||||
if (acc > 0xff) {
|
||||
acc++;
|
||||
acc &= 0xff;
|
||||
|
||||
@Override
|
||||
public void add(int acc) {
|
||||
// EOR CKCD
|
||||
acc ^= checksum;
|
||||
// ROL A
|
||||
acc <<= 1;
|
||||
// ADC CKCD
|
||||
if (acc >= 0xff) {
|
||||
checksum++;
|
||||
acc &= 0xff;
|
||||
}
|
||||
acc += checksum;
|
||||
// ADC #0
|
||||
if (acc > 0xff) {
|
||||
acc++;
|
||||
acc &= 0xff;
|
||||
}
|
||||
// STA CKCD
|
||||
checksum = acc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int value() {
|
||||
return this.checksum;
|
||||
}
|
||||
// STA CKCD
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +1,72 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.applecommander.bastools.api.model.Line;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
import org.applecommander.bastools.api.model.Statement;
|
||||
import org.applecommander.bastools.api.model.Token;
|
||||
|
||||
public class NibbleCheckit extends LineOrientedProofReader {
|
||||
private int totalChecksum;
|
||||
private int lineChecksum;
|
||||
public class NibbleCheckit implements ApplesoftInputBufferProofReader {
|
||||
private final Configuration config;
|
||||
private final Checksum totalChecksum = new Checksum();
|
||||
private final Checksum lineChecksum = new Checksum();
|
||||
|
||||
public NibbleCheckit(Configuration config) {
|
||||
super(config);
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Program visit(Program program) {
|
||||
public Configuration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void addProgramText(String code) {
|
||||
System.out.println("Nibble Checkit, Copyright 1988, Microsparc Inc.");
|
||||
try {
|
||||
return super.visit(program);
|
||||
} finally {
|
||||
System.out.printf("TOTAL: %02X%02X\n", totalChecksum & 0xff, totalChecksum >> 8);
|
||||
}
|
||||
ApplesoftInputBufferProofReader.super.addProgramText(code);
|
||||
System.out.printf("TOTAL: %02X%02X\n", totalChecksum.checksum & 0xff, totalChecksum.checksum >> 8);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Line visit(Line line) {
|
||||
public void addLine(String line) {
|
||||
// Calculate and output line value
|
||||
lineChecksum = 0;
|
||||
for (char ch : Integer.toString(line.lineNumber).toCharArray()) {
|
||||
lineChecksum = checkit(lineChecksum, ch|0x80);
|
||||
}
|
||||
boolean first = true;
|
||||
for (Statement statement : line.statements) {
|
||||
if (!first) {
|
||||
// We need to synthesize the colons
|
||||
lineChecksum = checkit(lineChecksum, ':'|0x80);
|
||||
}
|
||||
super.visit(statement);
|
||||
first = false;
|
||||
}
|
||||
int cs = ( (lineChecksum & 0xff) - (lineChecksum >> 8) ) & 0xff;
|
||||
System.out.printf("%02X | %s\n", cs, toString(line));
|
||||
lineChecksum.reset();
|
||||
|
||||
// Update program values
|
||||
totalChecksum = checkit(totalChecksum, line.lineNumber & 0xff);
|
||||
totalChecksum = checkit(totalChecksum, line.lineNumber >> 8);
|
||||
return line;
|
||||
}
|
||||
// The ? => PRINT replacement always occurs, including in strings!
|
||||
line = line.replace("?", "PRINT");
|
||||
|
||||
@Override
|
||||
public Token visit(Token token) {
|
||||
String value = switch (token.type()) {
|
||||
case EOL, DIRECTIVE -> "";
|
||||
case DATA, SYNTAX, IDENT -> token.text();
|
||||
case COMMENT -> "REM";
|
||||
case KEYWORD -> token.keyword().text;
|
||||
case NUMBER -> {
|
||||
if (token.text() != null) {
|
||||
yield token.text();
|
||||
}
|
||||
yield config.numberToString(token);
|
||||
}
|
||||
case STRING -> String.format("\"%s\"", token.text());
|
||||
};
|
||||
boolean inQuote = false;
|
||||
for (char ch : value.toCharArray()) {
|
||||
StringBuilder remLettersSeen = new StringBuilder();
|
||||
for (char ch : line.toCharArray()) {
|
||||
if (ch == '"') inQuote = !inQuote;
|
||||
if (!inQuote && ch == ' ') continue;
|
||||
lineChecksum = checkit(lineChecksum, ch|0x80);
|
||||
lineChecksum.add(ch|0x80);
|
||||
|
||||
// we only allow R E M from a comment; skip rest of the comment
|
||||
remLettersSeen.append(ch);
|
||||
if ("REM".contentEquals(remLettersSeen)) {
|
||||
break;
|
||||
}
|
||||
else if ("R".contentEquals(remLettersSeen) || "RE".contentEquals(remLettersSeen)) {
|
||||
// Keep them, this may be a comment
|
||||
}
|
||||
else {
|
||||
remLettersSeen = new StringBuilder();
|
||||
}
|
||||
}
|
||||
return token;
|
||||
|
||||
int cs = ( (lineChecksum.checksum & 0xff) - (lineChecksum.checksum >> 8) ) & 0xff;
|
||||
System.out.printf("%02X | %s\n", cs, line);
|
||||
|
||||
// Update program values
|
||||
int lineNumber = Integer.parseInt(line.split(" ")[0].trim());
|
||||
totalChecksum.add(lineNumber & 0xff);
|
||||
totalChecksum.add(lineNumber >> 8);
|
||||
}
|
||||
|
||||
public int getLineChecksumValue() {
|
||||
return lineChecksum.value();
|
||||
}
|
||||
public int getTotalChecksumValue() {
|
||||
return totalChecksum.value();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,17 +97,29 @@ public class NibbleCheckit extends LineOrientedProofReader {
|
||||
* XOR. The result is the middle two bytes where the checksum resides. (Note that the
|
||||
* <code>0x1021</code> was shifted by a byte as well.)
|
||||
*/
|
||||
public static int checkit(int checksum, int value) {
|
||||
assert value >= 0 && value <= 0xff;
|
||||
int work = (checksum << 8) | value;
|
||||
for (int i=0; i<8; i++) {
|
||||
work <<= 1;
|
||||
// Note: If we run into negative issues somehow, this could also be "((work & 0xff000000) != 0)".
|
||||
if (work > 0xffffff) {
|
||||
work &= 0xffffff;
|
||||
work ^= 0x102100;
|
||||
public static class Checksum implements ProofReaderChecksum {
|
||||
private int checksum = 0;
|
||||
@Override
|
||||
public void reset() {
|
||||
this.checksum = 0;
|
||||
}
|
||||
@Override
|
||||
public void add(int value) {
|
||||
assert value >= 0 && value <= 0xff;
|
||||
int work = (checksum << 8) | value;
|
||||
for (int i=0; i<8; i++) {
|
||||
work <<= 1;
|
||||
// Note: If we run into negative issues somehow, this could also be "((work & 0xff000000) != 0)".
|
||||
if (work > 0xffffff) {
|
||||
work &= 0xffffff;
|
||||
work ^= 0x102100;
|
||||
}
|
||||
}
|
||||
checksum = work >> 8;
|
||||
}
|
||||
@Override
|
||||
public int value() {
|
||||
return checksum;
|
||||
}
|
||||
return work >> 8;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
public interface ProofReaderChecksum {
|
||||
/** Reset the checksum back to initial state. */
|
||||
void reset();
|
||||
/** Add a value (typically a byte) into the checksum. */
|
||||
void add(int value);
|
||||
/** Get the current value of the checksum. */
|
||||
int value();
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Queue;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class ClassicTokenReaderTest {
|
||||
@Test
|
||||
@@ -357,6 +357,23 @@ public class ClassicTokenReaderTest {
|
||||
.end());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuestionMarkAsPrint49() throws IOException {
|
||||
testCode("""
|
||||
100 PRINT "HELLO WORLD"
|
||||
110 PRINT "HELLO WORLD?"
|
||||
""",
|
||||
Tokens.builder()
|
||||
.number("100")
|
||||
.keyword(ApplesoftKeyword.PRINT)
|
||||
.data("\"HELLO WORLD\"")
|
||||
.nextLine()
|
||||
.number("110")
|
||||
.keyword(ApplesoftKeyword.PRINT)
|
||||
.data("\"HELLO WORLD?\"")
|
||||
.end());
|
||||
}
|
||||
|
||||
public void testCode(String code, Token... expectedTokens) throws IOException {
|
||||
final Queue<Token> actualTokens = ClassicTokenReader.tokenize(new StringReader(code));
|
||||
final Token[] actualArray = actualTokens.toArray(new Token[0]);
|
||||
|
||||
+10
-8
@@ -1,7 +1,10 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
@@ -17,13 +20,12 @@ public class ComputeAutomaticProofreaderTest {
|
||||
}
|
||||
|
||||
protected int performLineCalc(String text) {
|
||||
int checksum = 0;
|
||||
for (int i=text.length()-1; i>=0; i--) {
|
||||
char ch = text.charAt(i);
|
||||
if (ch != ' ') {
|
||||
checksum = ComputeAutomaticProofreader.proofreader(checksum, ch|0x80);
|
||||
}
|
||||
}
|
||||
return checksum;
|
||||
Configuration config = Configuration.builder()
|
||||
.preserveNumbers(true)
|
||||
.sourceFile(new File("test.bas"))
|
||||
.build();
|
||||
ComputeAutomaticProofreader proofreader = new ComputeAutomaticProofreader(config);
|
||||
proofreader.addLine(text);
|
||||
return proofreader.getChecksumValue();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -16,8 +16,8 @@ public class MicrosparcKeyPerfect4Test {
|
||||
};
|
||||
Checksum checksum = new Checksum();
|
||||
for (int b : code) {
|
||||
checksum.addByte(b);
|
||||
checksum.add(b);
|
||||
}
|
||||
assertEquals(0x783, checksum.getChecksum());
|
||||
assertEquals(0x783, checksum.value());
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -16,9 +16,9 @@ public class MicrosparcKeyPerfect5Test {
|
||||
};
|
||||
Checksum checksum = new Checksum();
|
||||
for (int b : code) {
|
||||
checksum.addByte(b);
|
||||
checksum.add(b);
|
||||
}
|
||||
assertEquals(0xC397EF76, checksum.getChecksum());
|
||||
assertEquals(0xC397EF76, checksum.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -28,8 +28,8 @@ public class MicrosparcKeyPerfect5Test {
|
||||
};
|
||||
Checksum checksum = new Checksum();
|
||||
for (int b : code) {
|
||||
checksum.addByte(b);
|
||||
checksum.add(b);
|
||||
}
|
||||
assertEquals(0x9b714628, checksum.getChecksum());
|
||||
assertEquals(0x9b714628, checksum.value());
|
||||
}
|
||||
}
|
||||
+19
-8
@@ -1,25 +1,36 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class NibbleAppleCheckerTest {
|
||||
@Test
|
||||
public void testChecksum() {
|
||||
// Based on 6502 assembly run
|
||||
assertEquals(0x13, NibbleAppleChecker.checksum(0x0, 0x89)); // TEXT
|
||||
assertEquals(0x65, NibbleAppleChecker.checksum(0x13, 0x3a)); // :
|
||||
assertEquals(0x4b, NibbleAppleChecker.checksum(0x65, 0x97)); // HOME
|
||||
// Based on 6502 assembly run - checks step-by-step values
|
||||
NibbleAppleChecker.Checksum checksum = new NibbleAppleChecker.Checksum();
|
||||
checksum.add(0x89); // TEXT
|
||||
assertEquals(0x13, checksum.value());
|
||||
checksum.add(0x3a); // :
|
||||
assertEquals(0x65, checksum.value());
|
||||
checksum.add(0x97); // HOME
|
||||
assertEquals(0x4b, checksum.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCode() {
|
||||
NibbleAppleChecker.Checksum cksum = new NibbleAppleChecker.Checksum();
|
||||
Configuration config = Configuration.builder()
|
||||
.startAddress(0xb01)
|
||||
.sourceFile(new File("test.bas"))
|
||||
.build();
|
||||
NibbleAppleChecker checker = new NibbleAppleChecker(config);
|
||||
// 10 TEXT:HOME as a sample...
|
||||
byte[] code = { 0x09, 0x0b, 0x0a, (byte)0x89, 0x3a, (byte)0x97, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
cksum.compute(code, 0xb01);
|
||||
//assertEquals(0x2, cksum.getLength());
|
||||
assertEquals(0x4b, cksum.getChecksum());
|
||||
checker.addBytes(code);
|
||||
assertEquals(0x2, checker.getLength());
|
||||
assertEquals(0x4b, checker.getChecksumValue());
|
||||
}
|
||||
}
|
||||
+24
-11
@@ -1,7 +1,10 @@
|
||||
package org.applecommander.bastools.api.proofreaders;
|
||||
|
||||
import org.applecommander.bastools.api.Configuration;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
@@ -16,6 +19,12 @@ public class NibbleCheckitTest {
|
||||
assertEquals(0x91, performLineCalc("30 END"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuestionMark49() {
|
||||
assertEquals(0xf6, performLineCalc("110 PRINT \"HELLO WORLD?\""));
|
||||
assertEquals(0xe7, performLineCalc("10 PRINT \"?\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgramChecksum() {
|
||||
// Note: The value displayed is 1CB9, but the code prints low byte first...
|
||||
@@ -23,21 +32,25 @@ public class NibbleCheckitTest {
|
||||
}
|
||||
|
||||
protected int performLineCalc(String text) {
|
||||
int checksum = 0;
|
||||
for (char ch : text.toCharArray()) {
|
||||
if (ch != ' ') {
|
||||
checksum = NibbleCheckit.checkit(checksum, ch | 0x80);
|
||||
}
|
||||
}
|
||||
return ( (checksum & 0xff) - (checksum >> 8) ) & 0xff;
|
||||
Configuration config = Configuration.builder()
|
||||
.preserveNumbers(true)
|
||||
.sourceFile(new File("test.bas"))
|
||||
.build();
|
||||
NibbleCheckit proofreader = new NibbleCheckit(config);
|
||||
proofreader.addLine(text);
|
||||
return ( (proofreader.getLineChecksumValue() & 0xff) - (proofreader.getLineChecksumValue() >> 8) ) & 0xff;
|
||||
}
|
||||
|
||||
protected int performProgramCalc(int... lineNumbers) {
|
||||
int checksum = 0;
|
||||
Configuration config = Configuration.builder()
|
||||
.preserveNumbers(true)
|
||||
.sourceFile(new File("test.bas"))
|
||||
.build();
|
||||
NibbleCheckit proofreader = new NibbleCheckit(config);
|
||||
for (int lineNumber : lineNumbers) {
|
||||
checksum = NibbleCheckit.checkit(checksum, lineNumber & 0xff);
|
||||
checksum = NibbleCheckit.checkit(checksum, lineNumber >> 8);
|
||||
// We ignore the line, but line also computes the program checksum
|
||||
proofreader.addLine(Integer.toString(lineNumber));
|
||||
}
|
||||
return checksum;
|
||||
return proofreader.getTotalChecksumValue();
|
||||
}
|
||||
}
|
||||
+9
-8
@@ -4,18 +4,19 @@
|
||||
|
||||
Some summary notes and observations on the Apple II code checking tools.
|
||||
|
||||
| | Includes REM contents | Includes spaces | Control Chars? | Case-sensitive? | Operation | Grouping(s) | Size | Program Total |
|
||||
|--------------------------------|:----------------------|:----------------|:---------------|:----------------|:-------------|:--------------------------------|:------------------------------------|:-------------------------------------|
|
||||
| Compute! Automatic Proofreader | Yes | No | CTRL+D | Yes | Input Buffer | Line | 1 byte | No |
|
||||
| Nibble Checkit | No | In strings | In Strings | Yes | Input Buffer | Line, Program | 1 byte (line)<br/>2 bytes (program) | Yes, on line numbers |
|
||||
| Nibble Apple Checker | Yes | No | CTRL+D | Yes | Program | Program | 1 byte (2 bytes length) | Yes, checksum and length calculation |
|
||||
| MicroSPARC Key Perfect 2 | Yes | Yes | All | Yes | Program | Groups of 10 lines,<br/>Program | Max 3 bytes | Yes, byte count |
|
||||
| MicroSPARC Key Perfect 4 | Yes | No | CTRL+D | Yes | Program | Groups of 10 lines,<br/>Program | Max 3 bytes | Yes, byte count |
|
||||
| MicroSPARC Key Perfect 5 | No | No | CTRL+D | No | Program | Groups of 10 lines,<br/>Program | 4 bytes | Yes |
|
||||
| | Includes REM contents | Includes spaces | Control Chars? | Other? | Case-sensitive? | Operation | Grouping(s) | Checksum Size | Program Total |
|
||||
|--------------------------------|:----------------------|:----------------|:---------------|--------|:----------------|:-------------|:--------------------------------|:------------------------------------|:-------------------------------------|
|
||||
| Compute! Automatic Proofreader | Yes | No | CTRL+D | N/A | Yes | Input Buffer | Line | 1 byte | No |
|
||||
| Nibble Checkit | No | In strings | In Strings | "?" | Yes | Input Buffer | Line, Program | 1 byte (line)<br/>2 bytes (program) | Yes, on line numbers |
|
||||
| Nibble Apple Checker | Yes | No | CTRL+D | N/A | Yes | Program | Program | 1 byte (2 bytes length) | Yes, checksum and length calculation |
|
||||
| MicroSPARC Key Perfect 2 | Yes | Yes | All | N/A | Yes | Program | Groups of 10 lines,<br/>Program | Max 3 bytes | Yes, byte count |
|
||||
| MicroSPARC Key Perfect 4 | Yes | No | CTRL+D | N/A | Yes | Program | Groups of 10 lines,<br/>Program | Max 3 bytes | Yes, byte count |
|
||||
| MicroSPARC Key Perfect 5 | No | No | CTRL+D | N/A | No | Program | Groups of 10 lines,<br/>Program | 4 bytes | Yes |
|
||||
|
||||
* *Includes REM contents* - most checksum algorithms includes the REM as well as the contents of the REM statement; some only include the REM itself.
|
||||
* *Includes spaces* - indicates if whitespace is important.
|
||||
* *Control Chars?* - indicates if any control characters are included in the checksum.
|
||||
* *Other?* - Checkit replaces "?" with "PRINT" to standardize the shortcut for the `PRINT` statement. The catch is that it ignores quotes. So _any_ "?" is replaced with "PRINT" for the checksum algorithm.
|
||||
* *Case-sensitive?* - is "A" and "a" handled differently?
|
||||
* *Operation* - if "Input Buffer" is specified, the checksums are displayed after a line of code has been entered; otherwise, the program must be completed and saved before running checksum.
|
||||
* *Groupings* - what, if any, groupings apply.
|
||||
|
||||
@@ -17,15 +17,6 @@
|
||||
*/
|
||||
package org.applecommander.bastools.tools.bt;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
|
||||
import io.github.applecommander.applesingle.AppleSingle;
|
||||
import org.applecommander.bastools.api.*;
|
||||
import org.applecommander.bastools.api.model.Program;
|
||||
@@ -34,11 +25,21 @@ import org.applecommander.bastools.api.model.Token.Type;
|
||||
import org.applecommander.bastools.api.proofreaders.*;
|
||||
import org.applecommander.bastools.api.visitors.ByteVisitor;
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.ArgGroup;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Help.Visibility;
|
||||
import picocli.CommandLine.Option;
|
||||
import picocli.CommandLine.Parameters;
|
||||
import picocli.CommandLine.ArgGroup;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_FOOTER;
|
||||
|
||||
@@ -218,7 +219,7 @@ public class Main implements Callable<Integer> {
|
||||
program.accept(Visitors.variableReportVisitor());
|
||||
}
|
||||
if (proofReader.proofReaderFn != null) {
|
||||
program.accept(proofReader.proofReaderFn.apply(config));
|
||||
proofReader.proofReaderFn.accept(config, program);
|
||||
}
|
||||
|
||||
ByteVisitor byteVisitor = Visitors.byteVisitor(config);
|
||||
@@ -346,36 +347,54 @@ public class Main implements Callable<Integer> {
|
||||
}
|
||||
|
||||
public static class ProofReaderSelection {
|
||||
Function<Configuration,Visitor> proofReaderFn;
|
||||
BiConsumer<Configuration,Program> proofReaderFn;
|
||||
|
||||
@Option(names = "--checkit", description = "Apply Nibble Checkit (ca 1988) to code")
|
||||
public void selectNibbleCheckit(boolean flag) {
|
||||
this.proofReaderFn = NibbleCheckit::new;
|
||||
this.proofReaderFn = (c,p) -> {
|
||||
NibbleCheckit proofreader = new NibbleCheckit(c);
|
||||
proofreader.addProgram(p);
|
||||
};
|
||||
}
|
||||
|
||||
@Option(names = "--proofreader", description = "Apply Compute! Apple Automatic Proofreader (ca 1985) to code")
|
||||
public void selectComputeProofreader(boolean flag) {
|
||||
this.proofReaderFn = ComputeAutomaticProofreader::new;
|
||||
this.proofReaderFn = (c,p) -> {
|
||||
ComputeAutomaticProofreader proofreader = new ComputeAutomaticProofreader(c);
|
||||
proofreader.addProgram(p);
|
||||
};
|
||||
}
|
||||
|
||||
@Option(names = "--apple-checker", description = "Apply Nibble Apple Checker 3.0 (ca 1982) to code")
|
||||
public void selectNibbleAppleChecker(boolean flag) {
|
||||
this.proofReaderFn = NibbleAppleChecker::new;
|
||||
this.proofReaderFn = (c,p) -> {
|
||||
NibbleAppleChecker proofreader = new NibbleAppleChecker(c);
|
||||
proofreader.addProgram(p);
|
||||
};
|
||||
}
|
||||
|
||||
@Option(names = { "--key-perfect-2", "--kp2" }, description = "Apply MicroSPARC Key Perfect V2 (ca 1981) to code")
|
||||
public void selectKeyPerfectV2(boolean flag) {
|
||||
this.proofReaderFn = MicrosparcKeyPerfect2::new;
|
||||
this.proofReaderFn = (c,p) -> {
|
||||
MicrosparcKeyPerfect2 proofreader = new MicrosparcKeyPerfect2(c);
|
||||
proofreader.addProgram(p);
|
||||
};
|
||||
}
|
||||
|
||||
@Option(names = { "--key-perfect-4", "--kp4" }, description = "Apply MicroSPARC Key Perfect V4 (ca 1981) to code")
|
||||
public void selectKeyPerfectV4(boolean flag) {
|
||||
this.proofReaderFn = MicrosparcKeyPerfect4::new;
|
||||
this.proofReaderFn = (c,p) -> {
|
||||
MicrosparcKeyPerfect4 proofreader = new MicrosparcKeyPerfect4(c);
|
||||
proofreader.addProgram(p);
|
||||
};
|
||||
}
|
||||
|
||||
@Option(names = { "--key-perfect-5", "--kp5" }, description = "Apply MicroSPARC Key Perfect V5 (ca 1985) to code")
|
||||
public void selectKeyPerfectV5(boolean flag) {
|
||||
this.proofReaderFn = MicrosparcKeyPerfect5::new;
|
||||
this.proofReaderFn = (c,p) -> {
|
||||
MicrosparcKeyPerfect5 proofreader = new MicrosparcKeyPerfect5(c);
|
||||
proofreader.addProgram(p);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user