aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--whichbas.c167
1 files changed, 74 insertions, 93 deletions
diff --git a/whichbas.c b/whichbas.c
index 20b2fdf..f4bd151 100644
--- a/whichbas.c
+++ b/whichbas.c
@@ -19,6 +19,7 @@ int bas_type = 0x0f; /* start out with all enabled */
int comma_count; /* count of regular commas (not string/array) in statement */
unsigned char last_cmd;
+unsigned char last_op_tok;
unsigned short last_cmd_pos;
int keep_going = 0; /* -k flag */
@@ -260,102 +261,82 @@ CALLBACK(handle_op) {
print_result();
}
- /* FIXME: I should have written this as a switch, not a bunch of if's */
-
- if(tok == 0x55) {
- /* DPEEK (function) TB, USING (infix, not a function) in BXL/BXE */
- if(nexttok == OP_FUNC_LPAR) {
- remove_type(BT_BXL_BXE);
- } else {
- remove_type(BT_TURBO);
- }
- }
-
- /* 56! & (logical AND) or % (XOR), both infix numeric ops; can't tell apart */
- /* 57! ! (logical OR) in both Turbo and BXL/BXE, can't tell apart */
-
- /* 58: INSTR (function) or & (infix numeric) */
- if(tok == 0x58) {
- if(nexttok == OP_FUNC_LPAR) {
- remove_type(BT_BXL_BXE);
- } else {
- remove_type(BT_TURBO);
- }
- }
-
- /* 59: INKEY$ (pseudo-function) in TB, string array separator semicolon in BXL/BXE */
- if(tok == 0x59) {
- if(nexttok == OP_NUMCONST || nexttok >= 0x80) {
- /* INKEY$ may not be followed by a numeric constant or a variable of any kind */
- remove_type(BT_TURBO);
- }
- }
-
- /* 5a: EXOR (infix num op) or BUMP( (pseudo-function, no OP_FUNC_LPAR) */
- /* 5d: DIV (infix num op) or RANDOM( (pseudo-func, 1 or 2 num args) */
- if(tok == 0x5a || tok == 0x5d) {
- /* XXX: incomplete */
- if(last_cmd_pos == pos - 1) {
- /* partial: if the last token was a command, this *can't* be infix.*/
- remove_type(BT_TURBO);
- } else if(program[pos - 1] >= 0x80) {
- /* partial: if the last token was a variable, this can't
- be a function (last token would have to have been a command
- or a regular operator). however, Turbo BASIC allows up to 256
- variables, this only catches the first 128. */
- remove_type(BT_BXL_BXE);
- }
- }
-
- /* 5b: HEX$ (func, takes 1 num arg) or FIND( (pseudo-func, 3 args */
- if(tok == 0x5b) {
- if(nexttok == OP_FUNC_LPAR) {
- remove_type(BT_BXL_BXE);
- } else {
- /* BXL/BXE token FIND( includes the (, there's no OP_FUNC_LPAR */
- remove_type(BT_TURBO);
- }
- }
-
- if(tok == 0x5c) {
- /* DEC (function, takes str) in TB, HEX$ (function, takes num) in BXL/BXE */
- if(nexttok2 == OP_STRCONST) {
- remove_type(BT_BXL_BXE);
- } else if(nexttok2 > 0x80 && (get_vartype(nexttok2) == TYPE_STRING)) {
- /* TODO: see if this test is actually valid! */
- remove_type(BT_BXL_BXE);
- }
- }
+ /* There are 25 extra operators in Turbo, and 20 of them are shared with
+ BXL/BXE. Of the 20, 6 of them are undecidable, and the rest are
+ covered here, which means 70% coverage of the shared ops.
+ Undecidables are:
+ 0x56 & (logical AND) or % (XOR), both infix numeric ops; can't tell apart
+ 0x57 ! (logical OR) in both Turbo and BXL/BXE, can't tell apart
+ 0x5e FRAC (num func, 1 arg) or DPEEK (num func, 1 arg), can't tell apart
+ 0x63 RND (func, 1 num arg) or ERR (func, 1 num arg), can't tell apart
+ 0x64 RAND (func, 1 num arg) or TAB (func, 1 num arg), can't tell apart
+ 0x65 TRUNC (func, 1 num arg) or PEN (func, 1 num arg), can't tell apart
+ */
- /* 5d: see 5a, above (same logic). */
- /* 5e! FRAC (num func, 1 arg) or DPEEK (num func, 1 arg), can't tell apart :( */
-
- /* 5f: TIME$ in TB, SYS (function) in BXL/BXE */
- /* 60: TIME in TB, VSTICK (function) in BXL/BXE */
- /* 61: MOD (infix op) in TB, HSTICK (function) in BXL/BXE */
- /* 62: EXEC (infix op, with ON) in TB, PMADR (function) in BXL/BXE */
- if(tok == 0x5f || tok == 0x60 || tok == 0x61 || tok == 0x62) {
- if(nexttok == OP_FUNC_LPAR) {
- remove_type(BT_TURBO);
- } else {
- remove_type(BT_BXL_BXE);
- }
+ switch(tok) {
+ case 0x55: /* DPEEK (function) TB, USING (infix, not a function) in BXL/BXE */
+ case 0x58: /* INSTR (function) or & (infix numeric) */
+ case 0x5b: /* HEX$ (func, takes 1 num arg) or FIND( (pseudo-func, 3 args */
+ if(nexttok == OP_FUNC_LPAR) {
+ remove_type(BT_BXL_BXE);
+ } else {
+ remove_type(BT_TURBO);
+ }
+ break;
+ case 0x59: /* INKEY$ (0 arg pseudo-func) in TB, string array separator semicolon in BXL/BXE */
+ if(nexttok == OP_NUMCONST || nexttok >= 0x80) {
+ /* INKEY$ may not be followed by a numeric constant or a variable of any kind */
+ remove_type(BT_TURBO);
+ }
+ break;
+ case 0x5a: /* EXOR (infix num op) or BUMP( (pseudo-function, no OP_FUNC_LPAR) */
+ case 0x5d: /* DIV (infix num op) or RANDOM( (pseudo-func, 1 or 2 num args) */
+ /* XXX: incomplete */
+ if(last_cmd_pos == pos - 1) {
+ /* partial: if the last token was a command, this *can't* be infix.*/
+ remove_type(BT_TURBO);
+ } else if(last_op_tok == OP_NUMCONST || last_op_tok == OP_HEXCONST || last_op_tok >= 0x80) {
+ /* partial: if the last token was a variable or a numeric, this can't
+ be a function (last token would have to have been a command
+ or a regular operator). however, Turbo BASIC allows up to 256
+ variables, this only catches the first 128. */
+ remove_type(BT_BXL_BXE);
+ }
+ break;
+ case 0x5c: /* DEC (function, takes str) in TB, HEX$ (function, takes num) in BXL/BXE */
+ if(nexttok2 == OP_STRCONST) {
+ remove_type(BT_BXL_BXE);
+ } else if(nexttok2 > 0x80 && (get_vartype(nexttok2) == TYPE_STRING)) {
+ /* TODO: see if this test is actually valid! */
+ remove_type(BT_BXL_BXE);
+ }
+ break;
+ case 0x5f: /* TIME$ in TB, SYS (function) in BXL/BXE */
+ case 0x60: /* TIME in TB, VSTICK (function) in BXL/BXE */
+ case 0x61: /* MOD (infix op) in TB, HSTICK (function) in BXL/BXE */
+ case 0x62: /* EXEC (infix op, with ON) in TB, PMADR (function) in BXL/BXE */
+ if(nexttok == OP_FUNC_LPAR) {
+ remove_type(BT_TURBO);
+ } else {
+ remove_type(BT_BXL_BXE);
+ }
+ break;
+ case 0x66: /* %0 in TB, LEFT$ (pseudo-func, takes string) in BXL/BXE */
+ case 0x67: /* %1 in TB, RIGHT$ (pseudo-func, takes string) in BXL/BXE */
+ case 0x68: /* %2 in TB, MID$ (pseudo-func, takes string) in BXL/BXE */
+ if(nexttok == OP_STRCONST || nexttok >= 0x80) {
+ /* %0 %1 %2 can't be followed by a string constant *or* a variable */
+ remove_type(BT_TURBO);
+ } else {
+ /* whereas LEFT$ RIGHT$ MID$ can't be followed by anything else */
+ remove_type(BT_BXL_BXE);
+ }
+ break;
+ default:
+ break;
}
- /* 63! RND (func, 1 num arg) or ERR (func, 1 num arg), can't tell apart */
- /* 64! RAND (func, 1 num arg) or TAB (func, 1 num arg), can't tell apart */
- /* 65! TRUNC (func, 1 num arg) or PEN (func, 1 num arg), can't tell apart */
-
- if(tok == 0x66 || tok == 0x67 || tok == 0x68) {
- /* either %0 %1 %2 (TB), or LEFT$ RIGHT$ MID$ (BXL/XE, *no* OP_FUNC_LPAR) */
- if(nexttok == OP_STRCONST || nexttok >= 0x80) {
- /* %0 %1 %2 can't be followed by a string constant *or* a variable */
- remove_type(BT_TURBO);
- } else {
- /* whereas LEFT$ RIGHT$ MID$ can't be followed by anything else */
- remove_type(BT_BXL_BXE);
- }
- }
+ last_op_tok = tok;
if(verbose) fprintf(stderr, " bas_type now %02x\n", bas_type);
}