aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-06-15 16:22:25 -0400
committerB. Watson <urchlay@slackware.uk>2024-06-15 16:22:25 -0400
commit5b4d161d5c82105f92006aa9cebbcd72b9383178 (patch)
treefb8f8e430e61a828a2327cedfb2b69894fce0c7e
parented4f8e0e2e20cb16f40844895f79b69da96caf35 (diff)
downloadbw-atari8-tools-5b4d161d5c82105f92006aa9cebbcd72b9383178.tar.gz
vxrefbas: WIP.
-rw-r--r--bas.h51
-rw-r--r--vxrefbas.165
-rw-r--r--vxrefbas.c100
-rw-r--r--vxrefbas.rst33
4 files changed, 100 insertions, 149 deletions
diff --git a/bas.h b/bas.h
index ce67309..c88d035 100644
--- a/bas.h
+++ b/bas.h
@@ -33,30 +33,33 @@
/* BASIC tokens. Not a full set. BASIC uses 2 sets of tokens, one
for commands and the other for operators (which is to say, everything
*not* a command). */
-#define CMD_GOTO 0x0a
-#define CMD_GO_TO 0x0b
-#define CMD_GOSUB 0x0c
-#define CMD_TRAP 0x0d
-#define CMD_LIST 0x04
-#define CMD_RESTORE 0x23
-#define CMD_REM 0x00
-#define CMD_DATA 0x01
-#define CMD_ERROR 0x37
-#define CMD_FOR 0x08
-#define CMD_NEXT 0x09
-#define CMD_LET 0x06
-#define CMD_ILET 0x36
-#define CMD_DIM 0x14
-#define CMD_READ 0x22
-#define CMD_INPUT 0x02
-#define OP_GOTO 0x17
-#define OP_GOSUB 0x18
-#define OP_THEN 0x1b
-#define OP_COMMA 0x12
-#define OP_EOS 0x14
-#define OP_EOL 0x16
-#define OP_NUMCONST 0x0e
-#define OP_STRCONST 0x0f
+#define CMD_GOTO 0x0a
+#define CMD_GO_TO 0x0b
+#define CMD_GOSUB 0x0c
+#define CMD_TRAP 0x0d
+#define CMD_LIST 0x04
+#define CMD_RESTORE 0x23
+#define CMD_REM 0x00
+#define CMD_DATA 0x01
+#define CMD_ERROR 0x37
+#define CMD_FOR 0x08
+#define CMD_NEXT 0x09
+#define CMD_LET 0x06
+#define CMD_ILET 0x36
+#define CMD_DIM 0x14
+#define CMD_READ 0x22
+#define CMD_INPUT 0x02
+#define CMD_GET 0x29
+#define OP_GOTO 0x17
+#define OP_GOSUB 0x18
+#define OP_THEN 0x1b
+#define OP_COMMA 0x12
+#define OP_ARR_COMMA 0x3c
+#define OP_EOS 0x14
+#define OP_EOL 0x16
+#define OP_NUMCONST 0x0e
+#define OP_STRCONST 0x0f
+#define OP_HASH 0x1c
/* variable types, bits 6-7 of byte 0 of each vvtable entry. */
#define TYPE_SCALAR 0
diff --git a/vxrefbas.1 b/vxrefbas.1
index 17780d9..e139d59 100644
--- a/vxrefbas.1
+++ b/vxrefbas.1
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
-.TH "VXREFBAS" 1 "2024-06-13" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "VXREFBAS" 1 "2024-06-15" "0.2.1" "Urchlay's Atari 8-bit Tools"
.SH NAME
vxrefbas \- Variable cross-reference for tokenized Atari 8-bit BASIC files
.SH SYNOPSIS
@@ -68,6 +68,9 @@ Variable was \fIINPUT\fP on this line.
.TP
.B \fBR\fP
Variable was \fIREAD\fP on this line.
+.TP
+.B \fBG\fP
+Variable was read with \fIGET\fP on this line.
.UNINDENT
.SH OPTIONS
.SS General Options
@@ -83,66 +86,6 @@ Print version number and exit.
Verbose operation. When displaying a number in verbose mode, it will
be prefixed with \fI$\fP if it\(aqs in hex, or no prefix for decimal.
.UNINDENT
-.SH BUGS
-.sp
-This program:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-10 FILE=1:INPUT #FILE,LINE$
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Results in this:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-FILE/80: 10=AI (1)
-LINE$/81: 10=AI (1)
- 2 variables, 0 unreferenced.
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-\fBvxrefbas\fP thinks \fIFILE\fP is being \fIINPUT\fP on line 10, which it isn\(aqt.
-The output for \fIFILE\fP should read \fI10=A (1)\fP\&.
-.sp
-Also, this program:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-10 DIM A(1):A(0)=10
-20 DIM B(A(0))
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-Results in this:
-.INDENT 0.0
-.INDENT 3.5
-.sp
-.nf
-.ft C
-A(/80: 10=AD 20=D (2)
-B(/81: 20=D (1)
- 2 variables, 0 unreferenced.
-.ft P
-.fi
-.UNINDENT
-.UNINDENT
-.sp
-\fBvxrefbas\fP thinks \fIA(\fP is being DIMensioned on line 20, which it isn\(aqt. The
-output for \fIA(\fP should read \fI10=AD 20 (2)\fP\&.
.SH EXIT STATUS
.sp
0 for success, 1 for failure.
diff --git a/vxrefbas.c b/vxrefbas.c
index acc830c..e05e2d7 100644
--- a/vxrefbas.c
+++ b/vxrefbas.c
@@ -7,8 +7,9 @@
#include "bas.h"
-int target_var, lastline, assign, is_for, is_next, is_dim, is_read, is_input;
-int in_dim, in_read, in_input;
+int A, F, N, D, I, R, G;
+int target_var, lastline;
+unsigned char last_cmd = 0, last_op = 0;
int refcounts[128];
void print_help(void) {
@@ -17,57 +18,87 @@ void print_help(void) {
}
CALLBACK(new_line) {
- assign = is_for = is_next = is_dim = is_read = is_input = 0;
+ A = F = N = D = I = R = G = 0;
}
CALLBACK(end_line) {
if(lastline != lineno) return;
- printf("%d", lineno);
- if(assign || is_for || is_next || is_dim || is_read || is_input) {
+ if(A || F || N || D || I || R || G) {
putchar('=');
- if(assign) putchar('A');
- if(is_for) putchar('F');
- if(is_next) putchar('N');
- if(is_dim) putchar('D');
- if(is_read) putchar('R');
- if(is_input) putchar('I');
+ if(A) putchar('A');
+ if(F) putchar('F');
+ if(N) putchar('N');
+ if(D) putchar('D');
+ if(I) putchar('I');
+ if(R) putchar('R');
+ if(G) putchar('G');
}
+
putchar(' ');
}
CALLBACK(new_command) {
- switch(tok) {
+ last_cmd = tok;
+}
+
+CALLBACK(end_stmt) {
+ last_cmd = last_op = 0;
+}
+
+CALLBACK(handle_var) {
+ unsigned char last_tok;
+
+ if(tok != (target_var | 0x80)) return;
+
+ if(lastline != lineno) {
+ printf("%d", lineno);
+ refcounts[target_var]++;
+ }
+
+ lastline = lineno;
+ last_tok = program[pos - 1];
+
+ switch(last_cmd) {
case CMD_LET:
case CMD_ILET:
- assign = 1; break;
+ if(last_tok == last_cmd) A = 1;
+ break;
case CMD_FOR:
- is_for = 1; break;
+ if(last_tok == last_cmd) F = 1;
+ break;
case CMD_NEXT:
- is_next = 1; break;
+ if(last_tok == last_cmd) N = 1;
+ break;
case CMD_DIM:
- in_dim = 1; break;
- case CMD_READ:
- in_read= 1; break;
+ if(last_tok == last_cmd || last_tok == OP_COMMA) D = 1;
+ break;
case CMD_INPUT:
- in_input= 1; break;
- default: break;
+ if(last_tok == last_cmd || last_tok == OP_COMMA) I = 1;
+ break;
+ case CMD_READ:
+ if(last_tok == last_cmd || last_tok == OP_COMMA) R = 1;
+ break;
+ case CMD_GET:
+ if(last_tok == OP_COMMA) G = 1;
+ break;
}
}
-CALLBACK(end_stmt) {
- in_dim = in_read = in_input = 0;
-}
+void parse_args(int argc, char **argv) {
+ int opt;
-CALLBACK(handle_var) {
- if(in_dim) is_dim = 1;
- if(in_input) is_input = 1;
- if(in_read) is_read = 1;
- if(lastline == lineno) return;
- if((tok & 0x7f) == target_var) {
- refcounts[target_var]++;
- lastline = lineno;
+ while( (opt = getopt(argc, argv, "v")) != -1) {
+ switch(opt) {
+ case 'v': verbose = 1; break;
+ default: print_help(); exit(1);
+ }
}
+
+ if(optind >= argc)
+ die("No input file given (use - for stdin).");
+ else
+ open_input(argv[optind]);
}
int main(int argc, char **argv) {
@@ -77,8 +108,7 @@ int main(int argc, char **argv) {
set_self(*argv);
parse_general_args(argc, argv, print_help);
-
- open_input(argv[1]);
+ parse_args(argc, argv);
readfile();
parse_header();
@@ -92,6 +122,7 @@ int main(int argc, char **argv) {
target_var = 0;
vnpos = vnstart;
+ /* walk the variable value table */
for(pos = vvstart; pos < codestart; pos += 8) {
/* print the variable name */
while(program[vnpos] < 0x80)
@@ -110,7 +141,8 @@ int main(int argc, char **argv) {
}
putchar('\n');
- if(target_var++ == 128) break;
+ /* ignore any ERROR-4 vars, since they don't have tokens anyway. */
+ if(++target_var == 128) break;
}
printf(" %d variables, %d unreferenced.\n", target_var, unref);
diff --git a/vxrefbas.rst b/vxrefbas.rst
index 510d016..2e18186 100644
--- a/vxrefbas.rst
+++ b/vxrefbas.rst
@@ -49,6 +49,9 @@ which show the type of variable access.
**R**
Variable was *READ* on this line.
+**G**
+ Variable was read with *GET* on this line.
+
OPTIONS
=======
@@ -64,36 +67,6 @@ General Options
Verbose operation. When displaying a number in verbose mode, it will
be prefixed with *$* if it's in hex, or no prefix for decimal.
-BUGS
-====
-
-This program::
-
- 10 FILE=1:INPUT #FILE,LINE$
-
-Results in this::
-
- FILE/80: 10=AI (1)
- LINE$/81: 10=AI (1)
- 2 variables, 0 unreferenced.
-
-**vxrefbas** thinks *FILE* is being *INPUT* on line 10, which it isn't.
-The output for *FILE* should read *10=A (1)*.
-
-Also, this program::
-
- 10 DIM A(1):A(0)=10
- 20 DIM B(A(0))
-
-Results in this::
-
- A(/80: 10=AD 20=D (2)
- B(/81: 20=D (1)
- 2 variables, 0 unreferenced.
-
-**vxrefbas** thinks *A(* is being DIMensioned on line 20, which it isn't. The
-output for *A(* should read *10=AD 20 (2)*.
-
EXIT STATUS
===========