From fba189882a394e9d85975ad5ad43ea688f8481c8 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 25 Jun 2024 04:09:46 -0400 Subject: listbas: added (list basic programs, very barebones for now). --- listbas.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 listbas.c (limited to 'listbas.c') diff --git a/listbas.c b/listbas.c new file mode 100644 index 0000000..6469009 --- /dev/null +++ b/listbas.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "bas.h" +#include "bcdfp.h" +#include "tokens.h" + +int immediate = 0; + +void print_help(void) { + printf("Usage: %s [-v] [-i] \n", self); +} + +void parse_args(int argc, char **argv) { + int opt; + + while( (opt = getopt(argc, argv, "vi")) != -1) { + switch(opt) { + case 'v': verbose = 1; break; + case 'i': immediate = 1; break; + default: + print_help(); + exit(1); + } + } + + if(optind >= argc) + die("No input file given (use - for stdin)."); + else + open_input(argv[optind]); +} + +double bcd2double(const unsigned char *num) { + double result = 0, sign; + int exp, i; + + exp = *num; + if(!exp) { + return 0.0; + } + + sign = (exp & 0x80 ? -1.0 : 1.0); + exp &= 0x7f; + exp -= 0x40; + + for(i = 1; i < 6; i++) { + result *= 100.0; + result += bcd2int(num[i]); + } + + result *= pow(100, exp - 4); + result *= sign; + + return result; +} + +void print_number(unsigned int pos) { + printf("%G", bcd2double(program + pos)); +} + +void print_string(unsigned int pos, unsigned int len) { + putchar('"'); + while(len--) putchar(program[pos++]); + putchar('"'); +} + +CALLBACK(print_lineno) { + printf("%d ", lineno); +} + +CALLBACK(print_cmd) { + int bad; + const char *name; + + if(tok == CMD_ILET) return; + + if(tok > last_command) { + bad = 1; + } else if( (name = commands[tok]) ) { + bad = 0; + } else { + bad = 1; + } + + if(bad) + printf("(bad cmd token $%02x)", tok); + else + printf("%s ", name); +} + +CALLBACK(print_op) { + int bad; + const char *name; + + switch(tok) { + case OP_NUMCONST: + print_number(pos + 1); + return; + case OP_STRCONST: + print_string(pos + 2, program[pos + 1]); + return; + case OP_EOL: + return; + default: break; + } + + + if(tok > last_operator) { + bad = 1; + } else if( (name = operators[tok]) ) { + bad = 0; + } else { + bad = 1; + } + + if(bad) + printf("(bad op token $%02x)", tok); + else + printf("%s", name); +} + +CALLBACK(print_varname) { + int i, count; + unsigned char c; + + tok &= 0x7f; + for(i = vnstart, count = 0; count < tok; i++) { + if(program[i] & 0x80) count++; + } + while(1) { + c = program[i++]; + putchar(c & 0x7f); + if(c & 0x80) break; + } +} + +CALLBACK(print_text) { + while(program[pos] != 0x9b) putchar(program[pos++]); +} + +CALLBACK(print_newline) { + putchar('\n'); +} + +void list(void) { + on_start_line = print_lineno; + on_cmd_token = print_cmd; + on_exp_token = print_op; + on_var_token = print_varname; + on_end_line = print_newline; + on_text = print_text; + walk_code(0, 32767 + immediate); +} + +int main(int argc, char **argv) { + set_self(*argv); + parse_general_args(argc, argv, print_help); + parse_args(argc, argv); + + readfile(); + parse_header(); + + list(); + + return 0; +} -- cgit v1.2.3