From 9d1ce7321f27d47b76cba907127af777d6672188 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 13 Jun 2024 15:30:33 -0400 Subject: major surgery: callback API, port dumpbas to use callbacks, add vxrefbas. --- bas.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'bas.c') diff --git a/bas.c b/bas.c index e90d96c..fc5517b 100644 --- a/bas.c +++ b/bas.c @@ -155,6 +155,10 @@ void adjust_vntable_size(int oldsize, int newsize) { } } +unsigned char get_vartype(unsigned char tok) { + return program[vvstart + (tok & 0x7f) * 8] >> 6; +} + /* return true if the variable name table is OK */ int vntable_ok(void) { int vp, bad; @@ -249,10 +253,109 @@ void open_output(const char *name) { output_file = open_file(name, "wb"); } -extern void set_self(const char *argv0) { +void set_self(const char *argv0) { char *p; self = argv0; p = strrchr(self, '/'); if(p) self = p + 1; } + +/* callbacks */ +CALLBACK_PTR(on_start_line); +CALLBACK_PTR(on_bad_line_length); +CALLBACK_PTR(on_end_line); +CALLBACK_PTR(on_start_stmt); +CALLBACK_PTR(on_end_stmt); +CALLBACK_PTR(on_cmd_token); +CALLBACK_PTR(on_text); +CALLBACK_PTR(on_exp_token); +CALLBACK_PTR(on_var_token); +CALLBACK_PTR(on_string_const); +CALLBACK_PTR(on_num_const); + +#define CALL(x) if(x) (*x)(lineno, pos, program[pos], end) + +void walk_code(unsigned int startlineno, unsigned int endlineno) { + int linepos, nextpos, offset, soffset, lineno, pos, end, tok; + + linepos = codestart; + while(linepos < filelen) { /* loop over lines */ + lineno = getword(linepos); + offset = program[linepos + 2]; + nextpos = linepos + offset; + + end = nextpos; + pos = linepos; + + if(offset < 6) { + CALL(on_bad_line_length); + offset = program[linepos + 2]; /* on_bad_line_length fixed it (we hope) */ + if(offset < 6) + die("Program is code-protected; unprotect it first."); + } + + if(lineno < startlineno) { + linepos = nextpos; + continue; + } + + CALL(on_start_line); + + pos = linepos + 3; + while(pos < nextpos) { /* loop over statements within a line */ + soffset = program[pos]; + end = linepos + soffset; + CALL(on_start_stmt); + + while(pos < end) { /* loop over tokens within a statement */ + pos++; + CALL(on_cmd_token); + switch(program[pos]) { + case CMD_REM: + case CMD_DATA: + case CMD_ERROR: + pos++; + CALL(on_text); + pos = end; + break; + default: + pos++; + break; + } + + while(pos < end) { /* loop over operators */ + tok = program[pos]; + switch(tok) { + case OP_NUMCONST: + CALL(on_exp_token); + pos++; + CALL(on_num_const); + pos += 6; + break; + case OP_STRCONST: + CALL(on_exp_token); + pos++; + CALL(on_string_const); + pos += program[pos] + 1; + break; + default: + if(tok & 0x80) { + CALL(on_var_token); + } else { + CALL(on_exp_token); + } + pos++; + break; + } + } + CALL(on_end_stmt); + } + } + + CALL(on_end_line); + + if(lineno >= endlineno) break; + linepos = nextpos; + } +} -- cgit v1.2.3