From 53d33d9a44e3609b1abab902f4a45001690df142 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 18 Jul 2024 06:03:35 -0400 Subject: listbas: indentation seems complete for A+/Turbo/BXL/BXE. Still needs testing. --- listbas.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file 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); } -- cgit v1.2.3