BASIC compiler/interpreter for PIC32MX/MZ-80K
Revision | 0d7dd1dca26f170286f433ed1edcd1840cdbf186 (tree) |
---|---|
Time | 2019-02-07 07:09:22 |
Author | Katsumi <kmorimatsu@sour...> |
Commiter | Katsumi |
Debug issues of recursive object.
@@ -49,8 +49,6 @@ char* prepare_args_stack(char start_char){ | ||
49 | 49 | if (start_char==','){ |
50 | 50 | if (g_source[g_srcpos]!=',') break; |
51 | 51 | } else if (start_char=='('){ |
52 | - if (g_source[g_srcpos]!='(') return ERR_SYNTAX; | |
53 | - g_srcpos++; | |
54 | 52 | next_position(); |
55 | 53 | if (g_source[g_srcpos]==')') break; |
56 | 54 | g_srcpos--; |
@@ -95,7 +95,8 @@ char* end_compiling_class(int class){ | ||
95 | 95 | err=update_class_info(class); |
96 | 96 | if (err) return err; |
97 | 97 | // Resolve CMPDATA_UNSOLVED. |
98 | - resolve_unresolved(class); | |
98 | + err=resolve_unresolved(class); | |
99 | + if (err) return err; | |
99 | 100 | // Delete some cmpdata. |
100 | 101 | delete_cmpdata_for_class(class); |
101 | 102 | return 0; |
@@ -136,13 +137,23 @@ char* resolve_unresolved(int class){ | ||
136 | 137 | if (record[1]!=class) continue; |
137 | 138 | switch (record[0]&0xffff) { |
138 | 139 | case CMPTYPE_NEW_FUNCTION: |
140 | + // Shift of code may happen (man not). | |
141 | + for(i=-1;i<=0;i++){ | |
142 | + code=(int*)(record[2]); | |
143 | + if (code[i]!=0x3C080000) continue; | |
144 | + if (code[i+1]!=0x35080000) continue; | |
145 | + code=(int*)(record[3]); | |
146 | + if (code[i]!=ASM_ORI_A0_ZERO_) continue; | |
147 | + break; | |
148 | + } | |
149 | + if (0<i) return ERR_UNKNOWN; | |
139 | 150 | // Resolve address of code for pointer to class structure |
140 | - code=(int*)record[2]; | |
141 | - code[0]=(code[0]&0xFFFF0000) | (((int)classdata)>>16); | |
142 | - code[1]=(code[1]&0xFFFF0000) | (((int)classdata) & 0x0000FFFF); | |
151 | + code=(int*)(record[2]); | |
152 | + code[i+0]=0x3C080000 | (((unsigned int)classdata)>>16); | |
153 | + code[i+1]=0x35080000 | (((unsigned int)classdata) & 0x0000FFFF); | |
143 | 154 | // Resolve size of object |
144 | - code=(int*)record[3]; | |
145 | - code[0]=(code[0]&0xFFFF0000) | (object_size(classdata) & 0x0000FFFF); | |
155 | + code=(int*)(record[3]); | |
156 | + code[i+0]=ASM_ORI_A0_ZERO_ | (object_size(classdata) & 0x0000FFFF); | |
146 | 157 | // All done |
147 | 158 | break; |
148 | 159 | case CMPTYPE_STATIC_METHOD: |
@@ -150,7 +161,7 @@ char* resolve_unresolved(int class){ | ||
150 | 161 | // Find method |
151 | 162 | i=(int)search_method(classdata,record[2]); |
152 | 163 | if (!i) return ERR_NOT_FIELD; |
153 | - code=(int*)record[3]; | |
164 | + code=(int*)(record[3]); | |
154 | 165 | code[0]=(code[0]&0xFC000000)|((i&0x0FFFFFFF)>>2); |
155 | 166 | // All done |
156 | 167 | break; |
@@ -324,7 +335,7 @@ char* new_function(){ | ||
324 | 335 | // Class structure is unknown. Use null method. |
325 | 336 | init_method=(int*)&g_return_code[0]; |
326 | 337 | // Register CMPDATA |
327 | - cmpdata_insert(CMPDATA_UNSOLVED,CMPTYPE_NEW_FUNCTION,(int*)record[0],3); | |
338 | + cmpdata_insert(CMPDATA_UNSOLVED,CMPTYPE_NEW_FUNCTION,(int*)&record[0],3); | |
328 | 339 | } |
329 | 340 | if (!init_method) { |
330 | 341 | // All done |
@@ -406,6 +417,7 @@ char* field_statement(){ | ||
406 | 417 | */ |
407 | 418 | char* obj_method(int method){ |
408 | 419 | // $v0 contains the address of object. |
420 | + // Note that '(' has been passed. | |
409 | 421 | char* err; |
410 | 422 | int stack,opos; |
411 | 423 | // Parameters preparation (to $s5) here. |
@@ -466,11 +478,13 @@ char* _obj_field(char mode){ | ||
466 | 478 | if (i<65536) return ERR_SYNTAX; |
467 | 479 | if (g_source[g_srcpos]=='(' && mode==OBJ_FIELD_INTEGER) { |
468 | 480 | // This is a method |
481 | + g_srcpos++; | |
469 | 482 | return obj_method(i); |
470 | 483 | } else if (g_source[g_srcpos+1]=='(') { |
471 | 484 | if (g_source[g_srcpos]==mode) { |
472 | 485 | // This is a string/float method |
473 | 486 | g_srcpos++; |
487 | + g_srcpos++; | |
474 | 488 | return obj_method(i); |
475 | 489 | } |
476 | 490 | } else if (g_source[g_srcpos]==mode && mode==OBJ_FIELD_STRING) { |
@@ -229,10 +229,10 @@ static const char bastext[]= | ||
229 | 229 | "USECLASS CLASS1\n" |
230 | 230 | "CLS\n" |
231 | 231 | "a=new(CLASS1)\n" |
232 | -"b=new(CLASS1)\n" | |
233 | -"call a.TEST4(123)\n" | |
234 | -"call b.TEST4(456)\n" | |
235 | -"print a.TEST7(),b.TEST7()\n" | |
232 | +"b=a.T3()\n" | |
233 | +"c=b.T3()\n" | |
234 | +"print a,b,c\n" | |
235 | +"print a.T4(),b.T4(),c.T4()\n" | |
236 | 236 | "\n" |
237 | 237 | "\n" |
238 | 238 | "\n" |
@@ -243,26 +243,16 @@ static const char bastext[]= | ||
243 | 243 | |
244 | 244 | static const char classtext[]= |
245 | 245 | "REM\n" |
246 | -"STATIC TEST,TEST2\n" | |
247 | -"FIELD PRIVATE TEST6\n" | |
248 | -"METHOD TEST3\n" | |
249 | -" for i=-2 to 2:print args(i),:next\n" | |
250 | -" print\n" | |
251 | -"return TEST+TEST2\n" | |
252 | -"METHOD TEST4\n" | |
253 | -" TEST6=args(1)\n" | |
254 | -" while 1\n" | |
255 | -" return 3.14\n" | |
256 | -" wend\n" | |
257 | -" end\n" | |
258 | -"METHOD TEST5\n" | |
259 | -"return hex$(0xabc)\n" | |
260 | -"METHOD TEST7\n" | |
261 | -" for i=1 to 2\n" | |
262 | -" return TEST6\n" | |
263 | -" next\n" | |
264 | -" end\n" | |
265 | -"\n" | |
246 | +"STATIC T1,T2\n" | |
247 | +"FIELD PUBLIC T6\n" | |
248 | +"METHOD INIT\n" | |
249 | +" T6=rnd()\n" | |
250 | +" return\n" | |
251 | +"METHOD T3\n" | |
252 | +" o=new(CLASS1)\n" // TODO: save variables to object field before calling method of another object | |
253 | +" return o\n" | |
254 | +"METHOD T4\n" | |
255 | +" return T6\n" | |
266 | 256 | "\n" |
267 | 257 | "\n" |
268 | 258 | "\n" |
@@ -189,7 +189,8 @@ int compile_and_link_class(char* buff,int class){ | ||
189 | 189 | i=compile_and_link_file(buff,&classfile[0]); |
190 | 190 | if (i) break; |
191 | 191 | // End compiling class |
192 | - end_compiling_class(class); | |
192 | + err=end_compiling_class(class); | |
193 | + if (err) break; | |
193 | 194 | // Initial assembly is a jump statement to jump to the end of class file |
194 | 195 | g_object[0]=0x08000000 | ((((int)(&g_object[g_objpos]))&0x0FFFFFFF)>>2); // j xxxxxxxx |
195 | 196 | // In the next link, current region of object is ignored. |