aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--listbas.c80
1 files changed, 61 insertions, 19 deletions
diff --git a/listbas.c b/listbas.c
index f56b39b..328330b 100644
--- a/listbas.c
+++ b/listbas.c
@@ -479,8 +479,38 @@ const char *get_bxl_ext_name(unsigned char tok) {
}
}
+void clear_callbacks(void);
+void init_callbacks(void);
+
+CALLBACK(find_op_then) {
+ if(verbose)
+ fprintf(stderr, "find_op_then lineno %d, pos %04x, tok %02x\n", lineno, pos, tok);
+
+ if(tok == OP_THEN)
+ if_without_then = 0;
+}
+
+/* walk_code()'s API isn't really set up to be reentrant, but we
+ can do one level of sub-walk. */
+void find_then(int lineno, unsigned short pos) {
+ clear_callbacks();
+ on_exp_token = find_op_then;
+ walk_code(lineno, lineno);
+ init_callbacks();
+}
+
CALLBACK(print_lineno) {
+ unsigned char cmd_tok;
+
first_stmt = 1;
+
+ cmd_tok = program[pos + 4];
+ if_without_then = 0;
+ if((bas_type == B_APLUS && cmd_tok == 0x06) || (bas_type != B_APLUS && cmd_tok == CMD_IF)) {
+ if_without_then = 1; /* find_then() clears it, if there's a THEN */
+ find_then(lineno, pos);
+ }
+
if(skip_lineno) return;
if(color) color_on(color_lineno);
fprintf(outfh, "%d ", lineno);
@@ -539,7 +569,6 @@ void print_indent(void) {
}
void aplus_indent_line(const unsigned char tok) {
- if(if_without_then) indent_level++;
if(first_stmt) print_indent();
switch(tok) {
@@ -554,10 +583,13 @@ void aplus_indent_line(const unsigned char tok) {
return;
default: break;
}
+ if(if_without_then) {
+ indent_level++;
+ if_without_then = 0;
+ }
}
void turbo_indent_line(const unsigned char tok) {
- if(if_without_then) indent_level++;
switch(tok) {
case 0x40: /* ELSE */
if(first_stmt) {
@@ -586,15 +618,19 @@ void turbo_indent_line(const unsigned char tok) {
default: break;
}
if(first_stmt) print_indent();
+ if(if_without_then) {
+ indent_level++;
+ if_without_then = 0;
+ }
}
-/* FIXME: IF without THEN: the actual IF line is supposed to get indented,
- but only if there's *not* a THEN. no easy way to look ahead that I've
- thought of yet. */
/* Note: BXL's PROCEDURE/EXIT (from toolkit extensions) does
*not* get indented. */
void bxl_indent_line(unsigned char tok) {
- if(if_without_then) indent_level++;
+ if(if_without_then) {
+ indent_level++;
+ if_without_then = 0;
+ }
switch(tok) {
case CMD_FOR: /* FOR */
case 0x38: /* WHILE */
@@ -612,7 +648,6 @@ void bxl_indent_line(unsigned char tok) {
}
void bxe_indent_line(const unsigned char tok) {
- if(if_without_then) indent_level++;
switch(tok) {
case 0x3c: /* ELSE */
if(first_stmt) {
@@ -637,14 +672,15 @@ void bxe_indent_line(const unsigned char tok) {
default: break;
}
if(first_stmt) print_indent();
+ if(if_without_then) {
+ if_without_then = 0;
+ indent_level++;
+ }
}
void indent_line(const unsigned char tok) {
if(!indent) return;
- /*
- fprintf(stderr, "if_without_then == %d\n", if_without_then);
- */
switch(bas_type) {
case B_APLUS: aplus_indent_line(tok); return;
case B_TURBO: turbo_indent_line(tok); return;
@@ -663,13 +699,10 @@ CALLBACK(print_cmd) {
if(first_stmt)
first_stmt = 0;
- if_without_then = 0;
if(bas_type == B_APLUS) {
if(tok == 0x52) return;
- if(tok == 0x06) if_without_then = 1;
} else {
if(tok == CMD_ILET) return;
- if(tok == CMD_IF) if_without_then = 1;
}
if(color) color_on(color_cmd);
@@ -814,11 +847,6 @@ void print_varname(unsigned char varnum) {
CALLBACK(print_op) {
const char *name;
- if(tok == OP_THEN) {
- /* same token in A+ as in all the others, for once. */
- if_without_then = 0;
- }
-
switch(tok) {
case 0: /* Turbo variables numbered >= $80 */
if(bas_type == B_TURBO) {
@@ -898,7 +926,17 @@ CALLBACK(code_prot) {
exit(0);
}
-void list(void) {
+void clear_callbacks(void) {
+ on_start_line = 0;
+ on_cmd_token = 0;
+ on_exp_token = 0;
+ on_var_token = 0;
+ on_end_line = 0;
+ on_text = 0;
+ on_bad_line_length = 0;
+}
+
+void init_callbacks(void) {
on_start_line = print_lineno;
on_cmd_token = print_cmd;
on_exp_token = print_op;
@@ -906,6 +944,10 @@ void list(void) {
on_end_line = print_newline;
on_text = print_text;
on_bad_line_length = code_prot;
+}
+
+void list(void) {
+ init_callbacks();
walk_code(0, 32767 + immediate);
}