Vczh Free Script 2.0中namespace和大部分操作符過載完成!
阿新 • • 發佈:2018-12-27
今天上完課回來繼續把昨天晚上剩下的using字句完成。使用Syngram寫編譯器真是舒服啊,直接在程式碼裡面加兩條推導式就完成了。昨天發現了InsertEnv指令的bug以後,改過來了。不過InsertEnv不能用在using身上,只好另外寫了一個UsingEnv指令,把環境以及上游的連結串列而不是多個環境插進當前的環境中。這裡展示了class和namespace是如何通過閉包(函式)來實現的,以及他們的構造過程。
class以及namespace都是通過在return的跳轉目標後新增指令而保證return結束但是不修改class和namespace表示式的返回值。
class函式的引數是父類的構造子,class函式在所有程式碼之前首先構造好一個父類的連結串列,然後通過InsertEnv將這個表引用到自己身上,從而實現了正確的scope。然後讓constructor為空函式。ClassName.new()的時候首先執行class函式(使用callctor而不是invoke來自動找到父類並新增到引數中),然後複製堆疊,獲取constructor並呼叫,最後pop掉constructor函式的返回值就構造了一個完整的物件了。
namespace也是類似。class返回的是this,namespace返回的是_env。實際上_env和this對於這兩個函式來說代表的都是相同的物件——函式內部的上下文。上下文是一個符號表,符號表可以用Table.Member的形式訪問。構造namespace的時候,首先植入這個閉包,然後用空函式呼叫,把結果傳出來。
程式碼:
1 VectorSpace=namespace 2 {
3 Vector=class()
4 {
5 local X=0;
6 local Y=0;
7 8 local __get__=func(name)
9 {
10 if(name=="length")
11 {
12 return sqrt(X*X+Y*Y);
13 }
14 else15 throw("找不到"++name++"。");
16 };
17 18 local __set__=func(name,value)
19 {
20 if(name=="length")
21 {
22 len=sqrt(X*X+Y*Y);
23 X=X*value/len;
24 Y=Y*value/len;
25 }
26 else27 throw("找不到"++name++"。");
28 };
29 30 local __add__=func({Vector}a,{Vector}b)
31 {
32 return Vector.new(a.X +b.X,a.Y+b.Y);
33 };
34 35 local __sub__=func({Vector}a,{Vector}b)
36 {
37 return Vector.new(a.X-b.X,a.Y-b.Y);
38 };
39 40 local tostr=func()
41 {
42 return"("++X++","++Y++")";
43 };
44 45 local constructor=func(x,y)
46 {
47 X=x;
48 Y=y;
49 };
50 };
51 };
52 53 v1=VectorSpace.Vector.new(3,4);
54 writeln(v1.length);
55 v1.length=10;
56 writeln(v1.tostr());
57 58 using VectorSpace;
59 60 v2=Vector.new(-1,1);
61 writeln((v1+v2).tostr());
62 writeln((v1-v2).tostr()); 指令: 1 Entry : 1 2 3 func 0 4 begin
5 FINISH_FUNCTION :
6 end 7 8 func 1 9 begin
10 [Line : 1] func 2 11 [Line : 1] invoke 0 12 [Line : 1] ref VectorSpace
13 [Line : 1] assign
14 [Line : 1] pop
15 [Line : 53] push VectorSpace
16 [Line : 53] field Vector
17 [Line : 53] callctor
18 [Line : 53] int3 19 [Line : 53] int4 20 [Line : 53] copystack 2 21 [Line : 53] element constructor
22 [Line : 53] invoke 2 23 [Line : 53] pop
24 [Line : 53] ref v1
25 [Line : 53] assign
26 [Line : 53] pop
27 [Line : 54] push v1
28 [Line : 54] field length
29 [Line : 54] push writeln
30 [Line : 54] invoke 1 31 [Line : 54] pop
32 [Line : 55] int10 33 [Line : 55] push v1
34 [Line : 55] fieldref length
35 [Line : 55] assign
36 [Line : 55] pop
37 [Line : 56] push v1
38 [Line : 56] field tostr
39 [Line : 56] invoke 0 40 [Line : 56] push writeln
41 [Line : 56] invoke 1 42 [Line : 56] pop
43 [Line : 58] push VectorSpace
44 [Line : 58] usingenv
45 [Line : 60] push Vector
46 [Line : 60] callctor
47 [Line : 60] int1 48 [Line : 60] neg
49 [Line : 60] int1 50 [Line : 60] copystack 2 51 [Line : 60] element constructor
52 [Line : 60] invoke 2 53 [Line : 60] pop
54 [Line : 60] ref v2
55 [Line : 60] assign
56 [Line : 60] pop
57 [Line : 61] push v1
58 [Line : 61] push v2
59 [Line : 61] add
60 [Line : 61] field tostr
61 [Line : 61] invoke 0 62 [Line : 61] push writeln
63 [Line : 61] invoke 1 64 [Line : 61] pop
65 [Line : 62] push v1
66 [Line : 62] push v2
67 [Line : 62] sub 68 [Line : 62] field tostr
69 [Line : 62] invoke 0 70 [Line : 62] push writeln
71 [Line : 62] invoke 1 72 [Line : 62] pop
73 FINISH_FUNCTION :
74 end 75 76 func 2 77 begin
78 [Line : 3] push null 79 [Line : 3] func 3 80 [Line : 3] makector
81 [Line : 3] ref Vector
82 [Line : 3] assign
83 [Line : 3] pop
84 FINISH_FUNCTION :
85 [Line : 1] push _env
86 [Line : 1] result
87 end 88 89 func 3 90 begin
91 [Line : 3] func 0 92 [Line : 3] localref constructor
93 [Line : 3] assign
94 [Line : 3] pop
95 [Line : 3] push null 96 [Line : 3] push ctor
97 [Line : 3] ctorbase
98 [Line : 3] equ
99 [Line : 3] jumpfalse CONSTRUCTOR_CTOR_NOT_NULL
100 [Line : 3] push null101 [Line : 3] fixedref base
102 [Line : 3] assign
103 [Line : 3] pop
104 [Line : 3] jump CONSTRUCTOR_FINISH
105 CONSTRUCTOR_CTOR_NOT_NULL :
106 [Line : 3] push ctor
107 [Line : 3] ctorbase
108 [Line : 3] callctor
109 [Line : 3] copystack 0110 [Line : 3] fixedref base
111 [Line : 3] assign
112 [Line : 3] pop
113 [Line : 3] localref temp
114 [Line : 3] assign
115 [Line : 3] pop
116 [Line : 3] int0117 [Line : 3] localref count
118 [Line : 3] assign
119 [Line : 3] pop
120 CONSTRUCTOR_GET_BASE_LINK :
121 [Line : 3] push null122 [Line : 3] push temp
123 [Line : 3] equ
124 [Line : 3] jumptrue CONSTRUCTOR_LINK_DONE
125 [Line : 3] push count
126 [Line : 3] int1127 [Line : 3] add
128 [Line : 3] localref count
129 [Line : 3] assign
130 [Line : 3] pop
131 [Line : 3] push temp
132 [Line : 3] copystack 0133 [Line : 3] element base
134 [Line : 3] localref temp
135 [Line : 3] assign
136 [Line : 3] pop
137 [Line : 3] jump CONSTRUCTOR_GET_BASE_LINK
138 CONSTRUCTOR_LINK_DONE :
139 [Line : 3] push count
140 [Line : 3] insertenv
141 [Line : 3] remove count
142 [Line : 3] remove temp
143 CONSTRUCTOR_FINISH :
144 [Line : 5] int0145 [Line : 5] localref X
146 [Line : 5] assign
147 [Line : 5] pop
148 [Line : 6] int0149 [Line : 6] localref Y
150 [Line : 6] assign
151 [Line : 6] pop
152 [Line : 8] func 4153 [Line : 8] localref __get__
154 [Line : 8] assign
155 [Line : 8] pop
156 [Line : 18] func 5157 [Line : 18] localref __set__
158 [Line : 18] assign
159 [Line : 18] pop
160 [Line : 30] func 6161 [Line : 30] localref __add__
162 [Line : 30] assign
163 [Line : 30] pop
164 [Line : 35] func 7165 [Line : 35] localref __sub__
166 [Line : 35] assign
167 [Line : 35] pop
168 [Line : 40] func 8169 [Line : 40] localref tostr
170 [Line : 40] assign
171 [Line : 40] pop
172 [Line : 45] func 9173 [Line : 45] localref constructor
174 [Line : 45] assign
175 [Line : 45] pop
176 FINISH_FUNCTION :
177 [Line : 3] push this
178 [Line : 3] result
179 end180 181 func 4182 name
183 begin
184 [Line : 10] push name
185 [Line : 10] string length
186 [Line : 10] equ
187 [Line : 10] jumpfalse CHOOSE_ELSE_0
188 [Line : 12] push X
189 [Line : 12] push X
190 [Line : 12] mul
191 [Line : 12] push Y
192 [Line : 12] push Y
193 [Line : 12] mul
194 [Line : 12] add
195 [Line : 12] push sqrt
196 [Line : 12] invoke 1197 [Line : 12] result
198 [Line : 12] jump FINISH_FUNCTION
199 [Line : 10] jump CHOOSE_END_0
200 CHOOSE_ELSE_0 :
201 [Line : 15] string 找不到
202 [Line : 15] push name
203 [Line : 15] join204 [Line : 15] string 。
205 [Line : 15] join206 [Line : 15] push throw
207 [Line : 15] invoke 1208 [Line : 15] pop
209 CHOOSE_END_0 :
210 FINISH_FUNCTION :
211 end212 213 func 5214 name
215 value
216 begin
217 [Line : 20] push name
218 [Line : 20] string length
219 [Line : 20] equ
220 [Line : 20] jumpfalse CHOOSE_ELSE_0
221 [Line : 22] push X
222 [Line : 22] push X
223 [Line : 22] mul
224 [Line : 22] push Y
225 [Line : 22] push Y
226 [Line : 22] mul
227 [Line : 22] add
228 [Line : 22] push sqrt
229 [Line : 22] invoke 1230 [Line : 22] ref len231 [Line : 22] assign
232 [Line : 22] pop
233 [Line : 23] push X
234 [Line : 23] push value
235 [Line : 23] mul
236 [Line : 23] push len237 [Line : 23] div
238 [Line : 23] ref X
239 [Line : 23] assign
240 [Line : 23] pop
241 [Line : 24] push Y
242 [Line : 24] push value
243 [Line : 24] mul
244 [Line : 24] push len245 [Line : 24] div
246 [Line : 24] ref Y
247 [Line : 24] assign
248 [Line : 24] pop
249 [Line : 20] jump CHOOSE_END_0
250 CHOOSE_ELSE_0 :
251 [Line : 27] string 找不到
252 [Line : 27] push name
253 [Line : 27] join254 [Line : 27] string 。
255 [Line : 27] join256 [Line : 27] push throw
257 [Line : 27] invoke 1258 [Line : 27] pop
259 CHOOSE_END_0 :
260 FINISH_FUNCTION :
261 end262 263 func 6264 a
265 b
266 begin
267 [Line : 30] string 引數"a"型別不匹配
268 [Line : 30] push a
269 [Line : 30] push Vector
270 [Line : 30] isfromctor
271 [Line : 30] jumpfalse PARAMCHECK_FAIL
272 [Line : 30] pop
273 [Line : 30] string 引數"b
class以及namespace都是通過在return的跳轉目標後新增指令而保證return結束但是不修改class和namespace表示式的返回值。
class函式的引數是父類的構造子,class函式在所有程式碼之前首先構造好一個父類的連結串列,然後通過InsertEnv將這個表引用到自己身上,從而實現了正確的scope。然後讓constructor為空函式。ClassName.new()的時候首先執行class函式(使用callctor而不是invoke來自動找到父類並新增到引數中),然後複製堆疊,獲取constructor並呼叫,最後pop掉constructor函式的返回值就構造了一個完整的物件了。
namespace也是類似。class返回的是this,namespace返回的是_env。實際上_env和this對於這兩個函式來說代表的都是相同的物件——函式內部的上下文。上下文是一個符號表,符號表可以用Table.Member的形式訪問。構造namespace的時候,首先植入這個閉包,然後用空函式呼叫,把結果傳出來。
程式碼:
1
3 Vector=class()
4 {
5 local X=0;
6 local Y=0;
7 8 local __get__=func(name)
9 {
10 if(name=="length")
11 {
12 return sqrt(X*X+Y*Y);
13 }
14 else15 throw("找不到"++name++"。");
16 };
17 18 local __set__=func(name,value)
20 if(name=="length")
21 {
22 len=sqrt(X*X+Y*Y);
23 X=X*value/len;
24 Y=Y*value/len;
25 }
26 else27 throw("找不到"++name++"。");
28 };
29 30 local __add__=func({Vector}a,{Vector}b)
31 {
32 return Vector.new(a.X
33 };
34 35 local __sub__=func({Vector}a,{Vector}b)
36 {
37 return Vector.new(a.X-b.X,a.Y-b.Y);
38 };
39 40 local tostr=func()
41 {
42 return"("++X++","++Y++")";
43 };
44 45 local constructor=func(x,y)
46 {
47 X=x;
48 Y=y;
49 };
50 };
51 };
52 53 v1=VectorSpace.Vector.new(3,4);
54 writeln(v1.length);
55 v1.length=10;
56 writeln(v1.tostr());
57 58 using VectorSpace;
59 60 v2=Vector.new(-1,1);
61 writeln((v1+v2).tostr());
62 writeln((v1-v2).tostr()); 指令: 1 Entry : 1 2 3 func 0 4 begin
5 FINISH_FUNCTION :
6 end 7 8 func 1 9 begin
10 [Line : 1] func 2 11 [Line : 1] invoke 0 12 [Line : 1] ref VectorSpace
13 [Line : 1] assign
14 [Line : 1] pop
15 [Line : 53] push VectorSpace
16 [Line : 53] field Vector
17 [Line : 53] callctor
18 [Line : 53] int3 19 [Line : 53] int4 20 [Line : 53] copystack 2 21 [Line : 53] element constructor
22 [Line : 53] invoke 2 23 [Line : 53] pop
24 [Line : 53] ref v1
25 [Line : 53] assign
26 [Line : 53] pop
27 [Line : 54] push v1
28 [Line : 54] field length
29 [Line : 54] push writeln
30 [Line : 54] invoke 1 31 [Line : 54] pop
32 [Line : 55] int10 33 [Line : 55] push v1
34 [Line : 55] fieldref length
35 [Line : 55] assign
36 [Line : 55] pop
37 [Line : 56] push v1
38 [Line : 56] field tostr
39 [Line : 56] invoke 0 40 [Line : 56] push writeln
41 [Line : 56] invoke 1 42 [Line : 56] pop
43 [Line : 58] push VectorSpace
44 [Line : 58] usingenv
45 [Line : 60] push Vector
46 [Line : 60] callctor
47 [Line : 60] int1 48 [Line : 60] neg
49 [Line : 60] int1 50 [Line : 60] copystack 2 51 [Line : 60] element constructor
52 [Line : 60] invoke 2 53 [Line : 60] pop
54 [Line : 60] ref v2
55 [Line : 60] assign
56 [Line : 60] pop
57 [Line : 61] push v1
58 [Line : 61] push v2
59 [Line : 61] add
60 [Line : 61] field tostr
61 [Line : 61] invoke 0 62 [Line : 61] push writeln
63 [Line : 61] invoke 1 64 [Line : 61] pop
65 [Line : 62] push v1
66 [Line : 62] push v2
67 [Line : 62] sub 68 [Line : 62] field tostr
69 [Line : 62] invoke 0 70 [Line : 62] push writeln
71 [Line : 62] invoke 1 72 [Line : 62] pop
73 FINISH_FUNCTION :
74 end 75 76 func 2 77 begin
78 [Line : 3] push null 79 [Line : 3] func 3 80 [Line : 3] makector
81 [Line : 3] ref Vector
82 [Line : 3] assign
83 [Line : 3] pop
84 FINISH_FUNCTION :
85 [Line : 1] push _env
86 [Line : 1] result
87 end 88 89 func 3 90 begin
91 [Line : 3] func 0 92 [Line : 3] localref constructor
93 [Line : 3] assign
94 [Line : 3] pop
95 [Line : 3] push null 96 [Line : 3] push ctor
97 [Line : 3] ctorbase
98 [Line : 3] equ
99 [Line : 3] jumpfalse CONSTRUCTOR_CTOR_NOT_NULL
100 [Line : 3] push null101 [Line : 3] fixedref base
102 [Line : 3] assign
103 [Line : 3] pop
104 [Line : 3] jump CONSTRUCTOR_FINISH
105 CONSTRUCTOR_CTOR_NOT_NULL :
106 [Line : 3] push ctor
107 [Line : 3] ctorbase
108 [Line : 3] callctor
109 [Line : 3] copystack 0110 [Line : 3] fixedref base
111 [Line : 3] assign
112 [Line : 3] pop
113 [Line : 3] localref temp
114 [Line : 3] assign
115 [Line : 3] pop
116 [Line : 3] int0117 [Line : 3] localref count
118 [Line : 3] assign
119 [Line : 3] pop
120 CONSTRUCTOR_GET_BASE_LINK :
121 [Line : 3] push null122 [Line : 3] push temp
123 [Line : 3] equ
124 [Line : 3] jumptrue CONSTRUCTOR_LINK_DONE
125 [Line : 3] push count
126 [Line : 3] int1127 [Line : 3] add
128 [Line : 3] localref count
129 [Line : 3] assign
130 [Line : 3] pop
131 [Line : 3] push temp
132 [Line : 3] copystack 0133 [Line : 3] element base
134 [Line : 3] localref temp
135 [Line : 3] assign
136 [Line : 3] pop
137 [Line : 3] jump CONSTRUCTOR_GET_BASE_LINK
138 CONSTRUCTOR_LINK_DONE :
139 [Line : 3] push count
140 [Line : 3] insertenv
141 [Line : 3] remove count
142 [Line : 3] remove temp
143 CONSTRUCTOR_FINISH :
144 [Line : 5] int0145 [Line : 5] localref X
146 [Line : 5] assign
147 [Line : 5] pop
148 [Line : 6] int0149 [Line : 6] localref Y
150 [Line : 6] assign
151 [Line : 6] pop
152 [Line : 8] func 4153 [Line : 8] localref __get__
154 [Line : 8] assign
155 [Line : 8] pop
156 [Line : 18] func 5157 [Line : 18] localref __set__
158 [Line : 18] assign
159 [Line : 18] pop
160 [Line : 30] func 6161 [Line : 30] localref __add__
162 [Line : 30] assign
163 [Line : 30] pop
164 [Line : 35] func 7165 [Line : 35] localref __sub__
166 [Line : 35] assign
167 [Line : 35] pop
168 [Line : 40] func 8169 [Line : 40] localref tostr
170 [Line : 40] assign
171 [Line : 40] pop
172 [Line : 45] func 9173 [Line : 45] localref constructor
174 [Line : 45] assign
175 [Line : 45] pop
176 FINISH_FUNCTION :
177 [Line : 3] push this
178 [Line : 3] result
179 end180 181 func 4182 name
183 begin
184 [Line : 10] push name
185 [Line : 10] string length
186 [Line : 10] equ
187 [Line : 10] jumpfalse CHOOSE_ELSE_0
188 [Line : 12] push X
189 [Line : 12] push X
190 [Line : 12] mul
191 [Line : 12] push Y
192 [Line : 12] push Y
193 [Line : 12] mul
194 [Line : 12] add
195 [Line : 12] push sqrt
196 [Line : 12] invoke 1197 [Line : 12] result
198 [Line : 12] jump FINISH_FUNCTION
199 [Line : 10] jump CHOOSE_END_0
200 CHOOSE_ELSE_0 :
201 [Line : 15] string 找不到
202 [Line : 15] push name
203 [Line : 15] join204 [Line : 15] string 。
205 [Line : 15] join206 [Line : 15] push throw
207 [Line : 15] invoke 1208 [Line : 15] pop
209 CHOOSE_END_0 :
210 FINISH_FUNCTION :
211 end212 213 func 5214 name
215 value
216 begin
217 [Line : 20] push name
218 [Line : 20] string length
219 [Line : 20] equ
220 [Line : 20] jumpfalse CHOOSE_ELSE_0
221 [Line : 22] push X
222 [Line : 22] push X
223 [Line : 22] mul
224 [Line : 22] push Y
225 [Line : 22] push Y
226 [Line : 22] mul
227 [Line : 22] add
228 [Line : 22] push sqrt
229 [Line : 22] invoke 1230 [Line : 22] ref len231 [Line : 22] assign
232 [Line : 22] pop
233 [Line : 23] push X
234 [Line : 23] push value
235 [Line : 23] mul
236 [Line : 23] push len237 [Line : 23] div
238 [Line : 23] ref X
239 [Line : 23] assign
240 [Line : 23] pop
241 [Line : 24] push Y
242 [Line : 24] push value
243 [Line : 24] mul
244 [Line : 24] push len245 [Line : 24] div
246 [Line : 24] ref Y
247 [Line : 24] assign
248 [Line : 24] pop
249 [Line : 20] jump CHOOSE_END_0
250 CHOOSE_ELSE_0 :
251 [Line : 27] string 找不到
252 [Line : 27] push name
253 [Line : 27] join254 [Line : 27] string 。
255 [Line : 27] join256 [Line : 27] push throw
257 [Line : 27] invoke 1258 [Line : 27] pop
259 CHOOSE_END_0 :
260 FINISH_FUNCTION :
261 end262 263 func 6264 a
265 b
266 begin
267 [Line : 30] string 引數"a"型別不匹配
268 [Line : 30] push a
269 [Line : 30] push Vector
270 [Line : 30] isfromctor
271 [Line : 30] jumpfalse PARAMCHECK_FAIL
272 [Line : 30] pop
273 [Line : 30] string 引數"b