• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
                如上一篇文章所說(shuō),Vczh Library++3.0的NativeX語(yǔ)言實(shí)現(xiàn)了計(jì)劃的所有泛型語(yǔ)法。讓我們來(lái)看一個(gè)簡(jiǎn)單的例子:我們?yōu)轭愋蛯?xiě)一個(gè)Equals函數(shù)。我們可以為普通類型,譬如int32寫(xiě)一個(gè)Equals函數(shù)。我們有Vector<T>類型,只要T類型擁有一個(gè)Equals函數(shù),那么Vector<T>顯然也可以有Equals函數(shù)。問(wèn)題來(lái)了,我們?cè)赩ectorEquals<T>函數(shù)里面怎么知道T的Equals函數(shù)究竟是那一個(gè)呢?在這里我們用concept和instance,其實(shí)也就是haskell的type class在C語(yǔ)言上僅有的一種形式,來(lái)表達(dá)。

                首先我們定義一個(gè)叫Eq的concept,里面包含Equals和NotEquals兩個(gè)函數(shù)的原型。這兩個(gè)函數(shù)規(guī)定了參數(shù)的類型和返回值類型:
            1 concept T : Eq
            2 {
            3     Equals = function bool(T, T);
            4     NotEquals = function bool(T, T);
            5 }

                其次,我們?yōu)閕nt32實(shí)現(xiàn)這兩個(gè)函數(shù)。實(shí)現(xiàn)的方法很直接,首先我們寫(xiě)IntEquals和IntNotEquals兩個(gè)函數(shù),其次將int32、Eq和這兩個(gè)函數(shù)綁定起來(lái):
             1 instance int32 : Eq
             2 {
             3     Equals = IntEquals;
             4     NotEquals = IntNotEquals;
             5 }
             6 
             7 function bool IntEquals(int32 a, int32 b)
             8     (result = (a == b));
             9 
            10 function bool IntNotEquals(int32 a, int32 b)
            11     (result = (a != b));

                因?yàn)榻壎ㄔ贓q上的T的Equals和NotEquals函數(shù)的參數(shù)是T,因此IntEquals和IntNotEquals的參數(shù)必然就是int32了。接下來(lái)我們聲明一個(gè)Vector<T>類型,然后實(shí)現(xiàn)這兩個(gè)函數(shù):
             1 generic<U>
             2 structure Vector
             3 {
             4     U X;
             5     U Y;
             6 }
             7 
             8 generic<V> where
             9   V : Eq
            10 instance Vector : Eq
            11 {
            12     Equals = VectorEquals<V>;
            13     NotEquals = VectorNotEquals<V>;
            14 }
            15 
            16 generic<W> where
            17   W : Eq
            18 function bool VectorEquals(Vector<W> a, Vector<W> b)
            19 {
            20     variable bool x_equals = Eq<W>::Equals(a.X, b.X);
            21     variable bool y_equals = Eq<W>::Equals(a.Y, b.Y);
            22     (result = (x_equals && y_equals));
            23 }
            24 
            25 generic<W> where
            26   W : Eq
            27 function bool VectorNotEquals(Vector<W> a, Vector<W> b)
            28     (result = ( ! VectorEquals<W>(a, b)));

                我們看得出來(lái)這跟普通的函數(shù)沒(méi)什么區(qū)別,而且在給Vector<T>綁定Eq的時(shí)候,我們還可以規(guī)定T必須也存在一個(gè)到Eq的綁定。因此我們不僅可以有Vector<int32>,還能有Vector<Vector<int32>>。而且在VectorEquals內(nèi)部使用Eq<W>::Equals函數(shù)的時(shí)候,如果函數(shù)聲明沒(méi)有where W:Eq的標(biāo)記那么就無(wú)法通過(guò)編譯。因此所有調(diào)用VectorEquals<W>函數(shù)的W都需要有一個(gè)到Eq的綁定。如此下去,只要你漏綁定了什么,都會(huì)得到編譯錯(cuò)誤的提示。

                最后就剩下main函數(shù)了:
             1 function int32 main1()
             2 {
             3     variable Vector<int32> v1;
             4     variable Vector<int32> v2;
             5     (v1.X = 0s32);
             6     (v1.Y = 1s32);
             7     (v2.X = 2s32);
             8     (v2.Y = 3s32);
             9     if(Eq<Vector<int32>>::Equals(v1, v2))
            10         (result = 1s32);
            11     else
            12         (result = 0s32);
            13 }

                我們可以main函數(shù)和VectorEquals函數(shù)看到一個(gè)Equals函數(shù)是如何被調(diào)用的。當(dāng)然這個(gè)代碼編譯成二進(jìn)制代碼之后,虛擬機(jī)將會(huì)在適當(dāng)?shù)臅r(shí)候搜索、展開(kāi)并實(shí)例化這些具體的函數(shù)。我們可以看看編譯器在執(zhí)行完這些代碼之后究竟產(chǎn)生了什么數(shù)據(jù)結(jié)構(gòu):
              1 -----------------------------------------------
              2 Loaded Assemblies[0]
              3 -----------------------------------------------
              4 .data
              5 .label
              6 .code
              7      0: stack_reserve 2
              8      1: stack_offset 24
              9      2: push s32 0
             10      3: add s32
             11      4: readmem 4
             12      5: stack_offset 16
             13      6: push s32 0
             14      7: add s32
             15      8: readmem 4
             16      9: stack_offset -1
             17     10: call 46 1
             18     11: stack_offset 24
             19     12: push s32 4
             20     13: add s32
             21     14: readmem 4
             22     15: stack_offset 16
             23     16: push s32 4
             24     17: add s32
             25     18: readmem 4
             26     19: stack_offset -2
             27     20: call 46 1
             28     21: stack_offset -2
             29     22: read u8
             30     23: convert u32 u8
             31     24: stack_offset -1
             32     25: read u8
             33     26: convert u32 u8
             34     27: and u32
             35     28: push u32 0
             36     29: ne u32
             37     30: resptr
             38     31: write u8
             39     32: stack_reserve -2
             40     33: ret 16
             41 
             42 -----------------------------------------------
             43 Loaded Assemblies[1]
             44 -----------------------------------------------
             45 .data
             46 .label
             47      0: instruction 3
             48      1: instruction 8
             49      2: instruction 46
             50      3: instruction 56
             51      4: instruction 66
             52      5: instruction 100
             53 .code
             54      0: stack_reserve 0
             55      1: stack_reserve 0
             56      2: ret 0
             57      3: stack_reserve 0
             58      4: resptr
             59      5: call 8 1
             60      6: stack_reserve 0
             61      7: ret 0
             62      8: stack_reserve 16
             63      9: push s32 0
             64     10: stack_offset -8
             65     11: push s32 0
             66     12: add s32
             67     13: write s32
             68     14: push s32 1
             69     15: stack_offset -8
             70     16: push s32 4
             71     17: add s32
             72     18: write s32
             73     19: push s32 2
             74     20: stack_offset -16
             75     21: push s32 0
             76     22: add s32
             77     23: write s32
             78     24: push s32 3
             79     25: stack_offset -16
             80     26: push s32 4
             81     27: add s32
             82     28: write s32
             83     29: stack_reserve 1
             84     30: stack_offset -16
             85     31: readmem 8
             86     32: stack_offset -8
             87     33: readmem 8
             88     34: stack_top 16
             89     35: call 0 0
             90     36: jumpfalse 41 1
             91     37: push s32 1
             92     38: resptr
             93     39: write s32
             94     40: jump 44 1
             95     41: push s32 0
             96     42: resptr
             97     43: write s32
             98     44: stack_reserve -16
             99     45: ret 0
            100     46: stack_reserve 0
            101     47: stack_offset 20
            102     48: read s32
            103     49: stack_offset 16
            104     50: read s32
            105     51: eq s32
            106     52: resptr
            107     53: write u8
            108     54: stack_reserve 0
            109     55: ret 8
            110     56: stack_reserve 0
            111     57: stack_offset 20
            112     58: read s32
            113     59: stack_offset 16
            114     60: read s32
            115     61: ne s32
            116     62: resptr
            117     63: write u8
            118     64: stack_reserve 0
            119     65: ret 8
            120     66: stack_reserve 2
            121     67: stack_offset 0[Linear]
            122     68: push s32 0
            123     69: add s32
            124     70: readmem 1[Linear]
            125     71: stack_offset 16
            126     72: push s32 0
            127     73: add s32
            128     74: readmem 1[Linear]
            129     75: stack_offset -1
            130     76: generic_instance_callfunc 1
            131     77: stack_offset 0[Linear]
            132     78: push s32 1[Linear]
            133     79: add s32
            134     80: readmem 1[Linear]
            135     81: stack_offset 16
            136     82: push s32 1[Linear]
            137     83: add s32
            138     84: readmem 1[Linear]
            139     85: stack_offset -2
            140     86: generic_instance_callfunc 1
            141     87: stack_offset -2
            142     88: read u8
            143     89: convert u32 u8
            144     90: stack_offset -1
            145     91: read u8
            146     92: convert u32 u8
            147     93: and u32
            148     94: push u32 0
            149     95: ne u32
            150     96: resptr
            151     97: write u8
            152     98: stack_reserve -2
            153     99: ret 2[Linear]
            154    100: stack_reserve 0
            155    101: stack_reserve 1
            156    102: stack_offset 0[Linear]
            157    103: readmem 3[Linear]
            158    104: stack_offset 16
            159    105: readmem 3[Linear]
            160    106: stack_top 2[Linear]
            161    107: generic_callfunc 0
            162    108: push s8 1
            163    109: xor u8
            164    110: resptr
            165    111: write u8
            166    112: stack_reserve 0
            167    113: ret 2[Linear]
            168 .exports
            169 Assembly Name: assembly_generated
            170 Exports[0= (3, main)
            171 Exports[1= (8, main1)
            172 Exports[2= (46, IntEquals)
            173 Exports[3= (56, IntNotEquals)
            174 Function Entries[0= {
            175   Name = VectorEquals
            176   Arguments = 1
            177   Instruction = 66
            178   Length = 34
            179   UniqueName = [assembly_generated]::[VectorEquals]
            180 }
            181 Function Entries[1= {
            182   Name = VectorNotEquals
            183   Arguments = 1
            184   Instruction = 100
            185   Length = 14
            186   UniqueName = [assembly_generated]::[VectorNotEquals]
            187 }
            188 Targets[0= {
            189   AssemblyName = assembly_generated
            190   SymbolName = VectorEquals
            191   Argument[0= {0} : 1*T0 + 0
            192 }
            193 Linears[0= 2*T0 + 16
            194 Linears[1= 1*T0 + 0
            195 Linears[2= 4*T0 + 0
            196 Linears[3= 2*T0 + 0
            197 Concepts[0= {
            198   Name = Eq
            199   Functions[0= Equals
            200   Functions[1= NotEquals
            201 }
            202 Instances[0= {
            203   ConcpetAssemblyName = assembly_generated
            204   ConceptSymbolName = Eq
            205   TypeUniqueName = s32
            206   Arguments = 0
            207   Functions[0= {
            208     FunctionName = Equals
            209     AssemblyName = assembly_generated
            210     SymbolName = IntEquals
            211   }
            212   Functions[1= {
            213     FunctionName = NotEquals
            214     AssemblyName = assembly_generated
            215     SymbolName = IntNotEquals
            216   }
            217 }
            218 Instances[1= {
            219   ConcpetAssemblyName = assembly_generated
            220   ConceptSymbolName = Eq
            221   TypeUniqueName = [assembly_generated]::[Vector]
            222   Arguments = 1
            223   Functions[0= {
            224     FunctionName = Equals
            225     AssemblyName = assembly_generated
            226     SymbolName = VectorEquals
            227     Argument[0= {0} : 1*T0 + 0
            228   }
            229   Functions[1= {
            230     FunctionName = NotEquals
            231     AssemblyName = assembly_generated
            232     SymbolName = VectorNotEquals
            233     Argument[0= {0} : 1*T0 + 0
            234   }
            235 }
            236 Instance Targets[0= {
            237   AssemblyName = assembly_generated
            238   SymbolName = Eq
            239   FunctionName = Equals
            240   Argument = [assembly_generated]::[Vector] : 8 {
            241     s32 : 4
            242   }
            243 }
            244 Instance Targets[1= {
            245   AssemblyName = assembly_generated
            246   SymbolName = Eq
            247   FunctionName = Equals
            248   Argument = {0} : 1*T0 + 0
            249 }
            250 
            251 -----------------------------------------------
            252 Assembly Name Map
            253 -----------------------------------------------
            254 assembly_generated = 1
            255 
            256 -----------------------------------------------
            257 Function Pointer Map
            258 -----------------------------------------------
            259 0 = Assemblies[-1].Instructions[-1]
            260 1 = Assemblies[1].Instructions[3]
            261 2 = Assemblies[1].Instructions[8]
            262 3 = Assemblies[1].Instructions[46]
            263 4 = Assemblies[1].Instructions[56]
            264 5 = Assemblies[1].Instructions[66]
            265 6 = Assemblies[1].Instructions[100]
            266 7 = Assemblies[0].Instructions[0]
            267 
            268 -----------------------------------------------
            269 Loaded Symbol Names
            270 -----------------------------------------------
            271 assembly_generated.IntEquals
            272 assembly_generated.IntNotEquals
            273 assembly_generated.main
            274 assembly_generated.main1
            275 
            276 -----------------------------------------------
            277 Generic Function Entry Map
            278 -----------------------------------------------
            279 assembly_generated.VectorEquals
            280   Instruction = 66
            281   Count = 34
            282   Assembly = 1
            283   Generic Argument Count = 1
            284   Unique Entry ID = [assembly_generated]::[VectorEquals]
            285 assembly_generated.VectorNotEquals
            286   Instruction = 100
            287   Count = 14
            288   Assembly = 1
            289   Generic Argument Count = 1
            290   Unique Entry ID = [assembly_generated]::[VectorNotEquals]
            291 
            292 -----------------------------------------------
            293 Generic Variable Entry Map
            294 -----------------------------------------------
            295 
            296 -----------------------------------------------
            297 Instanciated Generic Function Map
            298 -----------------------------------------------
            299 [assembly_generated]::[VectorEquals]<s32> = 7
            300 
            301 -----------------------------------------------
            302 Instanciated Generic Variable Map
            303 -----------------------------------------------
            304 
            305 -----------------------------------------------
            306 Cached Generic Target List
            307 -----------------------------------------------
            308 Assembly Name = assembly_generated
            309 Symbol Name = VectorEquals
            310 Arguments = {
            311   Argument[0= {
            312     Name = s32
            313     Size = 4
            314   }
            315 }
            316 
            317 -----------------------------------------------
            318 Generic Concept Map
            319 -----------------------------------------------
            320 assembly_generated.Eq
            321 
            322 -----------------------------------------------
            323 Generic Instance Map
            324 -----------------------------------------------
            325 assembly_generated.Eq<[assembly_generated]::[Vector]>
            326   Generic Argument Count = 1
            327   Resource Index = 1
            328   Function Equals = 0
            329   Function NotEquals = 1
            330 assembly_generated.Eq<s32>
            331   Generic Argument Count = 0
            332   Resource Index = 0
            333   Function Equals = 0
            334   Function NotEquals = 1
            335 
            336 

                Assembly[0]是專門(mén)用來(lái)保存模板函數(shù)的展開(kāi)結(jié)果的,當(dāng)然這里面只有一個(gè)模板函數(shù)被使用了:VectorEquals<int32>。其他的Assembly都是代碼編譯出來(lái)的。

                接下來(lái)只需要測(cè)試一下,然后就可以著手開(kāi)發(fā)最后一個(gè)語(yǔ)法了:異常處理。
            posted on 2010-08-26 03:09 陳梓瀚(vczh) 閱讀(3104) 評(píng)論(3)  編輯 收藏 引用 所屬分類: VL++3.0開(kāi)發(fā)紀(jì)事

            評(píng)論:
            # re: Vczh Library++3.0完成了NativeX語(yǔ)言的所有泛型語(yǔ)法 2010-08-26 05:31 | 空明流轉(zhuǎn)
            沙發(fā),vc威武。  回復(fù)  更多評(píng)論
              
            # re: Vczh Library++3.0完成了NativeX語(yǔ)言的所有泛型語(yǔ)法 2010-08-26 16:34 | 路青飛
            板凳,恭喜恭喜  回復(fù)  更多評(píng)論
              
            # re: Vczh Library++3.0完成了NativeX語(yǔ)言的所有泛型語(yǔ)法 2010-08-26 19:20 | 溪流
            地板,同賀同賀  回復(fù)  更多評(píng)論
              
            久久久久综合网久久| 久久亚洲av无码精品浪潮| 波多野结衣中文字幕久久| 99久久777色| 日韩久久无码免费毛片软件| 亚洲欧洲精品成人久久曰影片| 久久精品青青草原伊人| 精品少妇人妻av无码久久| 久久www免费人成看国产片| 日日狠狠久久偷偷色综合0 | 国内精品久久久久久中文字幕| 久久综合日本熟妇| 国产精品久久久久久福利漫画| 久久综合给合综合久久| 亚洲精品乱码久久久久久蜜桃不卡| 四虎国产永久免费久久| 国产69精品久久久久9999APGF| 91久久精品无码一区二区毛片| 久久久精品国产免大香伊| 国产综合免费精品久久久| 色综合久久中文字幕无码| 亚洲精品无码久久久| 99久久综合国产精品二区| 久久久一本精品99久久精品66| 久久综合久久伊人| 国产精品热久久无码av| 久久久久人妻精品一区二区三区| 欧美成a人片免费看久久| 国产高潮久久免费观看| 精品熟女少妇a∨免费久久| 亚洲午夜久久久影院伊人| 亚洲国产成人乱码精品女人久久久不卡| 精品久久香蕉国产线看观看亚洲| 中文字幕乱码人妻无码久久| 人人狠狠综合久久亚洲高清| 99热热久久这里只有精品68| 东京热TOKYO综合久久精品| 久久亚洲AV成人无码电影| 亚洲日本va中文字幕久久| 久久精品一本到99热免费| 怡红院日本一道日本久久|