diff --git a/asoft_basic-utils/asoft_compact.c b/asoft_basic-utils/asoft_compact.c index 2d29a62d..06341070 100644 --- a/asoft_basic-utils/asoft_compact.c +++ b/asoft_basic-utils/asoft_compact.c @@ -1,29 +1,29 @@ /* asoft_compact */ -/* make applesoft code as compact as possible */ -/* + Renumber lines to be as short as possible */ -/* + Remove extraneous "LET" commands */ -/* + Transform "THEN GOTO" to "THEN" */ -/* + Make variables as short as possible */ -/* + Remove REM statements */ -/* + Combine lines right up to 255 char limit */ +/* make applesoft code as compact as possible */ +/* + Renumber lines to be as short as possible */ +/* + Remove extraneous "LET" commands */ +/* + Transform "THEN GOTO" to "THEN" */ +/* + Make variables as short as possible */ +/* + Remove REM statements */ +/* + Combine lines right up to 255 char limit */ /* Example */ /* demo.bas = 22,219 bytes */ /* tokenized = 17,407 bytes */ -/* compacted = */ +/* compacted = */ #include -#include /* strlen() */ +#include /* strlen() */ #include #include "version.h" -#define LOW(_x) ((_x)&0xff) +#define LOW(_x) ((_x)&0xff) #define HIGH(_x) (((_x)>>8)&0xff) - /* Starting at 0x80 */ -char applesoft_tokens[][8]={ + /* Starting at 0x80 */ +char applesoft_tokens[][8]={ /* 80 */ "END","FOR","NEXT","DATA","INPUT","DEL","DIM","READ", /* 88 */ "GR","TEXT","PR #","IN #","CALL","PLOT","HLIN","VLIN", /* 90 */ "HGR2","HGR","HCOLOR=","HPLOT","DRAW","XDRAW","HTAB","HOME", @@ -42,78 +42,78 @@ char applesoft_tokens[][8]={ /* F8 */ "","","","","","(","(","(" }; -#define TOKEN_END 0 -#define TOKEN_FOR 1 -#define TOKEN_NEXT 2 -#define TOKEN_DATA 3 -#define TOKEN_INPUT 4 -#define TOKEN_DEL 5 -#define TOKEN_DIM 6 -#define TOKEN_READ 7 -#define TOKEN_GR 8 -#define TOKEN_TEXT 9 -#define TOKEN_PR 10 -#define TOKEN_IN 11 -#define TOKEN_CALL 12 -#define TOKEN_PLOT 13 -#define TOKEN_HLIN 14 -#define TOKEN_VLIN 15 -#define TOKEN_HGR2 16 -#define TOKEN_HGR 17 -#define TOKEN_HCOLOR 18 -#define TOKEN_HPLOT 19 -#define TOKEN_DRAW 20 -#define TOKEN_XDRAW 21 -#define TOKEN_HTAB 22 -#define TOKEN_HOME 23 -#define TOKEN_ROT 24 -#define TOKEN_SCALE 25 -#define TOKEN_SHLOAD 26 -#define TOKEN_TRACE 27 -#define TOKEN_NOTRACE 28 -#define TOKEN_NORMAL 29 -#define TOKEN_INVERSE 30 -#define TOKEN_FLASH 31 -#define TOKEN_COLOR 32 -#define TOKEN_POP 33 -#define TOKEN_VTAB 34 -#define TOKEN_HIMEM 35 -#define TOKEN_LOMEM 36 -#define TOKEN_ONERR 37 -#define TOKEN_RESUME 38 -#define TOKEN_RECALL 39 -#define TOKEN_STORE 40 -#define TOKEN_SPEED 41 -#define TOKEN_LET 42 -#define TOKEN_GOTO 43 -#define TOKEN_RUN 44 -#define TOKEN_IF 45 -#define TOKEN_RESTORE 46 -#define TOKEN_AMP 47 -#define TOKEN_GOSUB 48 -#define TOKEN_RETURN 49 -#define TOKEN_REM 50 -#define TOKEN_STOP 51 -#define TOKEN_ON 52 -#define TOKEN_WAIT 53 -#define TOKEN_LOAD 54 -#define TOKEN_SAVE 55 -#define TOKEN_DEFFN 56 -#define TOKEN_POKE 57 -#define TOKEN_PRINT 58 -#define TOKEN_CONT 59 -#define TOKEN_LIST 60 -#define TOKEN_CLEAR 61 -#define TOKEN_GET 62 -#define TOKEN_NEW 63 -#define TOKEN_TAB 64 -#define TOKEN_TO 65 -#define TOKEN_FN 66 -#define TOKEN_SPC 67 -#define TOKEN_THEN 68 -#define TOKEN_AT 69 -#define TOKEN_NO 70 -#define TOKEN_STEP 71 +#define TOKEN_END 0 +#define TOKEN_FOR 1 +#define TOKEN_NEXT 2 +#define TOKEN_DATA 3 +#define TOKEN_INPUT 4 +#define TOKEN_DEL 5 +#define TOKEN_DIM 6 +#define TOKEN_READ 7 +#define TOKEN_GR 8 +#define TOKEN_TEXT 9 +#define TOKEN_PR 10 +#define TOKEN_IN 11 +#define TOKEN_CALL 12 +#define TOKEN_PLOT 13 +#define TOKEN_HLIN 14 +#define TOKEN_VLIN 15 +#define TOKEN_HGR2 16 +#define TOKEN_HGR 17 +#define TOKEN_HCOLOR 18 +#define TOKEN_HPLOT 19 +#define TOKEN_DRAW 20 +#define TOKEN_XDRAW 21 +#define TOKEN_HTAB 22 +#define TOKEN_HOME 23 +#define TOKEN_ROT 24 +#define TOKEN_SCALE 25 +#define TOKEN_SHLOAD 26 +#define TOKEN_TRACE 27 +#define TOKEN_NOTRACE 28 +#define TOKEN_NORMAL 29 +#define TOKEN_INVERSE 30 +#define TOKEN_FLASH 31 +#define TOKEN_COLOR 32 +#define TOKEN_POP 33 +#define TOKEN_VTAB 34 +#define TOKEN_HIMEM 35 +#define TOKEN_LOMEM 36 +#define TOKEN_ONERR 37 +#define TOKEN_RESUME 38 +#define TOKEN_RECALL 39 +#define TOKEN_STORE 40 +#define TOKEN_SPEED 41 +#define TOKEN_LET 42 +#define TOKEN_GOTO 43 +#define TOKEN_RUN 44 +#define TOKEN_IF 45 +#define TOKEN_RESTORE 46 +#define TOKEN_AMP 47 +#define TOKEN_GOSUB 48 +#define TOKEN_RETURN 49 +#define TOKEN_REM 50 +#define TOKEN_STOP 51 +#define TOKEN_ON 52 +#define TOKEN_WAIT 53 +#define TOKEN_LOAD 54 +#define TOKEN_SAVE 55 +#define TOKEN_DEFFN 56 +#define TOKEN_POKE 57 +#define TOKEN_PRINT 58 +#define TOKEN_CONT 59 +#define TOKEN_LIST 60 +#define TOKEN_CLEAR 61 +#define TOKEN_GET 62 +#define TOKEN_NEW 63 +#define TOKEN_TAB 64 +#define TOKEN_TO 65 +#define TOKEN_FN 66 +#define TOKEN_SPC 67 +#define TOKEN_THEN 68 +#define TOKEN_AT 69 +#define TOKEN_NO 70 +#define TOKEN_STEP 71 #if 0 /* C8 */ "+","-","*","/","^","AND","OR",">", /* D0 */ "=","<","SGN","INT","ABS","USR","FRE","SCRN (", @@ -123,284 +123,268 @@ char applesoft_tokens[][8]={ #endif static void color_red(void) { - fprintf(stderr,"%c[1;31;40m",27); + fprintf(stderr,"%c[1;31;40m",27); } static void color_green(void) { - fprintf(stderr,"%c[1;32;40m",27); + fprintf(stderr,"%c[1;32;40m",27); } static void color_cyan(void) { - fprintf(stderr,"%c[1;36;40m",27); + fprintf(stderr,"%c[1;36;40m",27); } static void color_yellow(void) { - fprintf(stderr,"%c[1;33;40m",27); + fprintf(stderr,"%c[1;33;40m",27); } static void color_normal(void) { - fprintf(stderr,"%c[0m",27); + fprintf(stderr,"%c[0m",27); } -static int linenums[65536]; /* lazy */ +static int linenums[65536]; /* lazy */ static int output[65536]; static void print_int(int value, int *offset) { - unsigned char buffer[16]; - int pointer=15; - int r,q; + unsigned char buffer[16]; + int pointer=15; + int r,q; - q=value; + q=value; - while(1) { - r=q%10; - q/=10; + while(1) { + r=q%10; + q/=10; - buffer[pointer]=r+'0'; + buffer[pointer]=r+'0'; - if (q==0) break; + if (q==0) break; - pointer--; - } + pointer--; + } - while(pointer<16) { - output[*offset]=buffer[pointer]; - pointer++; - (*offset)++; - } + while(pointer<16) { + output[*offset]=buffer[pointer]; + pointer++; + (*offset)++; + } } int main(int argc, char **argv) { - - int ch1; - int size1,size2; - int line1,line2; - int link1,link2,link; - int debug=1; - int token,last_token=0; - int line_no=0; - int i; - FILE *fff; - int offset,link_offset,line_offset; + int ch1; + int size1,size2; + int line1,line2; + int link1,link2,link; + int debug=1; + int token,last_token=0; + int line_no=0; + int i; + FILE *fff; - if (argc<2) { - fprintf(stderr,"Usage: %s FILENAME -1 -2 -3 -4\n",argv[0]); - exit(1); - } + int offset,link_offset; - fff=fopen(argv[1],"r"); - if (fff==NULL) { - fprintf(stderr,"Error opening %s\n",argv[1]); - exit(1); - } + if (argc<2) { + fprintf(stderr,"Usage: %s FILENAME -1 -2 -3 -4\n",argv[0]); + exit(1); + } - - /* read size, first two bytes */ - size1=fgetc(fff); - size2=fgetc(fff); - - if (debug) fprintf(stderr,"File size: %x %x\n",size1,size2); + fff=fopen(argv[1],"r"); + if (fff==NULL) { + fprintf(stderr,"Error opening %s\n",argv[1]); + exit(1); + } - while(!feof(fff)) { - - /* link points to the next line */ - link1=fgetc(fff); - link2=fgetc(fff); - link=(link1<<8)|link2; - /* link==0 indicates EOF */ - if (link==0) goto the_end; - - /* line number is little endian 16-bit value */ - line1=fgetc(fff); - line2=fgetc(fff); - if (feof(fff)) goto the_end; + /* read size, first two bytes */ + size1=fgetc(fff); + size2=fgetc(fff); - color_red(); - fprintf(stderr,"%4d ",((line2)<<8)+line1); - color_normal(); + if (debug) fprintf(stderr,"File size: %x %x\n",size1,size2); - /* repeat until EOL character (0) */ - while(1) { + while(!feof(fff)) { - ch1=fgetc(fff); -after_read: - if (ch1==0) break; + /* link points to the next line */ + link1=fgetc(fff); + link2=fgetc(fff); + link=(link1<<8)|link2; + /* link==0 indicates EOF */ + if (link==0) goto the_end; - /* if > 0x80 it's a token */ - if (ch1>=0x80) { - color_green(); - fprintf(stderr,"%s",applesoft_tokens[ch1-0x80]); - color_normal(); - last_token=ch1&0x7f; - } + /* line number is little endian 16-bit value */ + line1=fgetc(fff); + line2=fgetc(fff); + if (feof(fff)) goto the_end; - - /* otherwise it is an ascii char */ - else { - if (ch1<0x20) { - color_cyan(); - fprintf(stderr,"%d",ch1); - color_normal(); - } - - if ((ch1>='0') && (ch1<='9')) { - if ((last_token==TOKEN_GOTO) || - (last_token==TOKEN_GOSUB) || - (last_token==TOKEN_THEN)) { - - line_no=ch1-'0'; - - while(1) { - ch1=fgetc(fff); - if ((ch1<'0') || (ch1>'9')) break; - line_no*=10; - line_no+=(ch1-'0'); - } - - color_yellow(); - fprintf(stderr,"%d",line_no); + color_red(); + fprintf(stderr,"%4d ",((line2)<<8)+line1); color_normal(); - linenums[line_no]++; - goto after_read; - } - } - - - fputc(ch1,stderr); - } - - } - fprintf(stderr,"\n"); - } - the_end:; - - fprintf(stderr,"Used Line Numbers:\n"); - for(i=0;i<65536;i++) { - if(linenums[i]) fprintf(stderr,"\t%d\t%d\n",i,linenums[i]); - } - - rewind(fff); - - /*********************/ - /* Create new output */ - /*********************/ - - /* skip size bytes */ - offset=2; - size1=fgetc(fff); - size2=fgetc(fff); - - - while(!feof(fff)) { - - link_offset=offset; - - link1=fgetc(fff); - link2=fgetc(fff); - link=(link1<<8)|link2; - - output[offset]=link1; - output[offset+1]=link2; - - /* link==0 indicates end */ - if (link==0) break; - offset+=2; - - - /* line number is little endian 16-bit value */ - - line_offset=offset; - - line1=fgetc(fff); - line2=fgetc(fff); - - output[offset]=line1; - output[offset+1]=line2; - - offset+=2; - - if (feof(fff)) break; - - /* repeat until EOL character (0) */ - while(1) { - - ch1=fgetc(fff); -after_read2: - if (ch1==0) break; - - /* if > 0x80 it's a token */ - if (ch1>=0x80) { - - token=ch1&0x7f; - - if (token==TOKEN_LET) { - /* Skip superfluous LET */ - } - else if ((token==TOKEN_GOTO) && (last_token==TOKEN_THEN)) { - /* Skip superfluous GOTO if THEN GOTO */ - - } - else { - output[offset]=ch1; - offset++; - } - last_token=token; - } - - - /* otherwise it is an ascii char */ - else { - - if ((ch1>='0') && (ch1<='9')) { - if ((last_token==TOKEN_GOTO) || - (last_token==TOKEN_GOSUB) || - (last_token==TOKEN_THEN)) { - - line_no=ch1-'0'; + /* repeat until EOL character (0) */ while(1) { - ch1=fgetc(fff); - if ((ch1<'0') || (ch1>'9')) break; - line_no*=10; - line_no+=(ch1-'0'); + + ch1=fgetc(fff); +after_read: + if (ch1==0) break; + /* if > 0x80 it's a token */ + if (ch1>=0x80) { + color_green(); + fprintf(stderr,"%s",applesoft_tokens[ch1-0x80]); + color_normal(); + last_token=ch1&0x7f; + } + /* otherwise it is an ascii char */ + else { + if (ch1<0x20) { + color_cyan(); + fprintf(stderr,"%d",ch1); + color_normal(); + } + + if ((ch1>='0') && (ch1<='9')) { + if ((last_token==TOKEN_GOTO) || + (last_token==TOKEN_GOSUB) || + (last_token==TOKEN_THEN)) { + + line_no=ch1-'0'; + + while(1) { + ch1=fgetc(fff); + if ((ch1<'0') || (ch1>'9')) break; + line_no*=10; + line_no+=(ch1-'0'); + } + color_yellow(); + fprintf(stderr,"%d",line_no); + color_normal(); + linenums[line_no]++; + goto after_read; + } + } + fputc(ch1,stderr); + } } + fprintf(stderr,"\n"); + } +the_end:; - print_int(line_no,&offset); - - goto after_read2; - } - } + fprintf(stderr,"Used Line Numbers:\n"); + for(i=0;i<65536;i++) { + if(linenums[i]) fprintf(stderr,"\t%d\t%d\n",i,linenums[i]); + } + rewind(fff); - output[offset]=ch1; - offset++; - } - - } - output[offset]=0; - offset++; + /*********************/ + /* Create new output */ + /*********************/ - output[link_offset]=LOW(offset+0x7ff); - output[link_offset+1]=HIGH(offset+0x7ff); + /* skip size bytes */ + offset=2; + size1=fgetc(fff); + size2=fgetc(fff); - } + while(!feof(fff)) { - /* write out our program */ + link_offset=offset; - /* set last link field to $00 $00 which indicates EOF */ - output[offset]='\0'; - output[offset+1]='\0'; - offset+=2; - - /* Set filesize */ - /* -1 to match observed values */ - output[0]=LOW(offset-1); - output[1]=HIGH(offset-1); - /* output our file */ - for(i=0;i 0x80 it's a token */ + if (ch1>=0x80) { + token=ch1&0x7f; + + if (token==TOKEN_LET) { + /* Skip superfluous LET */ + } + else if ((token==TOKEN_GOTO) && (last_token==TOKEN_THEN)) { + /* Skip superfluous GOTO if THEN GOTO */ + } + else { + output[offset]=ch1; + offset++; + } + last_token=token; + } + /* otherwise it is an ascii char */ + else { + + if ((ch1>='0') && (ch1<='9')) { + if ((last_token==TOKEN_GOTO) || + (last_token==TOKEN_GOSUB) || + (last_token==TOKEN_THEN)) { + + line_no=ch1-'0'; + + while(1) { + ch1=fgetc(fff); + if ((ch1<'0') || (ch1>'9')) break; + line_no*=10; + line_no+=(ch1-'0'); + } + print_int(line_no,&offset); + + goto after_read2; + } + } + + output[offset]=ch1; + offset++; + } + + } + output[offset]=0; + offset++; + + output[link_offset]=LOW(offset+0x7ff); + output[link_offset+1]=HIGH(offset+0x7ff); + + } + + /* write out our program */ + + /* set last link field to $00 $00 which indicates EOF */ + output[offset]='\0'; + output[offset+1]='\0'; + offset+=2; + + /* Set filesize */ + /* -1 to match observed values */ + output[0]=LOW(offset-1); + output[1]=HIGH(offset-1); + /* output our file */ + for(i=0;i