程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Vczh Library++3.0之山寨mscorlib.dll

Vczh Library++3.0之山寨mscorlib.dll

編輯:關於C語言

由於Vczh Library++3.0的托管語言ManagedX被設計成編譯到本地語言NativeX,因此山寨一個mscorlib.dll是必不可少的。不過我的mscorlib.dll只包含最低限度的代碼。譬如說string,譬如說數組,譬如說函數類型等等這些本不能用托管語言自己來實現的類(C++是唯一的一個所有東西都可以用類庫來彌補的語言)。因此花費了數日,用ManagedX實現了它的聲明和一些代碼,然後external一些函數。最終,ManagedX寫的mscorlib會被編譯成NativeX,而external的幾個函數自然會用NativeX自己來寫。譬如說如何比較兩個string的大小,這個托管語言自己顯然是搞不定的。

    因此這裡就比較麻煩了,需要做一些工程上的麻煩事情。首先,若干個ManagedX文件被編譯成一個單獨的NativeX文件,然後這個生成的NativeX文件跟另一個手寫的NativeX文件再一起被編譯成一個assembly。這就跟把C#編譯成C差不多。

    第一個版本的ManagedX還需要做出一點折衷,譬如說數組的維度不能超過10。這裡的維度指的是a[,,,,,,,,,],而不是a[][][][][][][][][][]。譬如說函數類型的參數數量不能超過10(但是函數的參數數量卻可以,這裡只針對函數類型)。主要是因為,為了讓ManagedX可以被編譯成NativeX,那麼勢必不可能運行的時候才動態生成某個類(模板除外,因為我的NativeX==C+template)。因此一維、二維乃至十維的數組當然是10個不同的類(你可以使用一個二維的十維數組的數組去模擬一個十二維的數組,這毫無問題)。不過為了避免我真的將一批相似的類重復寫10次,我使用了一年多前開發的Fpmacro來做。Fpmacro是一個語法不同的類似C語言宏的擴展,但是沒有C語言的宏的所有陷阱,而且其實是一門函數是語言,帶有類似lambda表達式的東西,每一個函數都被設計成一個返回字符串的函數,參數可以是數組、字符串或者另一個函數。而且語法經過了優化,完全沒有多余的東西。這裡給一個例子,譬如說聲明10個Array的Fpmacro代碼:   1 $$include:Common.fpm
  2
  3 $$define $DIMENTION_FIELD_NAME($element) dimSize$element
  4 $$define $DIMENTION_PARAMETER_NAME($element) _$element
  5 $$define $DIMENTION_PARAMETER_DEFINITION($element) int $DIMENTION_PARAMETER_NAME($element)
  6 $$define $DIMENTION_PARAMETER_NAME_IN_ARRAY($element) indices[$element]
  7
  8 $$define $DIMENTION_FIELD($element) $$begin
  9         private int $DIMENTION_FIELD_NAME($element);
 10 $( )
 11 $$end
 12
 13 $$define $DIMENTION_FIELD_SETTER($element) $$begin
 14             $DIMENTION_FIELD_NAME($element) = $DIMENTION_PARAMETER_NAME($element);
 15 $( )
 16 $$end
 17
 18 $$define $DIMENTION_SIZE_CASE($element) $$begin
 19                 case $element:
 20                     return $DIMENTION_FIELD_NAME($element);
 21 $( )
 22 $$end
 23
 24 $$define $DIMENTION_CHECK($element) $$begin
 25             if($DIMENTION_PARAMETER_NAME($element)<0 || $DIMENTION_PARAMETER_NAME($element)>=$DIMENTION_FIELD_NAME($element))
 26                 throw new ArgumentOutOfRangeException($(")$DIMENTION_PARAMETER_NAME($element)$("));
 27 $( )
 28 $$end
 29
 30 $$define $DIMENTION_SUMMERS($elements) $$begin
 31   $$define $DIMENTION_SUMMER($index) $$begin
 32             sum*=$DIMENTION_FIELD_NAME($sub($sub($elements,1),$index));
 33             index+=sum*$DIMENTION_PARAMETER_NAME($sub($sub($elements,2),$index));
 34 $( )
 35   $$end
 36 $loop($sub($elements,1),0,$DIMENTION_SUMMER)
 37 $$end
 38
 39 $$define $ARRAY_IMPLEMENTATION($elements) $$begin
 40 $( )
 41     generic<inout T>
 42     public sealed class Array$elements : Array
 43     {
 44 $( )
 45         public constructor($loopsep($elements,0,$DIMENTION_PARAMETER_DEFINITION,$(,) ), Array<T> src=null, bool copy=true)
 46         {
 47 $loop($elements,0,$DIMENTION_FIELD_SETTER)
 48             Initialize(this.Length, src, copy);
 49         }
 50 $( )
 51 $loop($elements,0,$DIMENTION_FIELD)
 52         public override int GetDimCount()
 53         {
 54             return $elements;
 55         }
 56 $( )
 57         public override int GetDimSize(int dim)
 58         {
 59             switch(dim)
 60             {
 61 $loop($elements,0,$DIMENTION_SIZE_CASE)
 62                 default:
 63                     throw new ArgumentOutOfRangeException("dim");
 64             }
 65         }
 66 $( )
 67         public override int Length
 68         {
 69             get
 70             {
 71                 return $loopsep($elements,0,$DIMENTION_FIELD_NAME,$(*));
 72             }
 73         }
 74 $( )
 75         public override int GetStartIndexFromIndices(params int[] indices)
 76         {
 77             if(indices.Length!=$elements)
 78             {
 79                 throw new ArgumentOutOfRangeException("indices");
 80             }
 81             return GetStartIndex[$loopsep($elements,0,$DIMENTION_PARAMETER_NAME_IN_ARRAY,$(,))];
 82         }
 83 $( )
 84         public int GetStartIndex($loopsep($elements,0,$DIMENTION_PARAMETER_DEFINITION,$(,) ))
 85         {
 86 $loop($elements,0,$DIMENTION_CHECK)
 87             int index=$DIMENTION_PARAMETER_NAME($sub($elements,1));
 88             int sum=1;
 89   &nb

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved