dmolony-DiskBrowser/src/com/bytezone/diskbrowser/applefile/SourceLine.java

99 lines
3.0 KiB
Java
Raw Normal View History

2020-12-30 03:06:50 +00:00
package com.bytezone.diskbrowser.applefile;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
2021-01-08 07:52:47 +00:00
public class SourceLine implements ApplesoftConstants
2020-12-30 03:06:50 +00:00
// -----------------------------------------------------------------------------------//
{
2020-12-31 09:50:53 +00:00
ApplesoftBasicProgram parent;
2021-01-18 00:06:17 +00:00
int addressNext;
2020-12-30 03:06:50 +00:00
int lineNumber;
int linePtr;
int length;
byte[] buffer;
2021-01-05 08:59:36 +00:00
List<SubLine> sublines = new ArrayList<> ();
2020-12-30 03:06:50 +00:00
// ---------------------------------------------------------------------------------//
SourceLine (ApplesoftBasicProgram parent, byte[] buffer, int ptr)
// ---------------------------------------------------------------------------------//
{
this.parent = parent;
this.buffer = buffer;
2021-01-05 08:59:36 +00:00
2020-12-30 03:06:50 +00:00
linePtr = ptr;
2021-01-18 00:06:17 +00:00
addressNext = Utility.unsignedShort (buffer, ptr);
2020-12-30 03:06:50 +00:00
lineNumber = Utility.unsignedShort (buffer, ptr + 2);
2021-02-20 09:49:48 +00:00
int startPtr = ptr += 4; // skip link to next line and lineNumber
boolean inString = false; // can toggle
boolean inRemark = false; // can only go false -> true
2020-12-30 03:06:50 +00:00
byte b;
while (ptr < buffer.length && (b = buffer[ptr++]) != 0)
{
2021-02-20 09:49:48 +00:00
if (inRemark) // cannot terminate a REM
2020-12-30 03:06:50 +00:00
continue;
if (inString)
{
if (b == Utility.ASCII_QUOTE) // terminate string
inString = false;
continue;
}
switch (b)
{
// break IF statements into two sublines (allows for easier line indenting)
case ApplesoftConstants.TOKEN_IF:
// skip to THEN or GOTO - if not found then it's an error
2021-01-08 02:03:12 +00:00
while (buffer[ptr] != TOKEN_THEN && buffer[ptr] != TOKEN_GOTO
&& buffer[ptr] != 0)
2020-12-30 03:06:50 +00:00
ptr++;
// keep THEN with the IF
2021-01-08 02:03:12 +00:00
if (buffer[ptr] == TOKEN_THEN)
2020-12-30 03:06:50 +00:00
++ptr;
2021-01-16 22:59:01 +00:00
// create subline from the condition (plus THEN if it exists)
2020-12-30 03:06:50 +00:00
sublines.add (new SubLine (this, startPtr, ptr - startPtr));
startPtr = ptr;
break;
// end of subline, so add it, advance startPtr and continue
case Utility.ASCII_COLON:
sublines.add (new SubLine (this, startPtr, ptr - startPtr));
startPtr = ptr;
break;
2021-01-08 02:03:12 +00:00
case TOKEN_REM:
2021-01-15 22:10:19 +00:00
if (ptr == startPtr + 1)
inRemark = true;
else
{ // REM appears mid-line (should follow a colon)
System.out.printf ("%5d %s%n", lineNumber, "mid-line REM token");
2021-01-18 00:06:17 +00:00
ptr--; // point back to this REM
sublines.add (new SubLine (this, startPtr, ptr - startPtr));
startPtr = ptr;
2020-12-30 03:06:50 +00:00
}
break;
case Utility.ASCII_QUOTE:
inString = true;
break;
}
}
2021-01-16 22:59:01 +00:00
length = ptr - linePtr;
2021-01-18 00:06:17 +00:00
// add whatever is left after the last colon
// if no colon was found this is the entire line
2021-01-16 22:59:01 +00:00
int bytesLeft = ptr - startPtr;
sublines.add (new SubLine (this, startPtr, bytesLeft));
2020-12-30 03:06:50 +00:00
}
}