今天上完课回来继续把昨天晚上剩下的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 else
15 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 else
27 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] int 3
19 [Line : 53] int 4
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] int 10
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] int 1
48 [Line : 60] neg
49 [Line : 60] int 1
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 null
101 [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 0
110 [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] int 0
117 [Line : 3] localref count
118 [Line : 3] assign
119 [Line : 3] pop
120 CONSTRUCTOR_GET_BASE_LINK :
121 [Line : 3] push null
122 [Line : 3] push temp
123 [Line : 3] equ
124 [Line : 3] jumptrue CONSTRUCTOR_LINK_DONE
125 [Line : 3] push count
126 [Line : 3] int 1
127 [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 0
133 [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] int 0
145 [Line : 5] localref X
146 [Line : 5] assign
147 [Line : 5] pop
148 [Line : 6] int 0
149 [Line : 6] localref Y
150 [Line : 6] assign
151 [Line : 6] pop
152 [Line : 8] func 4
153 [Line : 8] localref __get__
154 [Line : 8] assign
155 [Line : 8] pop
156 [Line : 18] func 5
157 [Line : 18] localref __set__
158 [Line : 18] assign
159 [Line : 18] pop
160 [Line : 30] func 6
161 [Line : 30] localref __add__
162 [Line : 30] assign
163 [Line : 30] pop
164 [Line : 35] func 7
165 [Line : 35] localref __sub__
166 [Line : 35] assign
167 [Line : 35] pop
168 [Line : 40] func 8
169 [Line : 40] localref tostr
170 [Line : 40] assign
171 [Line : 40] pop
172 [Line : 45] func 9
173 [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 end
180
181 func 4
182 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 1
197 [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] join
204 [Line : 15] string 。
205 [Line : 15] join
206 [Line : 15] push throw
207 [Line : 15] invoke 1
208 [Line : 15] pop
209 CHOOSE_END_0 :
210 FINISH_FUNCTION :
211 end
212
213 func 5
214 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 1
230 [Line : 22] ref len
231 [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 len
237 [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 len
245 [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] join
254 [Line : 27] string 。
255 [Line : 27] join
256 [Line : 27] push throw
257 [Line : 27] invoke 1
258 [Line : 27] pop
259 CHOOSE_END_0 :
260 FINISH_FUNCTION :
261 end
262
263 func 6
264 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"类型不匹配
274 [Line : 30] push b
275 [Line : 30] push Vector
276 [Line : 30] isfromctor
277 [Line : 30] jumpfalse PARAMCHECK_FAIL
278 [Line : 30] jump PARAMCHECK_SUCCESS
279 PARAMCHECK_FAIL :
280 [Line : 30] raiseerror
281 PARAMCHECK_SUCCESS :
282 [Line : 30] pop
283 [Line : 32] push Vector
284 [Line : 32] callctor
285 [Line : 32] push a
286 [Line : 32] field X
287 [Line : 32] push b
288 [Line : 32] field X
289 [Line : 32] add
290 [Line : 32] push a
291 [Line : 32] field Y
292 [Line : 32] push b
293 [Line : 32] field Y
294 [Line : 32] add
295 [Line : 32] copystack 2
296 [Line : 32] element constructor
297 [Line : 32] invoke 2
298 [Line : 32] pop
299 [Line : 32] result
300 [Line : 32] jump FINISH_FUNCTION
301 FINISH_FUNCTION :
302 end
303
304 func 7
305 a
306 b
307 begin
308 [Line : 35] string 参数"a"类型不匹配
309 [Line : 35] push a
310 [Line : 35] push Vector
311 [Line : 35] isfromctor
312 [Line : 35] jumpfalse PARAMCHECK_FAIL
313 [Line : 35] pop
314 [Line : 35] string 参数"b"类型不匹配
315 [Line : 35] push b
316 [Line : 35] push Vector
317 [Line : 35] isfromctor
318 [Line : 35] jumpfalse PARAMCHECK_FAIL
319 [Line : 35] jump PARAMCHECK_SUCCESS
320 PARAMCHECK_FAIL :
321 [Line : 35] raiseerror
322 PARAMCHECK_SUCCESS :
323 [Line : 35] pop
324 [Line : 37] push Vector
325 [Line : 37] callctor
326 [Line : 37] push a
327 [Line : 37] field X
328 [Line : 37] push b
329 [Line : 37] field X
330 [Line : 37] sub
331 [Line : 37] push a
332 [Line : 37] field Y
333 [Line : 37] push b
334 [Line : 37] field Y
335 [Line : 37] sub
336 [Line : 37] copystack 2
337 [Line : 37] element constructor
338 [Line : 37] invoke 2
339 [Line : 37] pop
340 [Line : 37] result
341 [Line : 37] jump FINISH_FUNCTION
342 FINISH_FUNCTION :
343 end
344
345 func 8
346 begin
347 [Line : 42] string (
348 [Line : 42] push X
349 [Line : 42] join
350 [Line : 42] string ,
351 [Line : 42] join
352 [Line : 42] push Y
353 [Line : 42] join
354 [Line : 42] string )
355 [Line : 42] join
356 [Line : 42] result
357 [Line : 42] jump FINISH_FUNCTION
358 FINISH_FUNCTION :
359 end
360
361 func 9
362 x
363 y
364 begin
365 [Line : 47] push x
366 [Line : 47] ref X
367 [Line : 47] assign
368 [Line : 47] pop
369 [Line : 48] push y
370 [Line : 48] ref Y
371 [Line : 48] assign
372 [Line : 48] pop
373 FINISH_FUNCTION :
374 end
375
posted on 2008-05-11 21:37
陈梓瀚(vczh) 阅读(1513)
评论(4) 编辑 收藏 引用 所属分类:
Vczh Free Script