随笔-341  评论-2670  文章-0  trackbacks-0
    由于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=nullbool 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。
posted on 2011-06-26 09:15 陈梓瀚(vczh) 阅读(3885) 评论(17)  编辑 收藏 引用 所属分类: VL++3.0开发纪事

评论:
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 16:47 | 空明流转
楼主威武!(别删我留言。。。)  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 17:42 | clayui
才知道楼主是这么一个牛人,也非常感谢楼主能去clayui踢馆,所以,我今天,不是来踢馆的:)我只有1个问题,我想用楼主的东西,不知道效率如何,跟adobe的AVM2比起来怎么样?  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 18:04 | 战魂小筑
为啥不用Live Writer呢,编辑起来多方便  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 18:18 | lwch
完全看不懂这是神马玩意...  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 18:24 | 空明流转
@clayui
完全不是一个性质的玩意儿。
它的那个东西更像是C#。一门Pure JIT的语言。  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 18:27 | 陈梓瀚(vczh)
@lwch
你只要想象一下string是如何写出来的,就知道了……为什么M¥要提供C++/CLI,基本上就是为了这个。  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 18:29 | 陈梓瀚(vczh)
@clayui
嗯,我还是在山寨C#。不过距离能用还很远……倒是再主页上置顶了一个freescript,是一门动态语言,你可以试试。  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 18:33 | Error
虽然现在还不知道楼主在说什么,但是依然觉得楼主V6、楼主牛鞭,,,  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 19:36 | clayui
@陈梓瀚(vczh)
试试freescript,这是一个现实的问题,而现实是比较残酷的,那么freescript与V8相比有什么优点?我的意思是如果别人用V8,而我用freescript,那么我是否比别人更有优势?  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 19:38 | clayui
@空明流转
我的确不是很懂这个,所以可能会说出让你笑掉大牙的话,呵呵,那么,我看介绍说的是“通用多语言脚本平台”,AVM2是一个脚本引擎,这2者究竟有何区别呢?望赐教。  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 19:47 | 陈梓瀚(vczh)
@clayui
这世界上任何一门动态语言都不会比其他动态语言更有优势——如果你拿他当脚本用的话。  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 19:51 | 陈梓瀚(vczh)
@clayui
这个嘛,我的初始目的是想做一个公共的后端,让以后拿新的语法做实验会变得非常容易,并且把结构拆散有利于别人学习编译原理,最后顺便实现把动态语言编译成本低代码的梦想。想要做到最后一步根据现在的速度,估计还得有几年的时间。

而一个脚本引擎,就是做来给你用的,目的很单纯。

这里的区别就是,倘若我在后面那几年把我想做的优化都做完的话,那以后想支持什么新语言(众口难调啊),都做到这个后端上去,那就变成一个parser的工作,而不是一个脚本引擎整个的工作了。譬如说javascript,譬如说python,譬如说ruby,虽然语法看上去差很远,但其实都没什么区别,不需要每一门都单独重做一次  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 20:14 | clayui
@陈梓瀚(vczh)
基本上明白了,呵呵,谢谢,我想我要的应该就是你优化后的东西吧,希望几年后我还能用上你的脚本语言。根据我的理解,你应该是想要实现一个统一的parser引擎?如果这个能做好,说不定可以成为所有脚本语言进行parser的一个工业标准?恩,假如是这样,那么,真的很有意思,呵呵。  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-26 21:36 | 陈梓瀚(vczh)
@clayui
不是统一的parser,parser没什么好统一的,只是another CLR/llvm/其他什么的罢了……  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-06-27 06:15 | 千暮(zblc)
- -bnr 两个美元符号真恶心  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-07-06 01:11 | 蔣枫亦
写编译器的工作量实在很大,各种考虑,这还是在用了工具的情况下,要是没有ANTLR ,LLVM等等这些工具的话,估计我们公司的编译器开发完成要猴年马月了。即时这样天天小问题还不断,目前在做怎么支持直接到android平台运行,android这个平台还真是复杂,关sdk工具命令就N多。楼主加油!  回复  更多评论
  
# re: Vczh Library++3.0之山寨mscorlib.dll 2011-07-08 08:04 | 陈梓瀚(vczh)
@蔣枫亦
嗯,我在尝试山寨一个后端,ANTLR那样子的前端我已经搞定了。  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理