From a0d702be7371e90250fc91454a5b26e825fa82e3 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Sun, 3 Jan 2021 13:04:24 +1000 Subject: [PATCH] unique variable names --- .../applefile/ApplesoftBasicProgram.java | 122 +++++++++++--- .../diskbrowser/applefile/SubLine.java | 153 +++++++----------- 2 files changed, 161 insertions(+), 114 deletions(-) diff --git a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java index fbfac52..75212c4 100644 --- a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java +++ b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java @@ -20,8 +20,8 @@ public class ApplesoftBasicProgram extends BasicProgram final Map> gotoLines = new TreeMap<> (); final Map> gosubLines = new TreeMap<> (); - final Map> symbolLines = new TreeMap<> (); - final Map> uniqueSymbols = new TreeMap<> (); + private final Map> symbolLines = new TreeMap<> (); + private final Map> uniqueSymbols = new TreeMap<> (); final List stringsLine = new ArrayList<> (); final List stringsText = new ArrayList<> (); @@ -46,10 +46,54 @@ public class ApplesoftBasicProgram extends BasicProgram sourceLines.add (line); ptr += line.length; currentAddress = nextAddress; + + for (SubLine subline : line.sublines) + { + for (String symbol : subline.getSymbols ()) + checkVar (symbol, line.lineNumber); + for (int targetLine : subline.getGosubLines ()) + addXref (line.lineNumber, targetLine, gosubLines); + for (int targetLine : subline.getGotoLines ()) + addXref (line.lineNumber, targetLine, gotoLines); + } } endPtr = ptr; } + // ---------------------------------------------------------------------------------// + void checkVar (String var, int lineNumber) + // ---------------------------------------------------------------------------------// + { + List lines = symbolLines.get (var); + if (lines == null) + { + lines = new ArrayList<> (); + symbolLines.put (var, lines); + } + if (lines.size () == 0) + lines.add (lineNumber); + else + { + int lastLine = lines.get (lines.size () - 1); + if (lastLine != lineNumber) + lines.add (lineNumber); + } + checkUniqueName (var); + } + + // ---------------------------------------------------------------------------------// + private void addXref (int sourceLine, int targetLine, Map> map) + // ---------------------------------------------------------------------------------// + { + List lines = map.get (targetLine); + if (lines == null) + { + lines = new ArrayList<> (); + map.put (targetLine, lines); + } + lines.add (sourceLine); + } + // ---------------------------------------------------------------------------------// @Override public String getText () @@ -67,9 +111,10 @@ public class ApplesoftBasicProgram extends BasicProgram StringBuilder fullText = new StringBuilder (); Stack loopVariables = new Stack<> (); + if (basicPreferences.showHeader) addHeader (fullText); - int alignPos = 0; + int alignEqualsPos = 0; StringBuilder text; int baseOffset = basicPreferences.showTargets ? 12 : 8; @@ -136,7 +181,7 @@ public class ApplesoftBasicProgram extends BasicProgram // Align assign statements if required if (basicPreferences.alignAssign) - alignPos = alignEqualsPosition (subline, alignPos); + alignEqualsPos = alignEqualsPosition (subline, alignEqualsPos); int column = indent * indentSize + baseOffset; while (text.length () < column) @@ -144,8 +189,7 @@ public class ApplesoftBasicProgram extends BasicProgram } // Add the current text, then reset it - int pos = subline.is (ApplesoftConstants.TOKEN_REM) ? 0 : alignPos; - String lineText = subline.getAlignedText (pos); + String lineText = subline.getAlignedText (alignEqualsPos); if (subline.is (ApplesoftConstants.TOKEN_REM) && basicPreferences.deleteExtraRemSpace) @@ -155,7 +199,7 @@ public class ApplesoftBasicProgram extends BasicProgram && basicPreferences.deleteExtraDataSpace) lineText = lineText.replaceFirst ("DATA ", "DATA "); - // Check for a wrappable REM statement + // Check for a wrappable REM/DATA/DIM statement // (see SEA BATTLE on DISK283.DSK) int inset = Math.max (text.length (), getIndent (fullText)) + 1; if (subline.is (ApplesoftConstants.TOKEN_REM) @@ -196,11 +240,15 @@ public class ApplesoftBasicProgram extends BasicProgram ifIndent = ++indent; else if (subline.is (ApplesoftConstants.TOKEN_FOR)) { - loopVariables.push (subline.forVariable); - ++indent; + String latestLoopVar = loopVariables.size () > 0 ? loopVariables.peek () : ""; + if (!subline.forVariable.equals (latestLoopVar)) // don't add repeated loop + { + loopVariables.push (subline.forVariable); + ++indent; + } } else if (basicPreferences.blankAfterReturn - && subline.is (ApplesoftConstants.TOKEN_RETURN)) + && subline.is (ApplesoftConstants.TOKEN_RETURN) && subline.isFirst ()) insertBlankLine = true; } @@ -212,7 +260,7 @@ public class ApplesoftBasicProgram extends BasicProgram // Reset alignment value if we just left an IF - the indentation will be different now if (ifIndent > 0) - alignPos = 0; + alignEqualsPos = 0; } int ptr = endPtr + 2; @@ -238,7 +286,7 @@ public class ApplesoftBasicProgram extends BasicProgram int longestVarName = getLongestVarName (); String format = - longestVarName > 6 ? "%-" + longestVarName + "s %s%n" : "%-6s %s%n"; + longestVarName > 6 ? "%-" + longestVarName + "s %s%n" : "%-6s %s%n"; for (String symbol : symbolLines.keySet ()) { @@ -569,7 +617,7 @@ public class ApplesoftBasicProgram extends BasicProgram private int alignEqualsPosition (SubLine subline, int currentAlignPosition) // ---------------------------------------------------------------------------------// { - if (subline.assignEqualPos > 0) // does the line have an equals sign? + if (subline.equalsPosition > 0) // does the line have an equals sign? { if (currentAlignPosition == 0) currentAlignPosition = findHighest (subline); // examine following sublines @@ -585,7 +633,7 @@ public class ApplesoftBasicProgram extends BasicProgram // ---------------------------------------------------------------------------------// { boolean started = false; - int highestAssign = startSubline.assignEqualPos; + int highestAssign = startSubline.equalsPosition; fast: for (SourceLine line : sourceLines) { @@ -596,13 +644,13 @@ public class ApplesoftBasicProgram extends BasicProgram { // Stop when we come to a line without an equals sign (except for non-split REMs). // Lines that start with a REM always break. - if (subline.assignEqualPos == 0 + if (subline.equalsPosition == 0 // && (splitRem || !subline.is (TOKEN_REM) || subline.isFirst ())) && (basicPreferences.splitRem || !subline.isJoinableRem ())) break fast; // of champions - if (subline.assignEqualPos > highestAssign) - highestAssign = subline.assignEqualPos; + if (subline.equalsPosition > highestAssign) + highestAssign = subline.equalsPosition; } else if (subline == startSubline) started = true; @@ -717,11 +765,39 @@ public class ApplesoftBasicProgram extends BasicProgram private boolean sameVariable (String v1, String v2) // ---------------------------------------------------------------------------------// { - if (v1.equals (v2)) - return true; - if (v1.length () >= 2 && v2.length () >= 2 && v1.charAt (0) == v2.charAt (0) - && v1.charAt (1) == v2.charAt (1)) - return true; - return false; + return getUniqueName (v1).equals (getUniqueName (v2)); + } + + // ---------------------------------------------------------------------------------// + private void checkUniqueName (String symbol) + // ---------------------------------------------------------------------------------// + { + String uniqueName = getUniqueName (symbol); + + List usage = uniqueSymbols.get (uniqueName); + if (usage == null) + { + usage = new ArrayList<> (); + uniqueSymbols.put (uniqueName, usage); + } + + if (!usage.contains (symbol)) + usage.add (symbol); + } + + // ---------------------------------------------------------------------------------// + private String getUniqueName (String symbol) + // ---------------------------------------------------------------------------------// + { + int ptr = symbol.length () - 1; + if (symbol.charAt (ptr) == Utility.ASCII_LEFT_BRACKET) // array + ptr--; + if (symbol.charAt (ptr) == Utility.ASCII_DOLLAR // string + || symbol.charAt (ptr) == Utility.ASCII_PERCENT) // integer + ptr--; + + String unique = + (ptr <= 1) ? symbol : symbol.substring (0, 2) + symbol.substring (ptr + 1); + return unique; } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/applefile/SubLine.java b/src/com/bytezone/diskbrowser/applefile/SubLine.java index 402d7fb..0512729 100644 --- a/src/com/bytezone/diskbrowser/applefile/SubLine.java +++ b/src/com/bytezone/diskbrowser/applefile/SubLine.java @@ -2,7 +2,6 @@ package com.bytezone.diskbrowser.applefile; import java.util.ArrayList; import java.util.List; -import java.util.Map; import com.bytezone.diskbrowser.utilities.Utility; @@ -16,13 +15,12 @@ public class SubLine int length; String[] nextVariables; String forVariable = ""; - int assignEqualPos; // used for aligning the equals sign + int equalsPosition; // used for aligning the equals sign byte[] buffer; - private final Map> gotoLines; - private final Map> gosubLines; - private final Map> symbolLines; - private final Map> uniqueSymbols; + private final List gotoLines = new ArrayList<> (); + private final List gosubLines = new ArrayList<> (); + private final List symbols = new ArrayList<> (); // ---------------------------------------------------------------------------------// SubLine (SourceLine parent, int startPtr, int length) @@ -33,13 +31,9 @@ public class SubLine this.length = length; program = parent.parent; - this.gotoLines = program.gotoLines; - this.gosubLines = program.gosubLines; - this.symbolLines = program.symbolLines; - this.uniqueSymbols = program.uniqueSymbols; this.buffer = parent.buffer; - byte firstByte = parent.buffer[startPtr]; + byte firstByte = buffer[startPtr]; if (Utility.isHighBitSet (firstByte)) doToken (firstByte); @@ -58,7 +52,7 @@ public class SubLine while (length-- > 0) { - byte b = parent.buffer[ptr++]; + byte b = buffer[ptr++]; if (inQuote && b != Utility.ASCII_QUOTE) continue; @@ -78,33 +72,38 @@ public class SubLine } // ---------------------------------------------------------------------------------// - private void checkVar (String var, byte term) + private void checkVar (String var, byte terminator) // ---------------------------------------------------------------------------------// { if (var.length () == 0) return; - if (term == Utility.ASCII_LEFT_BRACKET) + if (terminator == Utility.ASCII_LEFT_BRACKET) var += "("; - if (Utility.isLetter ((byte) var.charAt (0))) - { - List lines = symbolLines.get (var); - if (lines == null) - { - lines = new ArrayList<> (); - symbolLines.put (var, lines); - } - if (lines.size () == 0) - lines.add (parent.lineNumber); - else - { - int lastLine = lines.get (lines.size () - 1); - if (lastLine != parent.lineNumber) - lines.add (parent.lineNumber); - } - checkUniqueName (var); - } + if (Utility.isLetter ((byte) var.charAt (0)) && !symbols.contains (var)) + symbols.add (var); + } + + // ---------------------------------------------------------------------------------// + List getSymbols () + // ---------------------------------------------------------------------------------// + { + return symbols; + } + + // ---------------------------------------------------------------------------------// + List getGotoLines () + // ---------------------------------------------------------------------------------// + { + return gotoLines; + } + + // ---------------------------------------------------------------------------------// + List getGosubLines () + // ---------------------------------------------------------------------------------// + { + return gosubLines; } // ---------------------------------------------------------------------------------// @@ -115,8 +114,8 @@ public class SubLine { case ApplesoftConstants.TOKEN_FOR: int p = startPtr + 1; - while (parent.buffer[p] != ApplesoftConstants.TOKEN_EQUALS) - forVariable += (char) parent.buffer[p++]; + while (buffer[p] != ApplesoftConstants.TOKEN_EQUALS) + forVariable += (char) buffer[p++]; break; case ApplesoftConstants.TOKEN_NEXT: @@ -124,7 +123,7 @@ public class SubLine nextVariables = new String[0]; else { - String varList = new String (parent.buffer, startPtr + 1, length - 2); + String varList = new String (buffer, startPtr + 1, length - 2); nextVariables = varList.split (","); } break; @@ -134,31 +133,31 @@ public class SubLine break; case ApplesoftConstants.TOKEN_GOTO: - int targetLine = getLineNumber (parent.buffer, startPtr + 1); + int targetLine = getLineNumber (buffer, startPtr + 1); addXref (targetLine, gotoLines); break; case ApplesoftConstants.TOKEN_GOSUB: - targetLine = getLineNumber (parent.buffer, startPtr + 1); + targetLine = getLineNumber (buffer, startPtr + 1); addXref (targetLine, gosubLines); break; case ApplesoftConstants.TOKEN_ON: p = startPtr + 1; int max = startPtr + length - 1; - while (p < max && parent.buffer[p] != ApplesoftConstants.TOKEN_GOTO - && parent.buffer[p] != ApplesoftConstants.TOKEN_GOSUB) + while (p < max && buffer[p] != ApplesoftConstants.TOKEN_GOTO + && buffer[p] != ApplesoftConstants.TOKEN_GOSUB) p++; - switch (parent.buffer[p++]) + switch (buffer[p++]) { case ApplesoftConstants.TOKEN_GOSUB: - for (int destLine : getLineNumbers (parent.buffer, p)) + for (int destLine : getLineNumbers (buffer, p)) addXref (destLine, gosubLines); break; case ApplesoftConstants.TOKEN_GOTO: - for (int destLine : getLineNumbers (parent.buffer, p)) + for (int destLine : getLineNumbers (buffer, p)) addXref (destLine, gotoLines); break; @@ -170,43 +169,18 @@ public class SubLine case ApplesoftConstants.TOKEN_ONERR: if (buffer[startPtr + 1] == ApplesoftConstants.TOKEN_GOTO) { - targetLine = getLineNumber (parent.buffer, startPtr + 2); + targetLine = getLineNumber (buffer, startPtr + 2); addXref (targetLine, gotoLines); } break; } } - // ---------------------------------------------------------------------------------// - private void checkUniqueName (String symbol) - // ---------------------------------------------------------------------------------// - { - int ptr = symbol.length () - 1; - if (symbol.charAt (ptr) == Utility.ASCII_LEFT_BRACKET) // array - ptr--; - if (symbol.charAt (ptr) == Utility.ASCII_DOLLAR - || symbol.charAt (ptr) == Utility.ASCII_PERCENT) - ptr--; - - String unique = - (ptr <= 1) ? symbol : symbol.substring (0, 2) + symbol.substring (ptr + 1); - - List usage = uniqueSymbols.get (unique); - if (usage == null) - { - usage = new ArrayList<> (); - uniqueSymbols.put (unique, usage); - } - - if (!usage.contains (symbol)) - usage.add (symbol); - } - // ---------------------------------------------------------------------------------// private void doDigit () // ---------------------------------------------------------------------------------// { - int targetLine = getLineNumber (parent.buffer, startPtr); + int targetLine = getLineNumber (buffer, startPtr); addXref (targetLine, gotoLines); } @@ -217,6 +191,14 @@ public class SubLine recordEqualsPosition (); } + // ---------------------------------------------------------------------------------// + private void addXref (int targetLine, List list) + // ---------------------------------------------------------------------------------// + { + if (!list.contains (targetLine)) + list.add (targetLine); + } + // ---------------------------------------------------------------------------------// private List getLineNumbers (byte[] buffer, int ptr) // ---------------------------------------------------------------------------------// @@ -259,24 +241,11 @@ public class SubLine return lineNumber; } - // ---------------------------------------------------------------------------------// - private void addXref (int targetLine, Map> map) - // ---------------------------------------------------------------------------------// - { - List lines = map.get (targetLine); - if (lines == null) - { - lines = new ArrayList<> (); - map.put (targetLine, lines); - } - lines.add (parent.lineNumber); - } - // ---------------------------------------------------------------------------------// boolean isImpliedGoto () // ---------------------------------------------------------------------------------// { - byte b = parent.buffer[startPtr]; + byte b = buffer[startPtr]; if (Utility.isHighBitSet (b)) return false; return (Utility.isDigit (b)); @@ -289,10 +258,10 @@ public class SubLine { int p = startPtr + 1; int max = startPtr + length; - while (parent.buffer[p] != ApplesoftConstants.TOKEN_EQUALS && p < max) + while (buffer[p] != ApplesoftConstants.TOKEN_EQUALS && p < max) p++; if (buffer[p] == ApplesoftConstants.TOKEN_EQUALS) - assignEqualPos = toString ().indexOf ('='); // use expanded line + equalsPosition = toString ().indexOf ('='); // use expanded line } // ---------------------------------------------------------------------------------// @@ -313,7 +282,7 @@ public class SubLine boolean is (byte token) // ---------------------------------------------------------------------------------// { - return parent.buffer[startPtr] == token; + return buffer[startPtr] == token; } // ---------------------------------------------------------------------------------// @@ -325,7 +294,7 @@ public class SubLine while (ptr < max) { - if (parent.buffer[ptr++] == token) + if (buffer[ptr++] == token) return true; } return false; @@ -403,13 +372,15 @@ public class SubLine } // ---------------------------------------------------------------------------------// - public String getAlignedText (int alignPosition) + public String getAlignedText (int alignEqualsPos) // ---------------------------------------------------------------------------------// { - StringBuilder line = toStringBuilder (); + StringBuilder line = toStringBuilder (); // get line - while (alignPosition-- > assignEqualPos) - line.insert (assignEqualPos, ' '); + // insert spaces before '=' until it lines up with the other assignment lines + if (!is (ApplesoftConstants.TOKEN_REM)) + while (alignEqualsPos-- > equalsPosition) + line.insert (equalsPosition, ' '); return line.toString (); }