1. 程式人生 > >Vczh Free Script 2.0中namespace和大部分操作符過載完成!

Vczh Free Script 2.0中namespace和大部分操作符過載完成!

    今天上完課回來繼續把昨天晚上剩下的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