diff options
Diffstat (limited to 'listamsb.c')
-rw-r--r-- | listamsb.c | 39 |
1 files changed, 32 insertions, 7 deletions
@@ -548,6 +548,8 @@ int crunch_line(void) { return codelen; } +/* only called during decrunching. + only handles one-byte tokens (only has to). */ void expand_token(unsigned char t, unsigned char *buf) { if(t < 0x80) { buf[0] = t; @@ -558,6 +560,10 @@ void expand_token(unsigned char t, unsigned char *buf) { strcpy((char *)buf, std_tokens[t - MIN_STD_TOK]); } +/* only called during decrunching. + the tokenizer in AMSB requires spaces to separate keywords + and variables/numbers. "IF A THEN 100" really needs the spaces + before and after the A, for example. */ int need_space_between(unsigned char t1, unsigned char t2) { unsigned char tok1[10], tok2[10]; unsigned char t1last, t2first; @@ -566,10 +572,24 @@ int need_space_between(unsigned char t1, unsigned char t2) { if(!t2) return 0; /* end of line */ if(t1 < 0x80 && t2 < 0x80) return 0; /* 2 ASCII chars */ + if(t1 > MAX_STD_TOK || t2 > MAX_STD_TOK) + die("invalid token in program, can't decrunch"); + expand_token(t1, tok1); expand_token(t2, tok2); t1last = tok1[strlen((char *)tok1) - 1]; /* "PRINT" => "T" */ - t2first = tok2[0]; /* "PRINT" => "P" */ + t2first = tok2[0]; /* "PRINT" => "P" */ + + /* space not really required between OPEN/PRINT/CLOSE and #, + but put one there for neatness. */ + if(t2first == '#') return 1; + + /* space not really required between a closing quote and + a keyword, but put it in for neatness. examples: + OPEN #1,"D:X" INPUT + IF A$="FOO" THEN 10 + these look weird with the space before INPUT or THEN. */ + if(t1last == '|' && isalnum(t2first)) return 1; return(isalnum(t1last) && isalnum(t2first)); } @@ -631,12 +651,14 @@ int decrunch_line(void) { return codelen; } +/* despite the name, this handles both crunching and decrunching */ void crunch_program(void) { int newproglen = 0, linelen = 0; + float percent; fputc(0x00, outfile); /* signature (0 = not locked) */ fputc(0x00, outfile); /* length LSB (fill in later) */ - fputc(0x00, outfile); /* length MSB */ + fputc(0x00, outfile); /* length MSB " " */ while((linelen = decrunch ? decrunch_line() : crunch_line()) != -1) newproglen += linelen; @@ -645,19 +667,22 @@ void crunch_program(void) { fputc(0x00, outfile); fputc(0x00, outfile); - if(fseek(outfile, 1L, SEEK_SET) < 0) - os_err("fseek() failed"); - + /* fill in length in header */ + if(fseek(outfile, 1L, SEEK_SET) < 0) os_err("fseek() failed"); newproglen += 2; /* account for trailing $00 $00 */ fputc(newproglen & 0xff, outfile); fputc((newproglen >> 8) & 0xff, outfile); fclose(outfile); + /* show the user how the size changed */ newproglen += 3; - verbose(1, "crunched %d byte program to %d bytes (%.1f%% savings)", + percent = 100.0 * (1.0 - (float)newproglen / (float)proglen); + verbose(1, "%scrunched %d byte program to %d bytes (%.1f%% %s)", + decrunch ? "de" : "", bytes_read, newproglen, - 100.0 * (1.0 - (float)newproglen / (float)proglen)); + percent < 0 ? -percent : percent, + percent < 0 ? "larger" : "smaller"); } void print_help(void) { |