BASIC compiler/interpreter for PIC32MX/MZ-80K
Revisión | c6fc4cfbaca492f00f4aca9ddc27cce8efd3d377 (tree) |
---|---|
Tiempo | 2019-02-05 07:10:30 |
Autor | Katsumi <kmorimatsu@sour...> |
Commiter | Katsumi |
Standardize arguments construction routines.
@@ -0,0 +1,108 @@ | ||
1 | +/* | |
2 | + This file is provided under the LGPL license ver 2.1. | |
3 | + Written by Katsumi. | |
4 | + http://hp.vector.co.jp/authors/VA016157/ | |
5 | + kmorimatsu@users.sourceforge.jp | |
6 | +*/ | |
7 | + | |
8 | +/* | |
9 | + This file is shared by Megalopa and Zoea | |
10 | +*/ | |
11 | + | |
12 | +#include "compiler.h" | |
13 | + | |
14 | +const unsigned int g_initial_s5_stack[3]={ | |
15 | + 0, // -8($s5): no object | |
16 | + (unsigned int) &g_initial_s5_stack[2], // -4($s5): previous $s5 (recursive) | |
17 | + 0 // 0($s5): no parameter | |
18 | +}; | |
19 | + | |
20 | +static int g_args_stack; | |
21 | +/* | |
22 | + See ARGS_SP_XXXX and ARGS_S5_XXXX in compiler.h | |
23 | + At least 4 stacks are needed even without argument | |
24 | + 4($sp) = -12($s5): $sp | |
25 | + 8($sp) = -8($s5): $v0 - pointer to object or previous -8($s5) | |
26 | + 12($sp) = -4($s5): previous $s5 | |
27 | + 16($sp) = 0($s5): number of arguments | |
28 | + 20($sp) = 4($s5): first argument | |
29 | + $v0 must be the pointer to an object before comming to this code. | |
30 | + After this code, -12($s5) must be set to $sp: 0xAEBDFFF4 sw sp,-12(s5) | |
31 | +*/ | |
32 | +char* prepare_args_stack(char start_char){ | |
33 | + // start_char is either ',' or '(' | |
34 | + // When ',' mode, there must be a ',' if argument(s) exist(s). | |
35 | + // When '(' mode, there shouldn't be a '(', because this character has passed. | |
36 | + char* err; | |
37 | + int opos,stack; | |
38 | + stack=0; | |
39 | + opos=g_objpos; | |
40 | + check_obj_space(2); | |
41 | + g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx | |
42 | + // 8(sp) is for $v0, which is pointer to an object | |
43 | + g_object[g_objpos++]=0xAFA20008; // sw v0,8(sp) | |
44 | + next_position(); | |
45 | + do { | |
46 | + if (!stack) { | |
47 | + // First parameter if exists | |
48 | + stack=16; | |
49 | + if (start_char==','){ | |
50 | + if (g_source[g_srcpos]!=',') break; | |
51 | + } else if (start_char=='('){ | |
52 | + if (g_source[g_srcpos]!='(') return ERR_SYNTAX; | |
53 | + g_srcpos++; | |
54 | + next_position(); | |
55 | + if (g_source[g_srcpos]==')') break; | |
56 | + g_srcpos--; | |
57 | + } else { | |
58 | + return ERR_UNKNOWN; | |
59 | + } | |
60 | + } | |
61 | + g_srcpos++; | |
62 | + stack+=4; | |
63 | + err=get_stringFloatOrValue(); | |
64 | + if (err) return err; | |
65 | + check_obj_space(1); | |
66 | + g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp) | |
67 | + next_position(); | |
68 | + } while (g_source[g_srcpos]==','); | |
69 | + // 12(sp) is for $s5, 16(sp) is for # of parameters | |
70 | + check_obj_space(5); | |
71 | + g_object[g_objpos++]=0xAFB5000C; // sw s5,12(sp) | |
72 | + g_object[g_objpos++]=0x34020000|(stack/4-4); // ori v0,zero,xx | |
73 | + g_object[g_objpos++]=0xAFA20010; // sw v0,16(sp) | |
74 | + g_object[g_objpos++]=0x27B50010; // addiu s5,sp,16 | |
75 | + g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above) | |
76 | + // All done. Register # of stacks to global var. | |
77 | + g_args_stack=stack; | |
78 | + return 0; | |
79 | +} | |
80 | + | |
81 | +char* remove_args_stack(void){ | |
82 | + // Remove stack | |
83 | + check_obj_space(2); | |
84 | + g_object[g_objpos++]=0x8FB5000C; // lw s5,12(sp) | |
85 | + g_object[g_objpos++]=0x27BD0000|g_args_stack; // addiu sp,sp,xx | |
86 | + return 0; | |
87 | +} | |
88 | + | |
89 | +char* args_function_main(void){ | |
90 | + char* err; | |
91 | + int i; | |
92 | + err=get_value(); | |
93 | + if (err) return err; | |
94 | + i=g_object[g_objpos-1]; | |
95 | + if ((i>>16)==0x3402) { | |
96 | + // Previous object is "ori v0,zero,xxxx". | |
97 | + i&=0xffff; | |
98 | + i=i<<2; | |
99 | + g_object[g_objpos-1]=0x8EA20000|i; // lw v0,xx(s5) | |
100 | + } else { | |
101 | + check_obj_space(3); | |
102 | + g_object[g_objpos++]=0x00021080; // sll v0,v0,0x2 | |
103 | + g_object[g_objpos++]=0x02A21021; // addu v0,s5,v0 | |
104 | + g_object[g_objpos++]=0x8C420000; // lw v0,0(v0) | |
105 | + } | |
106 | + return 0; | |
107 | +} | |
108 | + |
@@ -319,51 +319,22 @@ char* obj_method(int method){ | ||
319 | 319 | // Parameters preparation (to $s5) here. |
320 | 320 | next_position(); |
321 | 321 | opos=g_objpos; |
322 | - | |
323 | 322 | // Begin parameter(s) construction routine |
324 | - // Note that this comment must be copied | |
325 | - // when inserting simiar routine to source | |
326 | - | |
327 | - stack=12; | |
328 | - g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx | |
329 | - // 4(sp) is for $v0 (pointer to object) | |
330 | - g_object[g_objpos++]=0xAFA20004; // sw v0,4(sp) | |
331 | - if (g_source[g_srcpos]!=')') { | |
332 | - g_srcpos--; | |
333 | - do { | |
334 | - g_srcpos++; | |
335 | - stack+=4; | |
336 | - err=get_stringFloatOrValue(); | |
337 | - if (err) return err; | |
338 | - check_obj_space(1); | |
339 | - g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp) | |
340 | - next_position(); | |
341 | - } while(g_source[g_srcpos]==','); | |
342 | - } | |
323 | + err=prepare_args_stack('('); | |
324 | + if (err) return err; | |
343 | 325 | if (g_source[g_srcpos]!=')') return ERR_SYNTAX; |
344 | 326 | g_srcpos++; |
345 | - // 8(sp) is for $s5, 12(sp) is for # of arguments | |
346 | - check_obj_space(4); | |
347 | - g_object[g_objpos++]=0xAFB50008; // sw s5,8(sp) | |
348 | - g_object[g_objpos++]=0x34020000|(stack/4-3); // ori v0,zero,xx | |
349 | - g_object[g_objpos++]=0xAFA2000C; // sw v0,12(sp) | |
350 | - g_object[g_objpos++]=0x27B50008; // addiu s5,sp,8 | |
351 | - g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above) | |
352 | - | |
353 | - // End parameter(s) construction routine | |
354 | - // Note that this comment must be copied | |
355 | - // when inserting simiar routine to source | |
356 | - | |
357 | 327 | // Determine address of method and store fields to local variables. |
358 | 328 | check_obj_space(3); |
359 | - g_object[g_objpos++]=0x8FA20004; // lw v0,4(sp) | |
329 | + g_object[g_objpos++]=0x8FA20000|ARGS_SP_V0_OBJ; // lw v0,8(sp) | |
360 | 330 | g_object[g_objpos++]=0x3C050000|((method>>16)&0x0000FFFF); // lui a1,xxxx |
361 | 331 | g_object[g_objpos++]=0x34A50000|(method&0x0000FFFF); // ori a1,a1,xxxx |
362 | 332 | call_quicklib_code(lib_pre_method,ASM_ADDU_A0_V0_ZERO); |
363 | 333 | // Call method address here. Same routine for GOSUB statement with integer value is used. |
364 | 334 | check_obj_space(6); |
365 | - g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
366 | 335 | g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4 |
336 | + g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
337 | + g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5) | |
367 | 338 | g_object[g_objpos++]=0x10000003; // beq zero,zero,label2 |
368 | 339 | g_object[g_objpos++]=0x00000000; // nop |
369 | 340 | // label1: |
@@ -371,14 +342,11 @@ char* obj_method(int method){ | ||
371 | 342 | g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp) // label2: |
372 | 343 | // Restore fields from local variables. |
373 | 344 | check_obj_space(3); |
374 | - g_object[g_objpos++]=0x8FA40004; // lw a0,4(sp) | |
375 | - g_object[g_objpos++]=0x3C050000|((method>>16)&0x0000FFFF); // lui a1,xxxx | |
376 | - g_object[g_objpos++]=0x34A50000|(method&0x0000FFFF); // ori a1,a1,xxxx | |
377 | - call_quicklib_code(lib_post_method,ASM_ADDU_A2_V0_ZERO); | |
345 | + g_object[g_objpos++]=0x8FA40008; // lw a0,8(sp) | |
346 | + call_quicklib_code(lib_post_method,ASM_ADDU_A1_V0_ZERO); | |
378 | 347 | // Remove stack |
379 | - check_obj_space(2); | |
380 | - g_object[g_objpos++]=0x8FB50008; // lw s5,8(sp) | |
381 | - g_object[g_objpos++]=0x27BD0000|stack; // addiu sp,sp,xx | |
348 | + err=remove_args_stack(); | |
349 | + if (err) return err; | |
382 | 350 | return 0; |
383 | 351 | } |
384 | 352 |
@@ -402,17 +370,15 @@ char* _obj_field(char mode){ | ||
402 | 370 | int i; |
403 | 371 | char* err; |
404 | 372 | do { |
405 | - i=check_var_name(); // TODO: consider accepting reserbed var names for field name | |
373 | + i=check_var_name(); | |
406 | 374 | if (i<65536) return ERR_SYNTAX; |
407 | 375 | if (g_source[g_srcpos]=='(' && mode==OBJ_FIELD_INTEGER) { |
408 | 376 | // This is a method |
409 | - g_srcpos++; | |
410 | 377 | return obj_method(i); |
411 | 378 | } else if (g_source[g_srcpos+1]=='(') { |
412 | 379 | if (g_source[g_srcpos]==mode) { |
413 | 380 | // This is a string/float method |
414 | 381 | g_srcpos++; |
415 | - g_srcpos++; | |
416 | 382 | return obj_method(i); |
417 | 383 | } |
418 | 384 | } else if (g_source[g_srcpos]==mode && mode==OBJ_FIELD_STRING) { |
@@ -539,8 +505,8 @@ int lib_pre_method(int* object, int methodname){ | ||
539 | 505 | return class[1]; |
540 | 506 | } |
541 | 507 | |
542 | -int lib_post_method(int* object, int methodname, int v0){ | |
543 | - // Note that existence of the method was checked in above function before reaching this function. | |
508 | +int lib_post_method(int* object, int v0){ | |
509 | + // Note that v0 (a1) contains the return value from a method. | |
544 | 510 | int i,num,nums; |
545 | 511 | int* class; |
546 | 512 | // Restore local variables to object field values |
@@ -706,51 +672,25 @@ char* static_method(char type){ | ||
706 | 672 | |
707 | 673 | } |
708 | 674 | if (g_source[g_srcpos]!='(') return ERR_SYNTAX; |
709 | - g_srcpos++; | |
710 | - | |
711 | 675 | // Begin parameter(s) construction routine |
712 | - // Note that this comment must be copied | |
713 | - // when inserting simiar routine to source | |
714 | - | |
715 | - stack=8; | |
716 | - opos=g_objpos; | |
717 | - g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx | |
718 | - while(g_source[g_srcpos]==',') { | |
719 | - g_srcpos++; | |
720 | - stack+=4; | |
721 | - err=get_stringFloatOrValue(); | |
722 | - if (err) return err; | |
723 | - check_obj_space(1); | |
724 | - g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp) | |
725 | - next_position(); | |
726 | - } | |
727 | - // 4(sp) is for $s5, 8(sp) is for # of parameters | |
728 | - check_obj_space(5); | |
729 | - g_object[g_objpos++]=0xAFB50004; // sw s5,4(sp) | |
730 | - g_object[g_objpos++]=0x34020000|(stack/4-2); // ori v0,zero,xx | |
731 | - g_object[g_objpos++]=0xAFA20008; // sw v0,8(sp) | |
732 | - g_object[g_objpos++]=0x27B50004; // addiu s5,sp,4 | |
733 | - g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above) | |
734 | - | |
735 | - // End parameter(s) construction routine | |
736 | - // Note that this comment must be copied | |
737 | - // when inserting simiar routine to source | |
738 | - | |
676 | + check_obj_space(1); | |
677 | + g_object[g_objpos++]=0x34020000; // ori v0,zero,0 | |
678 | + err=prepare_args_stack('('); | |
679 | + if (err) return err; | |
739 | 680 | // Calling subroutine, which is static method of class |
740 | - check_obj_space(6); | |
741 | - g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
681 | + check_obj_space(7); | |
742 | 682 | g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4 |
683 | + g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
684 | + g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5) | |
743 | 685 | g_object[g_objpos++]=0x10000003; // beq zero,zero,label2 |
744 | 686 | g_object[g_objpos++]=0x00000000; // nop |
745 | 687 | // label1: |
746 | 688 | g_object[g_objpos++]=0x08000000|((method&0x0FFFFFFF)>>2); // j xxxx |
747 | 689 | g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp) |
748 | - // label2: | |
690 | + // label2: | |
749 | 691 | // Remove stack |
750 | - check_obj_space(2); | |
751 | - g_object[g_objpos++]=0x8FB50004; // lw s5,4(sp) | |
752 | - g_object[g_objpos++]=0x27BD0000|stack; // addiu sp,sp,xx | |
753 | - | |
692 | + err=remove_args_stack(); | |
693 | + if (err) return err; | |
754 | 694 | return 0; |
755 | 695 | } |
756 | 696 |
@@ -57,6 +57,8 @@ void start_program(void* addr, void* memory){ | ||
57 | 57 | asm volatile("la $v0,%0"::"i"(&g_end_addr)); |
58 | 58 | asm volatile("la $v1,label"); |
59 | 59 | asm volatile("sw $v1,0($v0)"); |
60 | + // Set s5 for initial_s5_stack | |
61 | + asm volatile("la $s5,%0"::"i"(&g_initial_s5_stack[2])); | |
60 | 62 | // Set s7 for easy calling call_library() |
61 | 63 | asm volatile("la $s7,%0"::"i"(&call_library)); |
62 | 64 | // Set fp and execute program |
@@ -335,6 +335,11 @@ char* update_class_info(int class); | ||
335 | 335 | char* construct_class_structure(int class); |
336 | 336 | void delete_cmpdata_for_class(); |
337 | 337 | |
338 | +extern const unsigned int g_initial_s5_stack[3]; | |
339 | +char* prepare_args_stack(char start_char); | |
340 | +char* remove_args_stack(void); | |
341 | +char* args_function_main(void); | |
342 | + | |
338 | 343 | char* begin_compiling_class(int class); |
339 | 344 | char* end_compiling_class(int class); |
340 | 345 | char* new_function(); |
@@ -344,7 +349,7 @@ char* string_obj_field(); | ||
344 | 349 | char* float_obj_field(); |
345 | 350 | int lib_obj_field(int* object, int fieldname); |
346 | 351 | int lib_pre_method(int* object, int methodname); |
347 | -int lib_post_method(int* object, int methodname, int v0); | |
352 | +int lib_post_method(int* object, int v0); | |
348 | 353 | char* method_statement(); |
349 | 354 | char* delete_statement(); |
350 | 355 | char* call_statement(); |
@@ -391,6 +396,16 @@ char* static_method(char type); | ||
391 | 396 | #define CMPDATA_FIELD 3 |
392 | 397 | #define CMPDATA_STATIC 4 |
393 | 398 | |
399 | +/* Stack position for values in args.c */ | |
400 | +#define ARGS_SP_SP 4 | |
401 | +#define ARGS_SP_V0_OBJ 8 | |
402 | +#define ARGS_SP_PREV_S5 12 | |
403 | +#define ARGS_SP_NUM_ARGS 16 | |
404 | +#define ARGS_S5_SP (-12 & 0xFFFF) | |
405 | +#define ARGS_S5_V0_OBJ (-8 & 0xFFFF) | |
406 | +#define ARGS_S5_PREV_S5 (-4 & 0xFFFF) | |
407 | +#define ARGS_S5_NUM_ARGS (0 & 0xFFFF) | |
408 | + | |
394 | 409 | /* |
395 | 410 | Hidden varname 31 bit values |
396 | 411 | Note that max number of 31 bit value is 0x61504BFF (for ZZZZZZ) |
@@ -229,26 +229,14 @@ static const char bastext[]= | ||
229 | 229 | "USECLASS CLASS1\n" |
230 | 230 | "CLS\n" |
231 | 231 | "a=new(CLASS1)\n" |
232 | -"call a.INIT(123,456)\n" | |
233 | -"CLASS1::TEST=123\n" | |
234 | -"CLASS1::TEST2=456\n" | |
235 | -"print CLASS1::TEST3(),\n" | |
236 | -"print CLASS1::TEST4#(),\n" | |
237 | -"print CLASS1::TEST5$(),\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" | |
238 | 236 | "\n" |
239 | 237 | "\n" |
240 | 238 | "\n" |
241 | 239 | "\n" |
242 | -"end\n" | |
243 | -"for i=1 to 150\n" | |
244 | -" a=new(CLASS1)\n" | |
245 | -" delete a\n" | |
246 | -" cursor 0,0\n" | |
247 | -" print i,\n" | |
248 | -"next\n" | |
249 | -"\n" | |
250 | -"\n" | |
251 | -"\n" | |
252 | 240 | "\n" |
253 | 241 | "\n"; |
254 | 242 |
@@ -256,13 +244,18 @@ static const char bastext[]= | ||
256 | 244 | static const char classtext[]= |
257 | 245 | "REM\n" |
258 | 246 | "STATIC TEST,TEST2\n" |
247 | +"FIELD PRIVATE TEST6\n" | |
259 | 248 | "METHOD TEST3\n" |
249 | +" for i=-2 to 2:print args(i),:next\n" | |
250 | +" print\n" | |
260 | 251 | "return TEST+TEST2\n" |
261 | 252 | "METHOD TEST4\n" |
253 | +" TEST6=args(1)\n" | |
262 | 254 | "return 3.14\n" |
263 | 255 | "METHOD TEST5\n" |
264 | 256 | "return hex$(0xabc)\n" |
265 | -"\n" | |
257 | +"METHOD TEST7\n" | |
258 | +"return TEST6\n" | |
266 | 259 | "\n" |
267 | 260 | "\n" |
268 | 261 | "\n" |
@@ -282,8 +275,9 @@ static const void* debugjumptable[]={ | ||
282 | 275 | int _debug_test(int a0, int a1, int a2, int a3, int param4, int param5){ |
283 | 276 | asm volatile(".set noreorder"); |
284 | 277 | asm volatile("lw $a0,0($v1)"); |
285 | - asm volatile("nop"); | |
286 | - asm volatile("nop"); | |
278 | + asm volatile("sw $sp,-12($s5)"); | |
279 | + asm volatile("lw $sp,-12($s5)"); | |
280 | + asm volatile("lw $v0,-8($s5)"); | |
287 | 281 | asm volatile("nop"); |
288 | 282 | asm volatile("nop"); |
289 | 283 | asm volatile("nop"); |
@@ -261,23 +261,7 @@ char* inkey_function(void){ | ||
261 | 261 | } |
262 | 262 | |
263 | 263 | char* args_function(void){ |
264 | - char* err; | |
265 | - int i; | |
266 | - err=get_value(); | |
267 | - if (err) return err; | |
268 | - i=g_object[g_objpos-1]; | |
269 | - if ((i>>16)==0x3402) { | |
270 | - // Previous object is "ori v0,zero,xxxx". | |
271 | - i&=0xffff; | |
272 | - i=(i+1)<<2; | |
273 | - g_object[g_objpos-1]=0x8EA20000|i; // lw v0,xx(s5) | |
274 | - } else { | |
275 | - check_obj_space(3); | |
276 | - g_object[g_objpos++]=0x00021080; // sll v0,v0,0x2 | |
277 | - g_object[g_objpos++]=0x02A21021; // addu v0,s5,v0 | |
278 | - g_object[g_objpos++]=0x8C420004; // lw v0,4(v0) | |
279 | - } | |
280 | - return 0; | |
264 | + return args_function_main(); | |
281 | 265 | } |
282 | 266 | |
283 | 267 | char* system_function(void){ |
@@ -70,6 +70,7 @@ file_042=. | ||
70 | 70 | file_043=. |
71 | 71 | file_044=. |
72 | 72 | file_045=. |
73 | +file_046=. | |
73 | 74 | [GENERATED_FILES] |
74 | 75 | file_000=no |
75 | 76 | file_001=no |
@@ -117,6 +118,7 @@ file_042=no | ||
117 | 118 | file_043=no |
118 | 119 | file_044=no |
119 | 120 | file_045=no |
121 | +file_046=no | |
120 | 122 | [OTHER_FILES] |
121 | 123 | file_000=no |
122 | 124 | file_001=no |
@@ -160,10 +162,11 @@ file_038=no | ||
160 | 162 | file_039=no |
161 | 163 | file_040=no |
162 | 164 | file_041=no |
163 | -file_042=yes | |
165 | +file_042=no | |
164 | 166 | file_043=yes |
165 | 167 | file_044=yes |
166 | 168 | file_045=yes |
169 | +file_046=yes | |
167 | 170 | [FILE_INFO] |
168 | 171 | file_000=compiler.c |
169 | 172 | file_001=debug.c |
@@ -192,25 +195,26 @@ file_023=io.c | ||
192 | 195 | file_024=i2c.c |
193 | 196 | file_025=spi.c |
194 | 197 | file_026=class.c |
195 | -file_027=api.h | |
196 | -file_028=compiler.h | |
197 | -file_029=debug.h | |
198 | -file_030=editor.h | |
199 | -file_031=keyinput.h | |
200 | -file_032=main.h | |
201 | -file_033=ps2keyboard.h | |
202 | -file_034=sdfsio370f.h | |
203 | -file_035=lib_video_megalopa.h | |
204 | -file_036=envspecific.h | |
205 | -file_037=io.h | |
206 | -file_038=ps2keyboard370f.X.a | |
207 | -file_039=sdfsio370fLib.X.a | |
208 | -file_040=lib_videoout_megalopa.X.a | |
209 | -file_041=app_p32MX370F512H.ld | |
210 | -file_042=help.txt | |
211 | -file_043=reservednames.js | |
212 | -file_044=class.txt | |
213 | -file_045=sharedfiles.js | |
198 | +file_027=args.c | |
199 | +file_028=api.h | |
200 | +file_029=compiler.h | |
201 | +file_030=debug.h | |
202 | +file_031=editor.h | |
203 | +file_032=keyinput.h | |
204 | +file_033=main.h | |
205 | +file_034=ps2keyboard.h | |
206 | +file_035=sdfsio370f.h | |
207 | +file_036=lib_video_megalopa.h | |
208 | +file_037=envspecific.h | |
209 | +file_038=io.h | |
210 | +file_039=ps2keyboard370f.X.a | |
211 | +file_040=sdfsio370fLib.X.a | |
212 | +file_041=lib_videoout_megalopa.X.a | |
213 | +file_042=app_p32MX370F512H.ld | |
214 | +file_043=help.txt | |
215 | +file_044=reservednames.js | |
216 | +file_045=class.txt | |
217 | +file_046=sharedfiles.js | |
214 | 218 | [SUITE_INFO] |
215 | 219 | suite_guid={62D235D8-2DB2-49CD-AF24-5489A6015337} |
216 | 220 | suite_state= |
@@ -359,9 +359,10 @@ char* gosub_statement_sub(){ | ||
359 | 359 | // Label/number is constant. |
360 | 360 | // Linker will change following codes later. |
361 | 361 | // Note that 0x0812xxxx and 0x0813xxxx are specific codes for these. |
362 | - check_obj_space(6); | |
363 | - g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
362 | + check_obj_space(7); | |
364 | 363 | g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4 |
364 | + g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
365 | + g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5) | |
365 | 366 | g_object[g_objpos++]=0x10000003; // beq zero,zero,label2 |
366 | 367 | g_object[g_objpos++]=0x08120000|((g_label>>16)&0x0000FFFF); // nop |
367 | 368 | // label1: |
@@ -373,15 +374,16 @@ char* gosub_statement_sub(){ | ||
373 | 374 | err=get_value(); |
374 | 375 | if (err) return err; |
375 | 376 | call_lib_code(LIB_LABEL); |
376 | - check_obj_space(6); | |
377 | - g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
378 | - g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4 | |
379 | - g_object[g_objpos++]=0x10000003; // beq zero,zero,label2 | |
380 | - g_object[g_objpos++]=0x00000000; // nop | |
381 | - // label1: | |
382 | - g_object[g_objpos++]=0x00400008; // jr v0 | |
383 | - g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp) | |
384 | - // label2: | |
377 | + check_obj_space(7); | |
378 | + g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4 | |
379 | + g_object[g_objpos++]=0x04130003; // bgezall zero,label1 | |
380 | + g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5) | |
381 | + g_object[g_objpos++]=0x10000003; // beq zero,zero,label2 | |
382 | + g_object[g_objpos++]=0x00000000; // nop | |
383 | + // label1: | |
384 | + g_object[g_objpos++]=0x00400008; // jr v0 | |
385 | + g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp) | |
386 | + // label2: | |
385 | 387 | } |
386 | 388 | return 0; |
387 | 389 | } |
@@ -397,34 +399,10 @@ char* gosub_statement(){ | ||
397 | 399 | next_position(); |
398 | 400 | // Rewind object and construct argument-creating routine. |
399 | 401 | g_objpos=opos; |
400 | - | |
401 | 402 | // Begin parameter(s) construction routine |
402 | - // Note that this comment must be copied | |
403 | - // when inserting simiar routine to source | |
404 | - | |
405 | - stack=8; | |
406 | - g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx | |
407 | - while(g_source[g_srcpos]==',') { | |
408 | - g_srcpos++; | |
409 | - stack+=4; | |
410 | - err=get_stringFloatOrValue(); | |
411 | - if (err) return err; | |
412 | - check_obj_space(1); | |
413 | - g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp) | |
414 | - next_position(); | |
415 | - } | |
416 | - // 4(sp) is for $s5, 8(sp) is for # of parameters | |
417 | - check_obj_space(5); | |
418 | - g_object[g_objpos++]=0xAFB50004; // sw s5,4(sp) | |
419 | - g_object[g_objpos++]=0x34020000|(stack/4-2); // ori v0,zero,xx | |
420 | - g_object[g_objpos++]=0xAFA20008; // sw v0,8(sp) | |
421 | - g_object[g_objpos++]=0x27B50004; // addiu s5,sp,4 | |
422 | - g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above) | |
423 | - | |
424 | - // End parameter(s) construction routine | |
425 | - // Note that this comment must be copied | |
426 | - // when inserting simiar routine to source | |
427 | - | |
403 | + g_object[g_objpos++]=0x8EA20000|ARGS_S5_V0_OBJ; // lw v0,-8(s5) | |
404 | + err=prepare_args_stack(','); | |
405 | + if (err) return err; | |
428 | 406 | // Rewind source and construct GOSUB routine again. |
429 | 407 | opos=spos; |
430 | 408 | spos=g_srcpos; |
@@ -432,9 +410,8 @@ char* gosub_statement(){ | ||
432 | 410 | err=gosub_statement_sub(); |
433 | 411 | if (err) return err; |
434 | 412 | // Remove stack |
435 | - check_obj_space(2); | |
436 | - g_object[g_objpos++]=0x8FB50004; // lw s5,4(sp) | |
437 | - g_object[g_objpos++]=0x27BD0000|stack; // addiu sp,sp,xx | |
413 | + err=remove_args_stack(); | |
414 | + if (err) return err; | |
438 | 415 | // All done, go back to right source position |
439 | 416 | g_srcpos=spos; |
440 | 417 | return 0; |
@@ -450,10 +427,11 @@ char* return_statement(){ | ||
450 | 427 | err=get_stringFloatOrValue(); |
451 | 428 | if (err) return err; |
452 | 429 | } |
453 | - check_obj_space(3); | |
454 | - g_object[g_objpos++]=0x8FA30004; // lw v1,4(sp) | |
455 | - g_object[g_objpos++]=0x00600008; // jr v1 | |
456 | - g_object[g_objpos++]=0x27BD0004; // addiu sp,sp,4 | |
430 | + check_obj_space(4); | |
431 | + g_object[g_objpos++]=0x8EBD0000|ARGS_S5_SP; // lw sp,-12(s5) | |
432 | + g_object[g_objpos++]=0x8FA30004; // lw v1,4(sp) | |
433 | + g_object[g_objpos++]=0x00600008; // jr v1 | |
434 | + g_object[g_objpos++]=0x27BD0004; // addiu sp,sp,4 | |
457 | 435 | return 0; |
458 | 436 | } |
459 | 437 |
@@ -1258,6 +1236,9 @@ char* var_statement(){ | ||
1258 | 1236 | call_lib_code(LIB_VAR_PUSH); |
1259 | 1237 | |
1260 | 1238 | } while (g_source[g_srcpos-1]==','); |
1239 | + // Renew sp stored in s5 stack. | |
1240 | + check_obj_space(1); | |
1241 | + g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5) | |
1261 | 1242 | return 0; |
1262 | 1243 | } |
1263 | 1244 |