mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2025-02-06 19:30:01 +00:00
unique variable names
This commit is contained in:
parent
bda2e3358a
commit
a0d702be73
@ -20,8 +20,8 @@ public class ApplesoftBasicProgram extends BasicProgram
|
||||
|
||||
final Map<Integer, List<Integer>> gotoLines = new TreeMap<> ();
|
||||
final Map<Integer, List<Integer>> gosubLines = new TreeMap<> ();
|
||||
final Map<String, List<Integer>> symbolLines = new TreeMap<> ();
|
||||
final Map<String, List<String>> uniqueSymbols = new TreeMap<> ();
|
||||
private final Map<String, List<Integer>> symbolLines = new TreeMap<> ();
|
||||
private final Map<String, List<String>> uniqueSymbols = new TreeMap<> ();
|
||||
|
||||
final List<Integer> stringsLine = new ArrayList<> ();
|
||||
final List<String> 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<Integer> 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<Integer, List<Integer>> map)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
List<Integer> 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<String> 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<String> 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;
|
||||
}
|
||||
}
|
@ -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<Integer, List<Integer>> gotoLines;
|
||||
private final Map<Integer, List<Integer>> gosubLines;
|
||||
private final Map<String, List<Integer>> symbolLines;
|
||||
private final Map<String, List<String>> uniqueSymbols;
|
||||
private final List<Integer> gotoLines = new ArrayList<> ();
|
||||
private final List<Integer> gosubLines = new ArrayList<> ();
|
||||
private final List<String> 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<Integer> 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<String> getSymbols ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
return symbols;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
List<Integer> getGotoLines ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
return gotoLines;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
List<Integer> 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<String> 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<Integer> list)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
if (!list.contains (targetLine))
|
||||
list.add (targetLine);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private List<Integer> getLineNumbers (byte[] buffer, int ptr)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@ -259,24 +241,11 @@ public class SubLine
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private void addXref (int targetLine, Map<Integer, List<Integer>> map)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
List<Integer> 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 ();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user