• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

BASIC compiler/interpreter for PIC32MX/MZ-80K


Commit MetaInfo

Revisión0d0d0b27966a8db911d5bc2bf806885f30ed03a8 (tree)
Tiempo2019-04-15 13:34:35
AutorKatsumi <kmorimatsu@sour...>
CommiterKatsumi

Log Message

Fast field access implementation.

Cambiar Resumen

Diferencia incremental

--- a/mips/megalopa/class.c
+++ b/mips/megalopa/class.c
@@ -33,6 +33,14 @@ static int* g_class_structure;
3333 record[1]: field/method name as integer
3434 record[2]: pointer to method
3535 */
36+/*
37+ CMPDATA_FASTFIELD structure
38+ type: CMPDATA_FASTFIELD
39+ len: 2
40+ data16: number of position of public field in object
41+ 0 for multiple usage of the same public field name
42+ record[1]: field name as integer
43+*/
3644
3745 /*
3846 CMPDATA_STATIC structure
@@ -62,6 +70,24 @@ static int* g_class_structure;
6270 */
6371
6472 /*
73+ About fast field access
74+ When a public field name used only once with a class,
75+ the address of this field of an object is defined quickly when compiling.
76+ This logic is always true when there is only a class.
77+
78+ However, if there are more than two classes and the field name is used
79+ by only a class, this logic is true only when the BASIC code does not have
80+ error. If there is an error in BASIC code, this type of error cannot be
81+ found by compiler and when executing.
82+
83+ Therefore, only use this logic when the number of class is one, and/or
84+ OPTION FASTFIELD is defined.
85+
86+ This logic is useless for public method, because library must be always called
87+ before calling public method.
88+*/
89+
90+/*
6591 Local prototyping
6692 */
6793 char* obj_method(int method);
@@ -259,10 +285,36 @@ char* construct_class_structure(int class){
259285
260286 void delete_cmpdata_for_class(int class){
261287 int* record;
288+ int i;
289+ short pos;
262290 // Delete field/method data
263291 cmpdata_reset();
292+ pos=0; // # of position of public field
264293 while(record=cmpdata_find(CMPDATA_FIELD)){
265- cmpdata_delete(record);
294+ if ((record[0]&0xffff)==CMPTYPE_PUBLIC_FIELD) {
295+ pos++;
296+ i=record[1]; // Field name
297+ cmpdata_delete(record);
298+ // Construct or disable CMPDATA_FASTFIELD
299+ // Note that the sequence of public fields here is the same
300+ // as that in the function, construct_class_struction().
301+ cmpdata_reset();
302+ while(record=cmpdata_find(CMPDATA_FASTFIELD)){
303+ if (record[1]==i) break;
304+ }
305+ if (record) {
306+ // Multiple definition of field name
307+ // Clear data16 if the position is different
308+ if (pos!=(record[0]&0xffff)) record[0]&=0xffff0000;
309+ } else {
310+ // Previous CMPDATA_FASTFIELD not found
311+ // Create now one for fast field implementation
312+ g_temp=i;
313+ cmpdata_insert(CMPDATA_FASTFIELD,pos,&g_temp,1);
314+ }
315+ } else {
316+ cmpdata_delete(record);
317+ }
266318 cmpdata_reset();
267319 }
268320 // Delete longvar data
@@ -488,6 +540,8 @@ char* _obj_field(char mode){
488540 // $v0 contains the address of object.
489541 int i;
490542 char* err;
543+ int* record;
544+ char fastfield;
491545 do {
492546 i=check_var_name();
493547 if (i<65536) return ERR_SYNTAX;
@@ -506,11 +560,38 @@ char* _obj_field(char mode){
506560 // This is a string field. Raise 31st bit.
507561 i|=0x80000000;
508562 }
509- check_obj_space(2);
510- g_object[g_objpos++]=0x3C050000|((i>>16)&0x0000FFFF); // lui a1,xxxx
511- g_object[g_objpos++]=0x34A50000|(i&0x0000FFFF); // ori a1,a1,xxxx
512- // First and second arguments are address of object and field name, respectively.
513- call_quicklib_code(lib_obj_field,ASM_ADDU_A0_V0_ZERO);
563+ // Check if Fast Field Access can be used.
564+ cmpdata_reset();
565+ while(record=cmpdata_find(CMPDATA_FASTFIELD)){
566+ if (record[1]==(i&0x7FFFFFFF)) break;
567+ }
568+ if (!record) {
569+ // Record wasn't found
570+ fastfield=0;
571+ } else if (1!=g_num_classes && !g_option_fastfield) {
572+ // No fast field opttion
573+ fastfield=0;
574+ } else if (!(record[0]&0xffff)) {
575+ // The same field name used twice at the different positions
576+ fastfield=0;
577+ } else {
578+ // All requirements passed
579+ fastfield=1;
580+ }
581+ // Generate code here
582+ if (fastfield) {
583+ // Get field value in $v0 and address in $v1
584+ i=(record[0]&0xffff)*4;
585+ check_obj_space(2);
586+ g_object[g_objpos++]=0x24430004|i; // addiu v1,v0,xxxx
587+ g_object[g_objpos++]=0x8C620000; // lw v0,0(v1)
588+ } else {
589+ check_obj_space(2);
590+ g_object[g_objpos++]=0x3C050000|((i>>16)&0x0000FFFF); // lui a1,xxxx
591+ g_object[g_objpos++]=0x34A50000|(i&0x0000FFFF); // ori a1,a1,xxxx
592+ // First and second arguments are address of object and field name, respectively.
593+ call_quicklib_code(lib_obj_field,ASM_ADDU_A0_V0_ZERO);
594+ }
514595 // Check if "." follows
515596 if (g_source[g_srcpos]=='.') {
516597 // "." found. $v0 is adress of an object. See the field.
--- a/mips/megalopa/class.txt
+++ b/mips/megalopa/class.txt
@@ -56,9 +56,6 @@ METHOD命令で宣言されたメソッドは、すべてパブリックです
5656 メソッドが指定された場合、オブジェクト作成時に、このメソッドが呼ばれます。INIT
5757 メソッドに引数を与える事も可能です(引数は必須ではありません)。
5858
59-クラス中でオブジェクトへのポインターが必要な場合は、ARGS(-2)で取り出す事が出来
60-ます。
61-
6259 記述例(CLASS1.BASの名前で保存):
6360  FIELD PUBLIC TEST1,TEST2
6461  FIELD PRIVATE TEST3
--- a/mips/megalopa/compiler.c
+++ b/mips/megalopa/compiler.c
@@ -163,7 +163,7 @@ char* compile_line(void){
163163 printstr(resolve_label(g_line));
164164 return ERR_MULTIPLE_LABEL;
165165 }
166- if (!g_nolinenum) {
166+ if (!g_option_nolinenum) {
167167 check_obj_space(1);
168168 g_object[g_objpos++]=0x34160000|g_line; //ori s6,zero,xxxx;
169169 }
--- a/mips/megalopa/compiler.h
+++ b/mips/megalopa/compiler.h
@@ -213,7 +213,7 @@ extern int g_var_mem[ALLOC_BLOCK_NUM];
213213 extern unsigned short g_var_pointer[ALLOC_BLOCK_NUM];
214214 extern unsigned short g_var_size[ALLOC_BLOCK_NUM];
215215 extern char g_temp_area_used;
216-extern char g_nolinenum;
216+extern char g_option_nolinenum;
217217 extern int* g_heap_mem;
218218 extern int g_max_mem;
219219 extern char g_disable_break;
@@ -225,6 +225,8 @@ extern int g_long_name_var_num;
225225 extern char g_music_active;
226226 extern int g_class;
227227 extern int g_compiling_class;
228+extern unsigned char g_num_classes;
229+extern char g_option_fastfield;
228230 extern int g_temp;
229231
230232 /* Prototypes */
@@ -412,13 +414,14 @@ char* interrupt_statement();
412414 #define ERR_NO_INIT (char*)(g_err_str[28])
413415
414416 /* compile data type numbers */
415-#define CMPDATA_RESERVED 0
416-#define CMPDATA_USEVAR 1
417-#define CMPDATA_CLASS 2
418-#define CMPDATA_FIELD 3
419-#define CMPDATA_STATIC 4
420-#define CMPDATA_UNSOLVED 5
421-#define CMPDATA_TEMP 6
417+#define CMPDATA_RESERVED 0
418+#define CMPDATA_USEVAR 1
419+#define CMPDATA_CLASS 2
420+#define CMPDATA_FIELD 3
421+#define CMPDATA_STATIC 4
422+#define CMPDATA_UNSOLVED 5
423+#define CMPDATA_TEMP 6
424+#define CMPDATA_FASTFIELD 7
422425 // Sub types follow
423426 #define CMPTYPE_PUBLIC_FIELD 0
424427 #define CMPTYPE_PRIVATE_FIELD 1
--- a/mips/megalopa/debug.c
+++ b/mips/megalopa/debug.c
@@ -228,32 +228,28 @@ static const char initext[]=
228228 "#PRINT\n";
229229
230230 static const char bastext[]=
231+"USECLASS CLASS1,CLASS2\n"
232+"OPTION FASTFIELD\n"
231233 "CLS\n"
232-"LABEL TEST_:i=0/0\n"
233-"\n"
234-"\n"
234+"o=new(CLASS1)\n"
235+"o.T1=123\n"
236+"print o.T2()\n"
235237 "\n"
236238 "\n"
237239 "\n"
238240 "\n";
239241
240242 static const char class1text[]=
241-"STATIC T1\n"
242-"useclass CLASS2\n"
243-"method T3\n"
244-" return CLASS2::T2\n"
245-"method T5\n"
246-" return T1\n"
243+"FIELD T1\n"
244+"method T2\n"
245+" return T1+100\n"
247246 "\n"
248247 "\n";
249248
250249 static const char class2text[]=
251-"STATIC T2\n"
252-"useclass CLASS1\n"
253-"method T4\n"
254-" return CLASS1::T1\n"
250+"FIELD T3\n"
255251 "method T6\n"
256-" return T2\n"
252+" return T3+100\n"
257253 "\n"
258254 "\n"
259255 "\n"
--- a/mips/megalopa/file.c
+++ b/mips/megalopa/file.c
@@ -124,7 +124,8 @@ int compile_and_link_file(char* buff,char* appname){
124124 }
125125
126126 // Option initialization(s)
127- g_nolinenum=0;
127+ g_option_nolinenum=0;
128+ g_option_fastfield=0;
128129
129130 // Compile the file
130131 err=compile_file();
@@ -181,6 +182,7 @@ int compile_and_link_class(char* buff,int class){
181182 int data[2];
182183 unsigned short cwd_id;
183184 int* record;
185+ g_num_classes++;
184186 while(1){
185187 // Begin compiling class
186188 err=begin_compiling_class(class);
@@ -250,7 +252,10 @@ int compile_and_link_class(char* buff,int class){
250252
251253 int compile_and_link_main_file(char* buff,char* appname){
252254 int i;
255+ // Reset parameters
253256 g_compiling_class=0;
257+ g_num_classes=0;
258+ // Compile the file
254259 i=compile_and_link_file(buff,appname);
255260 if (i) return i;
256261 return 0;
--- a/mips/megalopa/globalvars.c
+++ b/mips/megalopa/globalvars.c
@@ -56,7 +56,7 @@ unsigned short g_var_size[ALLOC_BLOCK_NUM];
5656 char g_temp_area_used;
5757
5858 // Flag to use option nolinenum
59-char g_nolinenum;
59+char g_option_nolinenum;
6060
6161 // Heap area
6262 int* g_heap_mem;
@@ -88,8 +88,12 @@ char g_music_active;
8888
8989 // Class name being compiled
9090 int g_class;
91-// Flag to compile class file
91+// Flag (and class name) to compile class file
9292 int g_compiling_class;
93+// Number of classes used
94+unsigned char g_num_classes;
95+// OPTION FASTFIELD
96+char g_option_fastfield;
9397
9498 // General purpose integer used for asigning value with pointer
9599 int g_temp;
--- a/mips/megalopa/help.txt
+++ b/mips/megalopa/help.txt
@@ -635,11 +635,13 @@ SYSTEM関数及びSYSTEMステートメントを用いて、各種システム
635635 SYSTEM$(0)
636636 MachiKania バージョン文字列、"Zoea"等を返す。
637637 SYSTEM$(1)
638- MachiKania バージョン文字列、"1.0"等を返す。
638+ MachiKania バージョン文字列、"1.2"等を返す。
639639 SYSTEM$(2)
640- BASIC バージョン文字列、"KM-1200"等を返す。
640+ BASIC バージョン文字列、"KM-1208"等を返す。
641641 SYSTEM$(3)
642642 現在実行中のHEXファイル名、"ZOEA.HEX"等を返す。
643+SYSTEM(4)
644+ 現在実行中のCPUのクロック周波数を返す。
643645 SYSTEM(20)
644646 キャラクターディスプレイ横幅を返す。
645647 SYSTEM(21)
@@ -817,7 +819,7 @@ CALL x
817819 <ヒント>
818820 MachiKania ver 1.2 以降、FOR-NEXTループ、WHILE-WENDループ、DO-LOOPループの途中で、
819821 RETURN文が使えるようになりました。ただし、GOTO文でループの外に飛ぶと、予期せぬ結
820-果(機器のリセット等)を引き起こします。ただし、GOSUB文でサブルーチンを呼んだり、別の
822+果(機器のリセット等)を引き起こします。また、GOSUB文でサブルーチンを呼んだり、別の
821823 ループをネストして使う事は可能です。
822824
823825 ON GOTO分やON GOSUB文はサポートしていません。ただし、例えば次のように記述す
@@ -841,6 +843,7 @@ ON GOTO分やON GOSUB文はサポートしていません。ただし、例え
841843  ・オプション機能(OPTIONステートメント)を追加。
842844  ・アイドル機能(IDLEステートメント)を追加。
843845  ・EXEC()関数を追加。
846+ ・変数名などで、英数字に加えてアンダースコアーが使用可能に。
844847 ・KM-1302 2019年3月公開。
845848  ・オブジェクト指向プログラミングに対応
846849  ・args(0)で引数の数を取得できるようにした
--- a/mips/megalopa/statement.c
+++ b/mips/megalopa/statement.c
@@ -1568,7 +1568,9 @@ char* option_statement(){
15681568 while(1){
15691569 next_position();
15701570 if (nextCodeIs("NOLINENUM")) {
1571- g_nolinenum=1;
1571+ g_option_nolinenum=1;
1572+ } else if (nextCodeIs("FASTFIELD")) {
1573+ g_option_fastfield=1;
15721574 } else {
15731575 return ERR_SYNTAX;
15741576 }