Vczh Library++3.0之山寨mscorlib.dll

Vczh Library++3.0之山寨mscorlib.dll
    由于 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              $DIMENTION_SUMMERS($elements)
 90               return  index;
 91          }
 92  $( )
 93           public   override  T GetElement( params   int [] indices)
 94          {
 95               return  Get(GetStartIndexFromIndices(indices));
 96          }
 97  $( )
 98           public   override   void  SetElement(T value,  params   int [] indices)
 99          {
100              Set(value, GetStartIndexFromIndices(indices));
101          }
102  $( )
103           public  T  operator   get []($loopsep($elements, 0 ,$DIMENTION_PARAMETER_DEFINITION,$(,) ))
104          {
105               return  Get($loopsep($elements, 0 ,$DIMENTION_PARAMETER_NAME,$(,) ));
106          }
107  $( )
108           public  T  operator   set [](T value, $loopsep($elements, 0 ,$DIMENTION_PARAMETER_DEFINITION,$(,) ))
109          {
110               return  Set(value, $loopsep($elements, 0 ,$DIMENTION_PARAMETER_NAME,$(,) ));
111          }
112  $( )
113      }
114  $$end
115 
116  namespace  System
117  {
118      generic < inout T >
119       public   abstract   class  Array : IEnumerable < T >
120      {
121           protected  intptr gchandle = 0 ;
122           protected  external  void  Initialize( int  size, Array < T >  src,  bool  copy);
123           public  external T Get( int  position);
124           public  external  void  Set(T value,  int  position);
125  $( )
126           public  external  void  CopyTo(intptr pointer,  int  fromStart,  int  length);
127           public  external  void  CopyTo(Array < T >  array,  int  fromStart,  int  length,  int  toStart);
128  $( )
129           public   abstract   int  GetDimCount();
130           public   abstract   int  GetDimSize( int  dim);
131           public   abstract   int  Length{ get ;}
132           public   abstract   int  GetStartIndexFromIndices( params   int [] indices);
133           public   abstract  T GetElement( params   int [] indices);
134           public   abstract   void  SetElement(T value,  params   int [] indices);
135  $( )
136           private   class  Enumerator : IEnumerator
137          {
138               private  Array < T >  array;
139               private   int  index;
140  $( )
141               public  constructor(Array < T >  array)
142              {
143                   this .array = array;
144                   this .index =- 1 ;
145              }
146  $( )
147               public   bool  MoveNext()
148              {
149                   if (index == array.Length - 1 )
150                  {
151                       return   false ;
152                  }
153                   else
154                  {
155                      index ++ ;
156                       return   true ;
157                  }
158              }
159  $( )
160               public  T Current
161              {
162                   get
163                  {
164                       return  array.Get(index);
165                  }
166              }
167  $( )
168               object  IEnumerator::Current
169              {
170                   get
171                  {
172                       return  array.Get(index);
173                  }
174              }
175          }
176  $( )
177          IEnumerator < T >  IEnumerable < T > ::GetEnumerator()
178          {
179               return   new  Enumerator( this );
180          }
181  $( )
182          IEnumerator IEnumerable::GetEnumerator()
183          {
184               return   new  Enumerator( this );
185          }
186  $( )
187      }
188  $( )
189      generic < inout T >
190       public   class  ReadonlyArray
191      {
192           private  T[] items;
193  $( )
194           public  constructor(T[] items)
195          {
196               this .items = items;
197          }
198  $( )
199           public   int  Length
200          {
201               get
202              {
203                   return   this .items.Length;
204              }
205          }
206  $( )
207           public  T  operator   get []( int  index)
208          {
209               return   this .items[index];
210          }
211      }
212  $loop($MAX_ELEMENT_COUNT(), 1 ,$ARRAY_IMPLEMENTATION)
213  }

    会被扩展成(太长cppblog编辑器性能太烂导致响应速度无法忍受, 下载代码并打开UnitTest\Binary\ScriptCoreLibrary\System.CoreManaged\Array.txt自行阅读)

    山寨mscorlib.dll的ManagedX部分基本完成,剩下的十几个函数写的NativeX则等到编译成NativeX的部分完成之后再写。到了这里,一共实现了:
    Array<T>
    Array1<T> .. Array10<T>
    Attribute
    AttributeUsageAttribute
    AutoGeneratedAttribute
    NotInstantiableAttribute
    StructBaseAttribute
    DefaultValueAttribute
    VariadicParameterAttribute
    EnumItemBase
    EnumItemManager
    Exception
    IndexOutOfRangeException
    ArgumentOutOfRangeException
    WrongFormatException
    TypeConversionException
    NotImplementedException
    Delegate
    DelegateTarget
    MethodDelegate
    BroadcastDelegate
    Function<R> .. Function<R, T0 .. T9>
    Procedure, Procedure<T0> .. Procedure<T0 .. T9>
    Event, Event<T0> .. Event<T0 .. T9>
    IEnumerator
    IEnumerable
    IEnumerator<T>
    IEnumerable<T>
    SInt8 .. SInt64
    UInt8 .. UInt64
    Single, Double, Char, Bool, Void
    Object
    String
    Type

    从明天开始就要做ManagedX的语义分析器了。接下来的路还很长。语义分析结束之后,要把ManagedX展开变成一份更长但是包含的东西更少的ManagedX(譬如没有lambda expression,因为被重写成了一个内部类),最后编译成NativeX。

你可能感兴趣的:(Vczh Library++3.0之山寨mscorlib.dll)