diff --git a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java index a81a13e..bf8c7a9 100644 --- a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java +++ b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java @@ -27,7 +27,8 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons private final Map> gotoLines = new TreeMap<> (); private final Map> gosubLines = new TreeMap<> (); - private final Map> constants = new TreeMap<> (); + private final Map> constantsInt = new TreeMap<> (); + private final Map> constantsFloat = new TreeMap<> (); private final Map> callLines = new TreeMap<> (); private final Map> symbolLines = new TreeMap<> (); @@ -79,8 +80,10 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons addXref (line.lineNumber, targetLine, gosubLines); for (int targetLine : subline.getGotoLines ()) addXref (line.lineNumber, targetLine, gotoLines); - for (int targetLine : subline.getConstants ()) - addXref (line.lineNumber, targetLine, constants); + for (int num : subline.getConstantsInt ()) + addNumberInt (line.lineNumber, num, constantsInt); + for (float num : subline.getConstantsFloat ()) + addNumberFloat (line.lineNumber, num, constantsFloat); if (subline.callTarget != null) addXref (line.lineNumber, subline.callTarget, callLines); } @@ -155,6 +158,32 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons lines.add (sourceLine); } + // ---------------------------------------------------------------------------------// + private void addNumberInt (int sourceLine, Integer num, Map> map) + // ---------------------------------------------------------------------------------// + { + List lines = map.get (num); + if (lines == null) + { + lines = new ArrayList<> (); + map.put (num, lines); + } + lines.add (sourceLine); + } + + // ---------------------------------------------------------------------------------// + private void addNumberFloat (int sourceLine, Float num, Map> map) + // ---------------------------------------------------------------------------------// + { + List lines = map.get (num); + if (lines == null) + { + lines = new ArrayList<> (); + map.put (num, lines); + } + lines.add (sourceLine); + } + // ---------------------------------------------------------------------------------// private void addXref (int sourceLine, String target, Map> map) // ---------------------------------------------------------------------------------// @@ -411,8 +440,11 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons if (basicPreferences.showFunctions && !functionLines.isEmpty ()) showSymbolsLeft (fullText, functionLines, "Fnction"); - if (basicPreferences.showConstants && !constants.isEmpty ()) - showSymbolsRight (fullText, constants, "Literal"); + if (basicPreferences.showConstants && !constantsInt.isEmpty ()) + showSymbolsRightInt (fullText, constantsInt, "Integer"); + + if (basicPreferences.showConstants && !constantsFloat.isEmpty ()) + showSymbolsRightFloat (fullText, constantsFloat, "Float"); if (basicPreferences.listStrings && stringsLine.size () > 0) { @@ -518,6 +550,28 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons appendLineNumbers (fullText, String.format (formatRight, symbol), map.get (symbol)); } + // ---------------------------------------------------------------------------------// + private void showSymbolsRightInt (StringBuilder fullText, + Map> map, String heading) + // ---------------------------------------------------------------------------------// + { + heading (fullText, formatRight, heading); + + for (int symbol : map.keySet ()) // right-justify integers + appendLineNumbers (fullText, String.format (formatRight, symbol), map.get (symbol)); + } + + // ---------------------------------------------------------------------------------// + private void showSymbolsRightFloat (StringBuilder fullText, + Map> map, String heading) + // ---------------------------------------------------------------------------------// + { + heading (fullText, formatRight, heading); + + for (float symbol : map.keySet ()) // right-justify integers + appendLineNumbers (fullText, String.format (formatRight, symbol), map.get (symbol)); + } + // ---------------------------------------------------------------------------------// private void appendLineNumbers (StringBuilder fullText, String symbol, List lineNumbers) diff --git a/src/com/bytezone/diskbrowser/applefile/SubLine.java b/src/com/bytezone/diskbrowser/applefile/SubLine.java index 4188f38..821f304 100644 --- a/src/com/bytezone/diskbrowser/applefile/SubLine.java +++ b/src/com/bytezone/diskbrowser/applefile/SubLine.java @@ -30,7 +30,8 @@ public class SubLine implements ApplesoftConstants private final List symbols = new ArrayList<> (); private final List functions = new ArrayList<> (); private final List arrays = new ArrayList<> (); - private final List constants = new ArrayList<> (); + private final List constantsInt = new ArrayList<> (); + private final List constantsFloat = new ArrayList<> (); // ---------------------------------------------------------------------------------// SubLine (SourceLine parent, int startPtr, int length) @@ -41,23 +42,28 @@ public class SubLine implements ApplesoftConstants this.length = length; this.buffer = parent.buffer; + int ptr = startPtr; byte firstByte = buffer[startPtr]; - if (Utility.isHighBitSet (firstByte)) + if (Utility.isHighBitSet (firstByte)) // BASIC command { doToken (firstByte); - if (is (TOKEN_REM) || is (TOKEN_DATA)) + if (is (TOKEN_REM) || is (TOKEN_DATA)) // no further processing return; - } - else if (Utility.isDigit (firstByte)) - { - doDigit (); - return; + ptr = startPtr + 1; } else - doAlpha (); + { + ptr = startPtr; + if (Utility.isDigit (firstByte)) // implied GOTO + { + addXref (getLineNumber (buffer, startPtr), gotoLines); + return; + } + else // variable assignment + recordEqualsPosition (); + } - int ptr = startPtr; String var = ""; boolean inQuote = false; @@ -65,9 +71,7 @@ public class SubLine implements ApplesoftConstants boolean inDefine = false; int max = startPtr + length - 1; - if (buffer[max] == 0) - --max; - if (buffer[max] == Utility.ASCII_COLON) + if (buffer[max] == 0 || buffer[max] == Utility.ASCII_COLON) --max; while (ptr <= max) @@ -94,16 +98,27 @@ public class SubLine implements ApplesoftConstants continue; } - if (inQuote && b != Utility.ASCII_QUOTE) // ignore strings - continue; - - if (Utility.isPossibleVariable (b)) // A-Z 0-9 $ % + if (inQuote) { - if (var.isEmpty () && buffer[ptr - 2] == TOKEN_MINUS && Utility.isDigit (b)) + if (b == Utility.ASCII_QUOTE) // ignore strings + inQuote = false; + continue; + } + + if (b == Utility.ASCII_QUOTE) + { + inQuote = true; + continue; + } + + if (Utility.isPossibleVariable (b) || b == Utility.ASCII_DOT) // A-Z 0-9 $ % . + { + if (var.isEmpty () && Utility.isDigit (b) && buffer[ptr - 2] == TOKEN_MINUS) var = "-"; var += (char) b; + // allow for PRINT A$B$ if ((b == Utility.ASCII_DOLLAR || b == Utility.ASCII_PERCENT) // var name end && buffer[ptr] != Utility.ASCII_LEFT_BRACKET) // not an array { @@ -122,30 +137,12 @@ public class SubLine implements ApplesoftConstants checkVar (var, b); var = ""; - - if (b == Utility.ASCII_QUOTE) - inQuote = !inQuote; } } checkVar (var, (byte) 0); } - // ---------------------------------------------------------------------------------// - private void doDigit () - // ---------------------------------------------------------------------------------// - { - int targetLine = getLineNumber (buffer, startPtr); - addXref (targetLine, gotoLines); - } - - // ---------------------------------------------------------------------------------// - private void doAlpha () - // ---------------------------------------------------------------------------------// - { - recordEqualsPosition (); - } - // ---------------------------------------------------------------------------------// private void checkFunction (String var, byte terminator) // ---------------------------------------------------------------------------------// @@ -165,12 +162,9 @@ public class SubLine implements ApplesoftConstants if (!Utility.isLetter ((byte) var.charAt (0))) { - if (is (TOKEN_GOTO) || is (TOKEN_GOSUB) || is (TOKEN_ON)) + if (is (TOKEN_GOTO) || is (TOKEN_GOSUB) || is (TOKEN_ON) || is (TOKEN_ONERR)) return; - - int varInt = Integer.parseInt (var); - if (!constants.contains (varInt)) - constants.add (varInt); + addNumber (var); return; } @@ -222,10 +216,17 @@ public class SubLine implements ApplesoftConstants } // ---------------------------------------------------------------------------------// - List getConstants () + List getConstantsInt () // ---------------------------------------------------------------------------------// { - return constants; + return constantsInt; + } + + // ---------------------------------------------------------------------------------// + List getConstantsFloat () + // ---------------------------------------------------------------------------------// + { + return constantsFloat; } // ---------------------------------------------------------------------------------// @@ -314,6 +315,50 @@ public class SubLine implements ApplesoftConstants functions.add (functionName); break; + + case TOKEN_DATA: + String[] chunks = new String (getBuffer ()).split (","); + for (String chunk : chunks) + { + b = (byte) chunk.charAt (0); + if (Utility.isDigit (b) || b == Utility.ASCII_MINUS || b == Utility.ASCII_DOT) + { + addNumber (chunk); + } + else if (Utility.isLetter (b)) + { + parent.parent.stringsText.add (chunk); + parent.parent.stringsLine.add (parent.lineNumber); + } + } + + break; + } + } + + // ---------------------------------------------------------------------------------// + private void addNumber (String var) + // ---------------------------------------------------------------------------------// + { + try + { + int decimalPos = var.indexOf ('.'); + if (decimalPos < 0) + { + int varInt = Integer.parseInt (var); + if (!constantsInt.contains (varInt)) + constantsInt.add (varInt); + } + else + { + float varFloat = Float.parseFloat (var); + if (!constantsFloat.contains (varFloat)) + constantsFloat.add (varFloat); + } + } + catch (NumberFormatException nfe) + { + System.out.printf ("NFE: %s%n", var); } } diff --git a/src/com/bytezone/diskbrowser/utilities/Utility.java b/src/com/bytezone/diskbrowser/utilities/Utility.java index 031ed32..f5d2c4f 100644 --- a/src/com/bytezone/diskbrowser/utilities/Utility.java +++ b/src/com/bytezone/diskbrowser/utilities/Utility.java @@ -24,6 +24,8 @@ public class Utility public static final byte ASCII_PERCENT = 0x25; public static final byte ASCII_LEFT_BRACKET = 0x28; public static final byte ASCII_RIGHT_BRACKET = 0x29; + public static final byte ASCII_MINUS = 0x2D; + public static final byte ASCII_DOT = 0x2E; public static final byte ASCII_COLON = 0x3A; public static final byte ASCII_SEMI_COLON = 0x3B; public static final byte ASCII_EQUALS = 0x3D; @@ -307,6 +309,13 @@ public class Utility || value == ASCII_PERCENT; } + // ---------------------------------------------------------------------------------// + public static boolean isPossibleNumber (byte value) + // ---------------------------------------------------------------------------------// + { + return isDigit (value) || value == ASCII_DOT; + } + // ---------------------------------------------------------------------------------// public static long getChecksumValue (File file) // ---------------------------------------------------------------------------------//