diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | cxrefbas.c | 170 | ||||
-rw-r--r-- | linetab.c | 165 | ||||
-rw-r--r-- | linetab.h | 22 |
4 files changed, 189 insertions, 170 deletions
@@ -59,7 +59,7 @@ dumpbas: bas.o vxrefbas: bas.o -cxrefbas: bas.o bcdfp.o +cxrefbas: bas.o bcdfp.o linetab.o bas.o: bas.c bas.h @@ -7,175 +7,7 @@ #include "bas.h" #include "bcdfp.h" - -typedef struct { - unsigned short lineno; - unsigned short pos; - unsigned char cmd; -} lineref_t; - -lineref_t *linerefs[32769]; -int refcounts[32769]; -int lines_exist[32769]; -unsigned char last_cmd, on_op; -int last_cmd_pos; - -void add_lineref(unsigned short from, unsigned short pos) { - lineref_t *p; - int c; - unsigned short to; - - to = fp2int(program + pos); - if(to > 32767) return; - - p = linerefs[to]; - c = refcounts[to]; - - if(c) { - p = realloc(p, sizeof(lineref_t) * (c + 1)); - } else { - p = malloc(sizeof(lineref_t)); - } - - if(!p) die("Out of memory."); - - linerefs[to] = p; - linerefs[to][c].lineno = from; - linerefs[to][c].pos = pos; - linerefs[to][c].cmd = last_cmd; - c++; - refcounts[to] = c; -} - -/* makes sure a numeric constant isn't start of an expression. */ -int is_standalone_num(unsigned short pos) { - if(program[pos] != OP_NUMCONST) return 0; - switch(program[pos + 7]) { - case OP_EOS: - case OP_EOL: - case OP_COMMA: - return 1; - default: - return 0; - } -} - -CALLBACK(start_stmt) { - lines_exist[lineno] = 1; -} - -CALLBACK(got_cmd) { - last_cmd = tok; - last_cmd_pos = pos; - on_op = 0; -} - -void computed_msg(unsigned short lineno) { - static int last_lineno = -1; - char *cmd; - - /* avoid duplicate warnings */ - if(lineno == last_lineno) return; - last_lineno = lineno; - - switch(last_cmd) { - case CMD_GOTO: - cmd = "GOTO"; break; - case CMD_GO_TO: - cmd = "GO TO"; break; - case CMD_GOSUB: - cmd = "GOSUB"; break; - case CMD_RESTORE: - cmd = "RESTORE"; break; - case CMD_TRAP: - cmd = "TRAP"; break; - /* - case CMD_IF: - cmd = "IF/THEN"; break; - */ - case CMD_ON: - if(on_op == OP_GOSUB) - cmd = "ON/GOSUB"; - else - cmd = "ON/GOTO"; - break; - default: /* should never happen! */ - cmd = "???"; break; - } - - fprintf(stderr, "Computed %s at line %d\n", cmd, lineno); -} - -CALLBACK(got_var) { - switch(last_cmd) { - case CMD_GOTO: - case CMD_GO_TO: - case CMD_GOSUB: - case CMD_RESTORE: - case CMD_TRAP: - computed_msg(lineno); - break; - default: - break; - } -} - -CALLBACK(got_exp) { - unsigned char last_tok = program[pos - 1]; - int standalone; - - if(last_cmd == CMD_ON) { - if(tok == OP_GOTO || tok == OP_GOSUB) - on_op = tok; - } - - if(tok != OP_NUMCONST) return; - standalone = is_standalone_num(pos); - - switch(last_cmd) { - case CMD_GOTO: - case CMD_GO_TO: - case CMD_GOSUB: - case CMD_RESTORE: - case CMD_TRAP: - if((pos == last_cmd_pos + 1) && standalone) { - add_lineref(lineno, pos + 1); - } else { - computed_msg(lineno); - } - break; - case CMD_IF: - if(last_tok == OP_THEN) { - add_lineref(lineno, pos + 1); - } - break; - case CMD_ON: { - switch(last_tok) { - case OP_GOTO: - case OP_GOSUB: - case OP_COMMA: - if(standalone) - add_lineref(lineno, pos + 1); - else - computed_msg(lineno); - break; - default: - break; - } - } - break; - default: - break; - } -} - -void build_ref_table(void) { - on_start_stmt = start_stmt; - on_cmd_token = got_cmd; - on_exp_token = got_exp; - on_var_token = got_var; - walk_all_code(); -} +#include "linetab.h" void print_ref_table(void) { char c; diff --git a/linetab.c b/linetab.c new file mode 100644 index 0000000..c4fe392 --- /dev/null +++ b/linetab.c @@ -0,0 +1,165 @@ +#include "linetab.h" + +lineref_t *linerefs[32769]; +int refcounts[32769]; +int lines_exist[32769]; +unsigned char last_cmd, on_op; +int last_cmd_pos; + +void add_lineref(unsigned short from, unsigned short pos) { + lineref_t *p; + int c; + unsigned short to; + + to = fp2int(program + pos); + if(to > 32767) return; + + p = linerefs[to]; + c = refcounts[to]; + + if(c) { + p = realloc(p, sizeof(lineref_t) * (c + 1)); + } else { + p = malloc(sizeof(lineref_t)); + } + + if(!p) die("Out of memory."); + + linerefs[to] = p; + linerefs[to][c].lineno = from; + linerefs[to][c].pos = pos; + linerefs[to][c].cmd = last_cmd; + c++; + refcounts[to] = c; +} + +/* makes sure a numeric constant isn't start of an expression. */ +int is_standalone_num(unsigned short pos) { + if(program[pos] != OP_NUMCONST) return 0; + switch(program[pos + 7]) { + case OP_EOS: + case OP_EOL: + case OP_COMMA: + return 1; + default: + return 0; + } +} + +CALLBACK(start_stmt) { + lines_exist[lineno] = 1; +} + +CALLBACK(got_cmd) { + last_cmd = tok; + last_cmd_pos = pos; + on_op = 0; +} + +void computed_msg(unsigned short lineno) { + static int last_lineno = -1; + char *cmd; + + /* avoid duplicate warnings */ + if(lineno == last_lineno) return; + last_lineno = lineno; + + switch(last_cmd) { + case CMD_GOTO: + cmd = "GOTO"; break; + case CMD_GO_TO: + cmd = "GO TO"; break; + case CMD_GOSUB: + cmd = "GOSUB"; break; + case CMD_RESTORE: + cmd = "RESTORE"; break; + case CMD_TRAP: + cmd = "TRAP"; break; + /* + case CMD_IF: + cmd = "IF/THEN"; break; + */ + case CMD_ON: + if(on_op == OP_GOSUB) + cmd = "ON/GOSUB"; + else + cmd = "ON/GOTO"; + break; + default: /* should never happen! */ + cmd = "???"; break; + } + + fprintf(stderr, "Computed %s at line %d\n", cmd, lineno); +} + +CALLBACK(got_var) { + switch(last_cmd) { + case CMD_GOTO: + case CMD_GO_TO: + case CMD_GOSUB: + case CMD_RESTORE: + case CMD_TRAP: + computed_msg(lineno); + break; + default: + break; + } +} + +CALLBACK(got_exp) { + unsigned char last_tok = program[pos - 1]; + int standalone; + + if(last_cmd == CMD_ON) { + if(tok == OP_GOTO || tok == OP_GOSUB) + on_op = tok; + } + + if(tok != OP_NUMCONST) return; + standalone = is_standalone_num(pos); + + switch(last_cmd) { + case CMD_GOTO: + case CMD_GO_TO: + case CMD_GOSUB: + case CMD_RESTORE: + case CMD_TRAP: + if((pos == last_cmd_pos + 1) && standalone) { + add_lineref(lineno, pos + 1); + } else { + computed_msg(lineno); + } + break; + case CMD_IF: + if(last_tok == OP_THEN) { + add_lineref(lineno, pos + 1); + } + break; + case CMD_ON: { + switch(last_tok) { + case OP_GOTO: + case OP_GOSUB: + case OP_COMMA: + if(standalone) + add_lineref(lineno, pos + 1); + else + computed_msg(lineno); + break; + default: + break; + } + } + break; + default: + break; + } +} + +void build_ref_table(void) { + on_start_stmt = start_stmt; + on_cmd_token = got_cmd; + on_exp_token = got_exp; + on_var_token = got_var; + walk_all_code(); +} + diff --git a/linetab.h b/linetab.h new file mode 100644 index 0000000..c6aeb15 --- /dev/null +++ b/linetab.h @@ -0,0 +1,22 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <time.h> + +#include "bas.h" +#include "bcdfp.h" + +typedef struct { + unsigned short lineno; + unsigned short pos; + unsigned char cmd; +} lineref_t; + +extern lineref_t *linerefs[]; +extern int refcounts[]; +extern int lines_exist[]; + +extern void add_lineref(unsigned short from, unsigned short pos); +extern void build_ref_table(void); |