BASIC compiler/interpreter for PIC32MX/MZ-80K
Révision | 243d3a37aeba7ab834b127091ab32f11c1b82782 (tree) |
---|---|
l'heure | 2019-02-17 17:29:13 |
Auteur | Katsumi <kmorimatsu@sour...> |
Commiter | Katsumi |
Restrict using previously deleted memory for permanent purpose.
@@ -119,8 +119,8 @@ DELETEするだけではこれらの領域は破棄されません。その場 | ||
119 | 119 | <フィールドへのアクセス方法> |
120 | 120 | |
121 | 121 | パブリックフィールドへアクセスする場合は、オブジェクトを含む変数に続けて「.」と |
122 | -フィールド名を記述して下さい。フィールドが文字列の場合は「$」を後ろに付けて下さ | |
123 | -い。 | |
122 | +フィールド名を記述して下さい。フィールドが文字列の場合は「$」を、実数の場合は | |
123 | +「#」を、それぞれ後ろに付けて下さい。 | |
124 | 124 | |
125 | 125 | 記述例: |
126 | 126 | USECLASS CLASS1 |
@@ -132,8 +132,8 @@ DELETEするだけではこれらの領域は破棄されません。その場 | ||
132 | 132 | |
133 | 133 | パブリックメソッドへアクセスする場合は、オブジェクトを含む変数に続けて「.」と |
134 | 134 | メソッド名、続けて「( )」を記述して下さい。メソッドが戻り値として文字列を返す場 |
135 | -合、メソッド名の後ろに「$」を付けて下さい。メソッドは関数と同じ扱いですが、戻 | |
136 | -り値を利用しない場合は、CALL命令により呼び出す事も出来ます。 | |
135 | +合、メソッド名の後ろに「$」を付けて下さい(実数の場合は「#」)。メソッドは関数 | |
136 | +と同じ扱いですが、戻り値を利用しない場合は、CALL命令により呼び出す事も出来ます。 | |
137 | 137 | |
138 | 138 | CALL x |
139 | 139 | xで指定されたオブジェクトのメソッドを呼び出す。 |
@@ -229,14 +229,21 @@ static const char initext[]= | ||
229 | 229 | |
230 | 230 | |
231 | 231 | static const char bastext[]= |
232 | -"USECLASS CLASS1,CLASS2\n" | |
232 | +"USECLASS CLASS1\n" | |
233 | 233 | "CLS\n" |
234 | -"CLASS1::T1=123\n" | |
235 | -"CLASS2::T2=456\n" | |
236 | -"print CLASS1::T3(),\n" | |
237 | -"print CLASS2::T4(),\n" | |
238 | -"print CLASS1::T5(),\n" | |
239 | -"print CLASS2::T6(),\n" | |
234 | +"dim o(9)\n" | |
235 | +"for j=1 to 100\n" | |
236 | +" cursor 0,0\n" | |
237 | +" for i=1 to 9\n" | |
238 | +" o(i)=new(CLASS1)\n" | |
239 | +" next\n" | |
240 | +" for i=1 to 9\n" | |
241 | +" a=o(i)\n" | |
242 | +" print hex$(a),\n" | |
243 | +" delete a\n" | |
244 | +" next\n" | |
245 | +"next\n" | |
246 | +"\n" | |
240 | 247 | "\n" |
241 | 248 | "\n"; |
242 | 249 |
@@ -723,6 +723,10 @@ FIELD [PUBLIC] x[,y[,z[, ... ]]] | ||
723 | 723 | FIELD PRIVATE x[,y[,z[, ... ]]] |
724 | 724 | クラスファイル中で、プライベートフィールドを宣言する。x,y,z等はフィールド |
725 | 725 | 名を6文字以内の英数字で指定。 |
726 | +STATIC [PUBLIC] x[,y[,z[, ... ]]] | |
727 | + クラスファイル中で、パブリックスなタティック変数を宣言する。"PUBLIC"は省略可。 | |
728 | +STATIC PRIVATE x[,y[,z[, ... ]]] | |
729 | + クラスファイル中で、プライベートなスタティック変数を宣言する。USEVARと同じ。 | |
726 | 730 | METHOD x |
727 | 731 | クラスファイル中で、メソッドを宣言する。xは、メソッド名を6文字以内の英 |
728 | 732 | 数字で指定。 |
@@ -735,10 +739,10 @@ CALL x | ||
735 | 739 | xで指定されたオブジェクトのメソッドを呼び出す。 |
736 | 740 | |
737 | 741 | <ヒント> |
738 | -FOR-NEXTループ、WHILE-WENDループ、DO-LOOPループの途中で、GOTO文でループの | |
739 | -外に飛んだり、RETURN文を実行したりすると、予期せぬ結果(機器のリセット等)を | |
740 | -引き起こします。ただし、GOSUB文でサブルーチンを呼んだり、別のループをネスト | |
741 | -して使う事は可能です。 | |
742 | +KM-1302以降、FOR-NEXTループ、WHILE-WENDループ、DO-LOOPループの途中で、 | |
743 | +RETURN文が使えるようになりました。ただし、GOTO文でループの外に飛ぶと、予期せぬ結 | |
744 | +果(機器のリセット等)を引き起こします。ただし、GOSUB文でサブルーチンを呼んだり、別の | |
745 | +ループをネストして使う事は可能です。 | |
742 | 746 | |
743 | 747 | ON GOTO分やON GOSUB文はサポートしていません。ただし、例えば次のように記述す |
744 | 748 | ることで、同様の動作をさせることは可能です。 |
@@ -32,15 +32,17 @@ static int g_deleted_num; | ||
32 | 32 | static int g_deleted_pointer[DELETE_LIST_SIZE]; |
33 | 33 | static int g_deleted_size[DELETE_LIST_SIZE]; |
34 | 34 | |
35 | - | |
36 | -#define register_deleted_block(x,y) \ | |
37 | - do {\ | |
38 | - if (g_deleted_num<DELETE_LIST_SIZE) {\ | |
39 | - g_deleted_pointer[g_deleted_num]=(x);\ | |
40 | - g_deleted_size[g_deleted_num]=(y);\ | |
41 | - g_deleted_num++;\ | |
42 | - }\ | |
43 | - } while(0) | |
35 | +void register_deleted_block(int pointer, int size){ | |
36 | + // There is maximum | |
37 | + if (DELETE_LIST_SIZE<=g_deleted_num) return; | |
38 | + if (g_deleted_num) { | |
39 | + // Avoid duplication | |
40 | + if (g_deleted_pointer[g_deleted_num-1]==pointer) return; | |
41 | + } | |
42 | + g_deleted_pointer[g_deleted_num]=pointer; | |
43 | + g_deleted_size[g_deleted_num]=size; | |
44 | + g_deleted_num++; | |
45 | +} | |
44 | 46 | |
45 | 47 | void set_free_area(void* begin, void* end){ |
46 | 48 | // Initialize heap area |
@@ -106,21 +108,26 @@ void* _alloc_memory_main(int size, int var_num){ | ||
106 | 108 | g_var_size[var_num]=0; |
107 | 109 | g_var_pointer[var_num]=0; |
108 | 110 | while(1){ |
109 | - // Try the block previously deleted | |
110 | - candidate=0; | |
111 | - while(g_deleted_num){ | |
112 | - // Check if the last deleted block fits | |
113 | - // If not, these cannot be used anymore | |
114 | - g_deleted_num--; | |
115 | - if (size<=g_deleted_size[g_deleted_num]) { | |
116 | - candidate=g_deleted_pointer[g_deleted_num]; | |
111 | + // Try the block previously deleted, not for temporary block. | |
112 | + // This is for fast allocation of memory for class object. | |
113 | + // Note that the temporary areas can be invaded for following purpose | |
114 | + // because these are temporary ones. | |
115 | + if (var_num<26 || ALLOC_VAR_NUM<=var_num) { | |
116 | + candidate=0; | |
117 | + while(g_deleted_num){ | |
118 | + // Check if the last deleted block fits | |
119 | + // If not, these cannot be used anymore | |
120 | + g_deleted_num--; | |
121 | + if (size<=g_deleted_size[g_deleted_num]) { | |
122 | + candidate=g_deleted_pointer[g_deleted_num]; | |
123 | + break; | |
124 | + } | |
125 | + } | |
126 | + if (candidate || g_deleted_num) { | |
127 | + // Candidate found | |
117 | 128 | break; |
118 | 129 | } |
119 | 130 | } |
120 | - if (candidate || g_deleted_num) { | |
121 | - // Candidate found | |
122 | - break; | |
123 | - } | |
124 | 131 | // Try the block after last block |
125 | 132 | candidate=0; |
126 | 133 | for(i=0;i<ALLOC_BLOCK_NUM;i++){ |
@@ -193,7 +200,7 @@ void free_non_temp_str(char* str){ | ||
193 | 200 | } |
194 | 201 | } |
195 | 202 | for(i=ALLOC_VAR_NUM;i<ALLOC_BLOCK_NUM;i++){ |
196 | - if (g_var_pointer[i]==pointer && g_var_size[i]) { | |
203 | + if (g_var_pointer[i]==pointer) { | |
197 | 204 | if (g_var_size[i] && g_var_mem[i]==(int)str) { |
198 | 205 | register_deleted_block(pointer,g_var_size[i]); |
199 | 206 | g_var_size[i]=0; |