BASIC compiler/interpreter for PIC32MX/MZ-80K (suspended)
| Revision | 154 (tree) |
|---|---|
| Time | 2016-08-24 06:18:08 |
| Author | kmorimatsu |
Implement CONTINUE statement.
| @@ -168,6 +168,7 @@ | ||
| 168 | 168 | extern unsigned char* g_pcg_font; |
| 169 | 169 | extern char g_use_graphic; |
| 170 | 170 | extern unsigned short* g_graphic_area; |
| 171 | +extern int g_temp; | |
| 171 | 172 | |
| 172 | 173 | /* Prototypes */ |
| 173 | 174 | int get_gp(void); |
| @@ -139,12 +139,11 @@ | ||
| 139 | 139 | |
| 140 | 140 | static const char bastext[]= |
| 141 | 141 | "CLS\n" |
| 142 | -"T#=10\n" | |
| 143 | -"T#=-10\n" | |
| 144 | -"T#=0\n" | |
| 145 | -"IF INT(T#=0) THEN X=1\n" | |
| 146 | -"T#=-10\n" | |
| 147 | -"PRINT T#\n" | |
| 142 | +"for i=1 to 10\n" | |
| 143 | +" print i;\n" | |
| 144 | +" continue\n" | |
| 145 | +" print \"NG\";\n" | |
| 146 | +"next\n" | |
| 148 | 147 | "\n"; |
| 149 | 148 | |
| 150 | 149 | /* |
| @@ -69,3 +69,5 @@ | ||
| 69 | 69 | // Pointer to graphic RAM |
| 70 | 70 | unsigned short* g_graphic_area; |
| 71 | 71 | |
| 72 | +// General purpose integer used for asigning value with pointer | |
| 73 | +int g_temp; |
| @@ -122,7 +122,7 @@ | ||
| 122 | 122 | } |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | -void* search_breakout(unsigned int start){ | |
| 125 | +void* search_breakout(unsigned int start, int* prevcode){ | |
| 126 | 126 | unsigned int pos,code1,depth; |
| 127 | 127 | // Start search from start point where BREAK statement is used. |
| 128 | 128 | depth=0; |
| @@ -147,6 +147,8 @@ | ||
| 147 | 147 | break; |
| 148 | 148 | } |
| 149 | 149 | // Destination found. |
| 150 | + // Previous code will be also set if required for CONTINUE statement. | |
| 151 | + if (prevcode) prevcode[0]=g_object[pos-1]; | |
| 150 | 152 | return (void*)&g_object[pos]; |
| 151 | 153 | default: |
| 152 | 154 | break; |
| @@ -194,6 +196,7 @@ | ||
| 194 | 196 | 0x0814xxxx, 0x0815xxxx: SOUND etc, for setting v0 as pointer to DATA array. |
| 195 | 197 | 0x0816xxxx: BREAK statemant and relatives |
| 196 | 198 | 0x08160000: BREAK |
| 199 | + 0x08160008: CONTINUE | |
| 197 | 200 | 0x08160100: Jump to next ELSE, ELSEIF or ENDIF |
| 198 | 201 | 0x082xyyyy: Begin block (FOR/DO/WHILE) |
| 199 | 202 | 0x083xyyyy: End block (NEXT/LOOP/WEND) |
| @@ -202,6 +205,7 @@ | ||
| 202 | 205 | MLB 2 bits show skip byte length in DATA. |
| 203 | 206 | 0x30000000: Begin block (IF-THEN-ELSEIF-ELSE-ENDIF) |
| 204 | 207 | 0x30008000: End block (IF-THEN-ELSEIF-ELSE-ENDIF) |
| 208 | + 0x3000Fxxx: General purpose NOP with value 0x0000-0x0FFF. | |
| 205 | 209 | |
| 206 | 210 | IF-THEN-ELSEIF-ELSE-ENDIF is written as follows: |
| 207 | 211 | IF-THEN: 0x30000000 0x10400000 0x30000000 |
| @@ -280,7 +284,7 @@ | ||
| 280 | 284 | // BREAK statement |
| 281 | 285 | // Find next the NEXT or WHILE statement and insert jump code after this. |
| 282 | 286 | g_label=g_line; |
| 283 | - code1=(int)search_breakout(pos); | |
| 287 | + code1=(int)search_breakout(pos,0); | |
| 284 | 288 | if (!code1) return ERR_INVALID_BREAK; |
| 285 | 289 | code1&=0x0FFFFFFF; |
| 286 | 290 | code1>>=2; |
| @@ -287,6 +291,24 @@ | ||
| 287 | 291 | code1|=0x08000000; // j xxxx |
| 288 | 292 | g_object[pos]=code1; |
| 289 | 293 | break; |
| 294 | + case 0x0008: | |
| 295 | + // CONTINUE statement | |
| 296 | + // Find next the NEXT or WHILE statement and insert jump code after this. | |
| 297 | + g_label=g_line; | |
| 298 | + code1=(int)search_breakout(pos,&g_temp); | |
| 299 | + if (!code1) return ERR_INVALID_BREAK; | |
| 300 | + if (0x3000F000 == (g_temp&0xFFFFF000)) { | |
| 301 | + // WEND or LOOP statement found | |
| 302 | + code1-=(g_temp&0x0FFF)<<2; | |
| 303 | + } else { | |
| 304 | + // NEXT statement found | |
| 305 | + code1-=3<<2; | |
| 306 | + } | |
| 307 | + code1&=0x0FFFFFFF; | |
| 308 | + code1>>=2; | |
| 309 | + code1|=0x08000000; // j xxxx | |
| 310 | + g_object[pos]=code1; | |
| 311 | + break; | |
| 290 | 312 | case 0x0100: |
| 291 | 313 | // Jump to next ENDIF |
| 292 | 314 | g_label=g_line; |
| @@ -717,6 +717,13 @@ | ||
| 717 | 717 | return 0; |
| 718 | 718 | } |
| 719 | 719 | |
| 720 | +char* continue_statement(){ | |
| 721 | + check_obj_space(2); | |
| 722 | + g_object[g_objpos++]=0x08160008; // j xxxx (See link() function) | |
| 723 | + g_object[g_objpos++]=0x00000000; // nop | |
| 724 | + return 0; | |
| 725 | +} | |
| 726 | + | |
| 720 | 727 | char* for_statement(){ |
| 721 | 728 | char* err; |
| 722 | 729 | char b1; |
| @@ -776,7 +783,9 @@ | ||
| 776 | 783 | |
| 777 | 784 | char* next_statement(){ |
| 778 | 785 | // Return to address stored in 4($sp) |
| 779 | - // while set $v0 to 8($sp) (see for_statement) | |
| 786 | + // while set $v0 to 8($sp) (see for_statement) | |
| 787 | + // Following assembly must be 4 words. | |
| 788 | + // If the number of words will be changed, link.c must be reviced for CONTINUE statement. | |
| 780 | 789 | check_obj_space(4); |
| 781 | 790 | g_object[g_objpos++]=0x8FBF0004; // lw ra,4(sp) |
| 782 | 791 | g_object[g_objpos++]=0x03E00008; // jr ra |
| @@ -821,6 +830,8 @@ | ||
| 821 | 830 | |
| 822 | 831 | char* loop_statement(){ |
| 823 | 832 | char* err; |
| 833 | + int opos; | |
| 834 | + opos=g_objpos; | |
| 824 | 835 | if (nextCodeIs("WHILE ")) { |
| 825 | 836 | // LOOP WHILE |
| 826 | 837 | err=get_floatOrValue(); |
| @@ -837,11 +848,12 @@ | ||
| 837 | 848 | // LOOP statement without WHILE/UNTIL |
| 838 | 849 | } |
| 839 | 850 | check_obj_space(4); |
| 840 | - g_object[g_objpos++]=0x8FBF0004; // lw ra,4(sp) | |
| 841 | - g_object[g_objpos++]=0x03E00008; // jr ra | |
| 842 | - g_object[g_objpos++]=0x00000000; // nop | |
| 843 | - // label1: | |
| 844 | - g_object[g_objpos++]=0x08320004; // addiu sp,sp,4 (See link() function) | |
| 851 | + g_object[g_objpos++]=0x8FBF0004; // lw ra,4(sp) | |
| 852 | + g_object[g_objpos++]=0x03E00008; // jr ra | |
| 853 | + opos=g_objpos+1-opos; | |
| 854 | + g_object[g_objpos++]=0x3000F000|opos; // nop (See linker, used for CONTINUE statement) | |
| 855 | + // label1: | |
| 856 | + g_object[g_objpos++]=0x08320004; // addiu sp,sp,4 (See link() function) | |
| 845 | 857 | return 0; |
| 846 | 858 | } |
| 847 | 859 |
| @@ -865,9 +877,9 @@ | ||
| 865 | 877 | check_obj_space(4); |
| 866 | 878 | g_object[g_objpos++]=0x8FBF0004; // lw ra,4(sp) |
| 867 | 879 | g_object[g_objpos++]=0x03E00008; // jr ra |
| 868 | - g_object[g_objpos++]=0x00000000; // nop | |
| 880 | + g_object[g_objpos++]=0x3000F003; // nop (See linker, used for CONTINUE statement) | |
| 869 | 881 | // label1: |
| 870 | - g_object[g_objpos++]=0x08310004; // addiu sp,sp,4 (See link() function) | |
| 882 | + g_object[g_objpos++]=0x08310004; // addiu sp,sp,4 (See link() function) | |
| 871 | 883 | return 0; |
| 872 | 884 | } |
| 873 | 885 |
| @@ -1357,6 +1369,8 @@ | ||
| 1357 | 1369 | err=wend_statement(); |
| 1358 | 1370 | } else if (nextCodeIs("BREAK")) { |
| 1359 | 1371 | err=break_statement(); |
| 1372 | + } else if (nextCodeIs("CONTINUE")) { | |
| 1373 | + err=continue_statement(); | |
| 1360 | 1374 | } else if (nextCodeIs("SYSTEM")) { |
| 1361 | 1375 | err=system_statement(); |
| 1362 | 1376 | #ifdef __DEBUG |