随笔-341  评论-2670  文章-0  trackbacks-0
    今天上完课回来继续把昨天晚上剩下的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) 阅读(1487) 评论(4)  编辑 收藏 引用 所属分类: Vczh Free Script

评论:
# re: Vczh Free Script 2.0中namespace和大部分操作符重载完成! 2008-05-12 00:45 | Gohan
Syngram是你以前的作品吗?我对编译还没上手  回复  更多评论
  
# re: Vczh Free Script 2.0中namespace和大部分操作符重载完成! 2008-05-12 06:46 | 陈梓瀚(vczh)
是  回复  更多评论
  
# re: Vczh Free Script 2.0中namespace和大部分操作符重载完成![未登录] 2008-05-13 04:16 | Alex
今天上完课回来继续把昨天晚上身下的using字句完成


#- - 你把using压身下了?  回复  更多评论
  
# re: Vczh Free Script 2.0中namespace和大部分操作符重载完成! 2008-05-15 01:07 | 买书网
写编译器不太好上手。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理