﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-λ-calculus（惊愕到手了欧耶）-随笔分类-VL++3.0开发纪事</title><link>http://www.cppblog.com/vczh/category/12070.html</link><description>【QQ：343056143（已满），504254078】【MSN：vczh@hotmail.com】【Email：vczh@163.com】</description><language>zh-cn</language><lastBuildDate>Tue, 27 Sep 2011 15:19:41 GMT</lastBuildDate><pubDate>Tue, 27 Sep 2011 15:19:41 GMT</pubDate><ttl>60</ttl><item><title>浅谈面向对象语言的类型运算</title><link>http://www.cppblog.com/vczh/archive/2011/09/27/157007.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Tue, 27 Sep 2011 13:54:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/09/27/157007.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/157007.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/09/27/157007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/157007.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/157007.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">像</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">C#<span lang="ZH-CN">或者</span>Haskell<span lang="ZH-CN">这样的先进的语言都有一个跟语法分不开的最核心的库。譬如说</span>C#<span lang="ZH-CN">的</span>int<span lang="ZH-CN">，是</span>mscorlib.dll<span lang="ZH-CN">里面的</span>System.SInt32<span lang="ZH-CN">，</span>Haskell<span lang="ZH-CN">的</span>(x:xs)<span lang="ZH-CN">则定义在了</span>prelude<span lang="ZH-CN">里面。</span></span><a style="text-decoration: underline" href="http://vlpp.codeplex.com/" target="_blank"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><font color="#0000ff">Vczh Library++ 3.0</font></span></a><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">的</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">ManagedX<span lang="ZH-CN">语言也有一个类似</span>mscorlib.dll<span lang="ZH-CN">的东西。之前的</span>NativeX<span lang="ZH-CN">提供了一个核心的函数库叫</span>System.CoreNative (syscrnat.assembly)<span lang="ZH-CN">，因此</span>ManagedX<span lang="ZH-CN">的就命名为</span>System.CoreManaged (syscrman.assembly)<span lang="ZH-CN">。</span>System.CoreManaged<span lang="ZH-CN">里面的预定义对象都是一些基本的、不可缺少的类型，例如</span>System.SInt32<span lang="ZH-CN">、</span>System.IEnumerable&lt;T&gt;<span lang="ZH-CN">或者</span>System.Reflection.Type<span lang="ZH-CN">。昨天晚上我的未完成的语义分析器的完成程度已经足以完全分析</span>System.CoreManaged<span lang="ZH-CN">里面的托管代码了，因此符号表里面的类型系统也基本上是一个完整的类型系统。在开发的过程中得到的心得体会便是写着一篇文章的来源。</span></span><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">如今，先进的面向对象语言的类型都离不开下面的几个特征：对象类型、函数类型和接口类型。修饰类型的工具则有泛型和延迟绑定等等。譬如说</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">C#<span lang="ZH-CN">，对象类型便是</span>object<span lang="ZH-CN">，函数类型则有</span>.net framework<span lang="ZH-CN">支持的很好，但是不是核心类型的</span>Func<span lang="ZH-CN">和</span>Action<span lang="ZH-CN">，接口类型则类似</span>IEnumerable<span lang="ZH-CN">。泛型大家都很熟悉，延迟绑定则类似于</span>dynamic<span lang="ZH-CN">关键字。</span>var<span lang="ZH-CN">关键字是编译期绑定的，因此不计算在内。</span>Java<span lang="ZH-CN">的</span>int<span lang="ZH-CN">是魔法类型，其设计的错误已经严重影响到了类库的优美程度，其使用&#8220;类型擦除&#8221;的泛型系统也为今后的发展留下了一些祸根，因此这些旁门左道本文章就不去详细讨论了。这篇文章讲针对重要的那三个类型和两个修饰进行讨论，并解释他们之间互相换算的方法。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">在</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">C#<span lang="ZH-CN">里面，函数类型也是对象类型的一部分，但是由于</span>C#<span lang="ZH-CN">可以在编译过程中把一个不完整的函数类型推导为一个完整的函数类型，因此在这里将它和对象类型区分开来。</span>Haskell<span lang="ZH-CN">则在推导上做得更加彻底，这都是先进的有类型语言所不可缺少的一个特征。由于类型之间的互相换算是本文所关心的内容，因此下面先给出几个定义。当然这些定义在数学上是不严谨的，而我也并不追求这个。</span>namespace<span lang="ZH-CN">在这里也不是非常重要，因为存在</span>namespace<span lang="ZH-CN">和不存在</span>namespace<span lang="ZH-CN">所带来的区别仅仅是一个对象被如何解释（黑话称之为</span>Resolving<span lang="ZH-CN">），并不影响推导过程。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">我们可以将一个类型命名为</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">T<span lang="ZH-CN">，它是不带泛型的。一般来说，因为类型存在成员函数，所以类型便有几个基本的属性，称之为</span>this<span lang="ZH-CN">类型和</span>base<span lang="ZH-CN">类型（在</span>C#<span lang="ZH-CN">，代表自己的关键字分别是</span>this<span lang="ZH-CN">和</span>base<span lang="ZH-CN">）。</span>this<span lang="ZH-CN">指的是类型</span>T<span lang="ZH-CN">的成员函数所看到的自己的类型。而</span>base<span lang="ZH-CN">类型则是父类的类型。在这里有必要做出一点解释。只有对象类型才具有</span>base<span lang="ZH-CN">类型，而且其</span>base<span lang="ZH-CN">类型指的是所有父类中唯一一个不是接口类型的那个。函数类型和接口类型都有</span>this<span lang="ZH-CN">类型。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">因此对于任何一个具有下面描述的类型</span></strong><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">T<span lang="ZH-CN">：</span><o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">class T : U, I1, I2, I3{}<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">this(T) == T<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">base(T) == U<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">现在让我们来考察一个带泛型的类型声明</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">T[U, V]<span lang="ZH-CN">，和他的实例化类型</span>T&lt;A, B&gt;<span lang="ZH-CN">之间的关系。我们知道，一个带泛型的类型声明</span>T[U, V]<span lang="ZH-CN">实际上是一个不完整的类型，因为这个类型还有</span>U<span lang="ZH-CN">和</span>V<span lang="ZH-CN">两个参数待填，正如下面的代码所示：</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">class T&lt;U, V&gt;{}<o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">而当你实例化他之后，令</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">U==A<span lang="ZH-CN">，</span>V==B<span lang="ZH-CN">，则</span>T<span lang="ZH-CN">类型被</span>A<span lang="ZH-CN">和</span>B<span lang="ZH-CN">实例化成了</span>T&lt;A, B&gt;<span lang="ZH-CN">。这就有点象我们把一个</span>Dictionary[K, V]<span lang="ZH-CN">给实例化成</span>Dictionary&lt;int, string&gt;<span lang="ZH-CN">一样。一个实例化后的类型才可以被当成另一个泛型类型的类型参数，或者直接使用它来定义一些符号，或者创建一个它的实例等等。但是不完整的泛型类型</span>T[U, V]<span lang="ZH-CN">和它的实例化类型</span>T&lt;A, B&gt;<span lang="ZH-CN">都具有共同的属性&#8212;&#8212;</span>this<span lang="ZH-CN">类型和</span>base<span lang="ZH-CN">类型。按照上面的定义，</span>this<span lang="ZH-CN">类型是该类型的成员函数所看到的自己的类型。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">因此对于任何一个具有下面描述的类型</span></strong><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">T[U, V]<span lang="ZH-CN">：</span><o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">class T&lt;U, V&gt; : W&lt;U, V&gt;{}<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">this(T[U, V]) == T&lt;U, V&gt;<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">base(T[U, V]) == W&lt;U, V&gt;<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">当然，对于</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">T&lt;A, B&gt;<span lang="ZH-CN">来说，它也具有</span>this<span lang="ZH-CN">类型</span>T&lt;A, B&gt;<span lang="ZH-CN">和</span>base<span lang="ZH-CN">类型</span>W&lt;A, B&gt;<span lang="ZH-CN">。一般情况下，非泛型类型</span>T<span lang="ZH-CN">的声明可以被处理成</span>T[]<span lang="ZH-CN">，我们令</span>T[]<span lang="ZH-CN">等于</span>T&lt;&gt;<span lang="ZH-CN">，就可以将所有泛型类型的规则实例化到一个带有</span>0<span lang="ZH-CN">个泛型参数的泛型类型&#8212;&#8212;也就是非泛型类型上面了。因此下面的讨论将不作区分。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">现在我们考虑如何获得一个泛型类型的所有成员的类型。我们考虑下面的一组类型：</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">interface IEnumerable&lt;T&gt;<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">{<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>IEnumerator&lt;T&gt; GetEnumerator();<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">}<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">class Base&lt;T&gt; : IEnumerable&lt;T&gt;<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">{<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>public T Value{get; set;}<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">}<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">class Derived&lt;T, U&gt; : Base&lt;U&gt;<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">{ <o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">}<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">我们来考虑一个问题：如何知道</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">Derived&lt;int, string&gt;<span lang="ZH-CN">的</span>GetEnumerator<span lang="ZH-CN">函数的返回值类型是什么呢？乍一看似乎很简单，其实对于人类来说这个问题的确是仅靠直觉就可以瞬间回答出来的、根本没有任何障碍的问题了。这里我一直佩服大自然可以将人类进化到如此牛逼的地步。不过这个问题困扰了我很久，主要是在开发语义分析器的时候，安排各种各样的类型运算、符号表的结构和其它的一些相关问题的时候，这个问题的难度就提高了。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">不过在这里我并不想多说什么废话，我们仅需要给类型对增加几个属性和运算规则，就可以很容易的将这个问题组合成一个表达式了。</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">首先，我们需要有一个</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">replace<span lang="ZH-CN">操作。</span>replace<span lang="ZH-CN">操作很难一下子严谨的定义出来，不过可以给一个直观的定义，就是：</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">replace(Derived&lt;T, U&gt;, {T=&gt;int, U=&gt;string}) == Derived&lt;int, string&gt;<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">相信大家已经可以很轻松的理解了，因此对于一个类型映射</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">tm={T=&gt;string}<span lang="ZH-CN">来说，</span>replace(Derived&lt;IEnumerable&lt;T&gt;&gt;, tk)<span lang="ZH-CN">的结果就是</span>Derived&lt;IEnumerable&lt;string&gt;&gt;<span lang="ZH-CN">了。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">其次，我们需要一个</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">decl<span lang="ZH-CN">操作，这个操作返回一个泛型类型的实例类型的定义：</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">decl(T&lt;A, B&gt;) == T[U, V]<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">然后，我们还需要一个</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">params<span lang="ZH-CN">操作。这个操作将一个泛型类型的实例类型和他的泛型定义相比较，提取出可以从泛型定义</span>replace<span lang="ZH-CN">到实例类型的那个类型映射：</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">params(T&lt;A, B&gt;) == {T=&gt;A, U=&gt;B}<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">因此一般来说，我们有下面的规则。只要类型</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">T<span lang="ZH-CN">是一个泛型类型的实例类型，那么总是有：</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">replace(this(decl(T)), params(T)) == T<o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">现在我们就可以开始回答上面提到的那个问题了。</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">首先对于类型</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">Derived&lt;int, string&gt;<span lang="ZH-CN">，我们需要找到他的父类。因此我们可以做如下几步操作：</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">tm = params(Derived&lt;int, string&gt;) = {T=&gt;int, U=&gt;string}<o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">tb = base(decl(Derived&lt;int, string&gt;)) = base(Derived[T, U]) = Base&lt;U&gt;<o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">result = replace(tb, tm) = replace(Base&lt;U&gt;, {T=&gt;int, U=&gt;string}) = Base&lt;string&gt;<o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">这样我们就成功求出</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">T=Derived&lt;int, string&gt;<span lang="ZH-CN">的父类</span>B=<strong style="mso-bidi-font-weight: normal">replace(base(decl(T)), params(T))</strong>=Base&lt;string&gt;<span lang="ZH-CN">了</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">其次，我们指定要计算类型</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">Base&lt;string&gt;<span lang="ZH-CN">所继承的那个接口</span>Base[T]=&gt;IEnumerable&lt;T&gt;<span lang="ZH-CN">，我们可以使用</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">tm = params(Base&lt;string&gt;) = {T=&gt;string}<o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">result = replace(IEnumerable&lt;T&gt;, tm) = IEnumerable&lt;string&gt;<o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">因此对于一个泛型声明</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">decl(T)<span lang="ZH-CN">所继承的一个接口</span>Id<span lang="ZH-CN">，泛型声明</span>D<span lang="ZH-CN">的实例类型</span>T<span lang="ZH-CN">所对应的接口</span>It<span lang="ZH-CN">等于</span><strong style="mso-bidi-font-weight: normal">replace(Td, params(T))</strong><span lang="ZH-CN">。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">因此对于</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">IEnumerable[T]<span lang="ZH-CN">的函数</span>GetEnumerator<span lang="ZH-CN">的返回值类型</span>IEnumerator&lt;T&gt;<span lang="ZH-CN">，聪明的读者肯定想到，</span>IEnumerable&lt;string&gt;<span lang="ZH-CN">所对应的类型就是</span>replace(IEnumerator&lt;T&gt;, params(IEnumerable&lt;string&gt;)) == IEnumerator&lt;string&gt;<span lang="ZH-CN">了。这个结果跟求实例类型所继承的接口类型的方法一样。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">我们可以知道，在计算泛型类型的实例类型的成员类型中，我们总是不断地在计算</span><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">replace(A, params(B))</span></strong><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">的结果。因此在我实现的带泛型的面向对象托管语言：</span><a style="text-decoration: underline" href="http://vlpp.codeplex.com/" target="_blank"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><font color="#0000ff">Vczh Library++ 3.0</font></span></a><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">的</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">ManagedX<span lang="ZH-CN">语言的语义分析器的符号表的代码里面，真实出现了使用</span>C++<span lang="ZH-CN">所完成的</span><strong style="mso-bidi-font-weight: normal">this</strong><span lang="ZH-CN">、</span><strong style="mso-bidi-font-weight: normal">base</strong><span lang="ZH-CN">、</span><strong style="mso-bidi-font-weight: normal">decl</strong><span lang="ZH-CN">、</span><strong style="mso-bidi-font-weight: normal">params</strong><span lang="ZH-CN">、</span><strong style="mso-bidi-font-weight: normal">replace</strong><span lang="ZH-CN">和</span><strong style="mso-bidi-font-weight: normal">replace_by_type</strong> = replace(A, params(B))<span lang="ZH-CN">这样的六个函数。因为在</span>C++<span lang="ZH-CN">里面，一个类型的实例只能被表示为一个带有复杂结构的对象的指针。因此只要符号表在计算类型的过程中，把所有产生出来的类型保存下来，建立索引，并且使得&#8220;只要类型</span>A<span lang="ZH-CN">和类型</span>B<span lang="ZH-CN">是同一个类型则有他们的指针</span>P(A)<span lang="ZH-CN">和</span>P(B)<span lang="ZH-CN">相等&#8221;的这个条件恒成立的话，类型系统的计算速度将直接提高。</span><o:p></o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast"><o:p>&nbsp;</o:p></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast" lang="ZH-CN">至于函数类型的推导法则（主要是应用于</span><span style="font-family: 宋体; mso-ascii-theme-font: minor-fareast; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-fareast">lambda<span lang="ZH-CN">表达式的缩写语法），则等到我开发到那里的时候再写后续的文章了。</span>System.CoreManaged<span lang="ZH-CN">有幸不需要使用</span>lambda<span lang="ZH-CN">表达式，使得我的第一个里程碑提前到来。</span><o:p></o:p></span></p><img src ="http://www.cppblog.com/vczh/aggbug/157007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-09-27 21:54 <a href="http://www.cppblog.com/vczh/archive/2011/09/27/157007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0之ManagedX语言检查类型的可见性</title><link>http://www.cppblog.com/vczh/archive/2011/07/16/151176.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 16 Jul 2011 09:38:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/07/16/151176.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/151176.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/07/16/151176.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/151176.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/151176.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; Vczh Library++3.0的山寨C#的ManagedX今天完成了一个功能，就是编译器检查一个类型在他上下文里面是否可用。这个过程足够复杂，我写了足足3个小时。&nbsp;&nbsp;&nbsp; ManagedX的符号表里面的类型已经被大大简化了。函数指针是类，基本数字类型也是类，所以归根结底只有&nbsp;&nbsp;&nbsp; 1：子类型&nbs...&nbsp;&nbsp;<a href='http://www.cppblog.com/vczh/archive/2011/07/16/151176.html'>阅读全文</a><img src ="http://www.cppblog.com/vczh/aggbug/151176.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-07-16 17:38 <a href="http://www.cppblog.com/vczh/archive/2011/07/16/151176.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0之山寨mscorlib.dll</title><link>http://www.cppblog.com/vczh/archive/2011/06/27/149521.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 26 Jun 2011 17:15:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/06/27/149521.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/149521.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/06/27/149521.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/149521.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/149521.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 由于Vczh Library++3.0的托管语言ManagedX被设计成编译到本地语言NativeX，因此山寨一个mscorlib.dll是必不可少的。不过我的mscorlib.dll只包含最低限度的代码。譬如说string，譬如说数组，譬如说函数类型等等这些本不能用托管语言自己来实现的类（C++是唯一的一个所有东西都可以用类库来弥补的语言）。因此花费了数日，...&nbsp;&nbsp;<a href='http://www.cppblog.com/vczh/archive/2011/06/27/149521.html'>阅读全文</a><img src ="http://www.cppblog.com/vczh/aggbug/149521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-06-27 01:15 <a href="http://www.cppblog.com/vczh/archive/2011/06/27/149521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0之如何把C#属性parse出来的超长pair链表赋值到语法书上</title><link>http://www.cppblog.com/vczh/archive/2011/06/14/148630.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Tue, 14 Jun 2011 07:01:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/06/14/148630.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/148630.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/06/14/148630.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/148630.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/148630.html</trackback:ping><description><![CDATA[<div>&nbsp;&nbsp;&nbsp; <a style="text-decoration: underline" href="http://vlpp.codeplex.com" target="_blank">Vczh Library++3.0</a>的ManagedX（山寨C#）语法分析器写好了。将近1000行的语法树声明，使用了ParserCombinator还有93k的语法分析器。写了好久。其中遇到了一些问题，譬如说C#的语法实在太复杂，parse一个method也好property也好都会有一大堆东西。举个例子，一个method的文法如下：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">(attributeInfo&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;opt(genericInfo)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;accessor&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;memberType&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;inheritation&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;internalExternal&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;opt(type&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;COLON(NeedColon)&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;COLON(NeedColon))&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;ID(NeedId)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(OPEN_EXP_BRACE(NeedOpenExpBrace)&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;plist(opt(parameter&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(COMMA&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;parameter)))&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;CLOSE_EXP_BRACE(NeedCloseExpBrace))&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statement<br /></span><span style="color: #008080">6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)[ToMethodMember]<br /></span><span style="color: #008080">7</span>&nbsp;<span style="color: #000000"></span></div><br />&nbsp;&nbsp;&nbsp; 最顶级的operator+一共有10个，也就是说这个东西的返回结果是pair&lt;pair&lt;pair&lt;pair&lt;pair&lt;pair&lt;pair&lt;pair&lt;pair&lt;pair&lt;a, b&gt;, c&gt;, d&gt;, e&gt;, f&gt;, g&gt;, f&gt;, i&gt;, j&gt;, k&gt;。因此ToMethodMember函数的参数也是这个类型。这显然很令人讨厌。<br /><br />&nbsp;&nbsp;&nbsp; 再举一个例子，property的文法如下：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #000000">(attributeInfo&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;accessor&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;memberType&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;inheritation&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;opt(type&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;COLON(NeedColon)&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;COLON(NeedColon))&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;ID(NeedId)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(OPEN_DECL_BRACE(NeedOpenDeclBrace)&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;(<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;opt(GET&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;statement)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;opt(opt(setterAccessor)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;(SET&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;statement))<br /></span><span style="color: #008080">5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;CLOSE_DECL_BRACE(NeedCloseDeclBrace))<br /></span><span style="color: #008080">6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)[ToPropertyMember]<br /></span><span style="color: #008080">7</span>&nbsp;<span style="color: #000000"></span></div><br />&nbsp;&nbsp;&nbsp; 这个东西的返回结果是pair&lt;pair&lt;pair&lt;pair&lt;pair&lt;a, b&gt;, c&gt;, d&gt;, e&gt;, pair&lt;list&lt;f&gt;, list&lt;list&lt;pair&lt;g, h&gt;&gt;&gt;&gt;。写起来也很令人发疯。因此这几天就想了一种方法来解决这种问题。<br /><br />&nbsp;&nbsp;&nbsp; 首先，我们一定要采取一种方法来让这种火箭一样的代码给平坦化。由于operator+的左结合特性，实际上我们无法去掉这些pair，因此只能换一种方法，譬如说让pair&lt;pair&lt;pair&lt;a, b&gt;, c&gt;, d&gt;总是等价于tuple&lt;a, b, c, d&gt;。这显然是可能的，只需要重载足够数量的tuple类型，就可以让typename tuple&lt;a, b, c, d&gt;::ResultType等于pair&lt;pair&lt;pair&lt;a, b&gt;, c&gt;, d&gt;。<br /><br />&nbsp;&nbsp;&nbsp; 其次，当我们面对这些pair&lt;pair&lt;pair&lt;a, b&gt;, c&gt;, d&gt;的时候，如何将他赋值到一个struct呢？假设struct的声明如下：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;s<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">{<br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;a&nbsp;_a;<br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;b&nbsp;_b;<br /></span><span style="color: #008080">5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;c&nbsp;_c;<br /></span><span style="color: #008080">6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;d&nbsp;_d;<br /></span><span style="color: #008080">7</span>&nbsp;<span style="color: #000000">};</span></div><br />&nbsp;&nbsp;&nbsp; 我们可以用下面的代码：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;s;<br /></span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">auto&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">ref</span><span style="color: #000000">(s._a)<br /></span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(s._b)<br /></span><span style="color: #008080">5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(s._c)<br /></span><span style="color: #008080">6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(s._d)<br /></span><span style="color: #008080">7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;;</span></div><br />&nbsp;&nbsp;&nbsp; 来让x等于pair&lt;pair&lt;pair&lt;*a, *b&gt;, *c&gt;, *d&gt;。因为&#8220;点&#8221;也是左结合的。后面只需要再用模板元编程就可以把pair&lt;pair&lt;pair&lt;a, b&gt;, c&gt;, d&gt;赋值给pair&lt;pair&lt;pair&lt;*a, *b&gt;, *c&gt;, *d&gt;了。<br /><br />&nbsp;&nbsp;&nbsp; 让我们看看<a style="text-decoration: underline" href="http://vlpp.codeplex.com" target="_blank">Vczh Library++3.0</a>源代码（Library\Scripting\Languages\ManagedX\ManagedXParser_Declaration.cpp）在使用了这个构造之前和之后的代码。首先是直接使用和读取pair的：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedMember</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;ToPropertyMember(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedAttributeInfo</span><span style="color: #000000">&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declatt::Accessor</span><span style="color: #000000">&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declatt::MemberType</span><span style="color: #000000">&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declatt::Inheritation</span><span style="color: #000000">&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedType</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ParsingList</span><span style="color: #000000">&lt;</span><span style="color: #000000">Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedType</span><span style="color: #000000">&gt;&gt;&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;RegexToken</span><span style="color: #000000">&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000"><br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ParsingList</span><span style="color: #000000">&lt;</span><span style="color: #000000">Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedStatement</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ParsingList</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingPair</span><span style="color: #000000">&lt;</span><span style="color: #000000">ParsingList</span><span style="color: #000000">&lt;</span><span style="color: #000000">declatt::Accessor</span><span style="color: #000000">&gt;</span><span style="color: #000000">,&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedStatement</span><span style="color: #000000">&gt;&gt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&gt;&gt;&amp;</span><span style="color: #000000">&nbsp;input)<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">{<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedProperty</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;member</span><span style="color: #000000">=</span><span style="color: #000000">CreateNode</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedProperty</span><span style="color: #000000">&gt;</span><span style="color: #000000">(input.First().Second());<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CopyAttributeInfo(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">attributeInfo,&nbsp;input.First().First().First().First().First().First().First());<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">accessor</span><span style="color: #000000">=</span><span style="color: #000000">input.First().First().First().First().First().First().Second();<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">memberType</span><span style="color: #000000">=</span><span style="color: #000000">input.First().First().First().First().First().Second();<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">inheritation</span><span style="color: #000000">=</span><span style="color: #000000">input.First().First().First().First().Second();<br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">type</span><span style="color: #000000">=</span><span style="color: #000000">input.First().First().First().Second();<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(input.First().First().Second().Head())<br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">implementedInterfaceType</span><span style="color: #000000">=</span><span style="color: #000000">input.First().First().Second().Head()</span><span style="color: #000000">-&gt;</span><span style="color: #000000">Value();<br /></span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">24</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">name</span><span style="color: #000000">=</span><span style="color: #000000">ConvertID(WString(input.First().Second().reading,&nbsp;input.First().Second().length));<br /></span><span style="color: #008080">25</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">26</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">setterAccessor</span><span style="color: #000000">=</span><span style="color: #000000">member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">accessor;<br /></span><span style="color: #008080">27</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(input.Second().First().Head())<br /></span><span style="color: #008080">28</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">29</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">getter</span><span style="color: #000000">=</span><span style="color: #000000">input.Second().First().Head()</span><span style="color: #000000">-&gt;</span><span style="color: #000000">Value();<br /></span><span style="color: #008080">30</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">31</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(input.Second().Second().Head())<br /></span><span style="color: #008080">32</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">33</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(input.Second().Second().Head()</span><span style="color: #000000">-&gt;</span><span style="color: #000000">Value().First().Head())<br /></span><span style="color: #008080">34</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /></span><span style="color: #008080">35</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">setterAccessor</span><span style="color: #000000">=</span><span style="color: #000000">input.Second().Second().Head()</span><span style="color: #000000">-&gt;</span><span style="color: #000000">Value().First().Head()</span><span style="color: #000000">-&gt;</span><span style="color: #000000">Value();<br /></span><span style="color: #008080">36</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">37</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">setter</span><span style="color: #000000">=</span><span style="color: #000000">input.Second().Second().Head()</span><span style="color: #000000">-&gt;</span><span style="color: #000000">Value().Second();<br /></span><span style="color: #008080">38</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080">39</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;member;<br /></span><span style="color: #008080">40</span>&nbsp;<span style="color: #000000">}<br /></span><span style="color: #008080">41</span>&nbsp;<span style="color: #000000"></span></div><br /><br />&nbsp;&nbsp;&nbsp; 其次是用tuple和ref来赋值的：
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedMember</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;ToPropertyMember(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;x::tp</span><span style="color: #000000">&lt;</span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedAttributeInfo</span><span style="color: #000000">&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declatt::Accessor,<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declatt::MemberType,<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;declatt::Inheritation,<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedType</span><span style="color: #000000">&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;x::opt</span><span style="color: #000000">&lt;</span><span style="color: #000000">Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedType</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;RegexToken,<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;x::tp</span><span style="color: #000000">&lt;</span><span style="color: #000000"><br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x::opt</span><span style="color: #000000">&lt;</span><span style="color: #000000">Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedStatement</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">,<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x::opt</span><span style="color: #000000">&lt;</span><span style="color: #000000">x::tp</span><span style="color: #000000">&lt;</span><span style="color: #000000">x::opt</span><span style="color: #000000">&lt;</span><span style="color: #000000">declatt::Accessor</span><span style="color: #000000">&gt;</span><span style="color: #000000">,&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedStatement</span><span style="color: #000000">&gt;&gt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">::ResultType</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;input)<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">{<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedProperty</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;member</span><span style="color: #000000">=</span><span style="color: #000000">CreateNode</span><span style="color: #000000">&lt;</span><span style="color: #000000">ManagedProperty</span><span style="color: #000000">&gt;</span><span style="color: #000000">(input.First().Second());<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;x::Fill(<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x::</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">attributeInfo)<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">accessor)<br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">memberType)<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">inheritation)<br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">type)<br /></span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">implementedInterfaceType)<br /></span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">name)<br /></span><span style="color: #008080">24</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(<br /></span><span style="color: #008080">25</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x::</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">getter)<br /></span><span style="color: #008080">26</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(<br /></span><span style="color: #008080">27</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x::</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">setterAccessor)<br /></span><span style="color: #008080">28</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.</span><span style="color: #0000ff">ref</span><span style="color: #000000">(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">setter)<br /></span><span style="color: #008080">29</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br /></span><span style="color: #008080">30</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br /></span><span style="color: #008080">31</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,&nbsp;input);<br /></span><span style="color: #008080">32</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">name</span><span style="color: #000000">=</span><span style="color: #000000">ConvertID(member</span><span style="color: #000000">-&gt;</span><span style="color: #000000">name);<br /></span><span style="color: #008080">33</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;member;<br /></span><span style="color: #008080">34</span>&nbsp;<span style="color: #000000">}<br /></span><span style="color: #008080">35</span>&nbsp;<span style="color: #000000"></span></div><br />&nbsp;&nbsp;&nbsp; 其简洁程度完全不同。<br /></div> <img src ="http://www.cppblog.com/vczh/aggbug/148630.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-06-14 15:01 <a href="http://www.cppblog.com/vczh/archive/2011/06/14/148630.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczhl Library++3.0之Parser Combinator为常见的语法结构做优化</title><link>http://www.cppblog.com/vczh/archive/2011/06/05/148106.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 05 Jun 2011 05:45:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/06/05/148106.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/148106.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/06/05/148106.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/148106.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/148106.html</trackback:ping><description><![CDATA[<div>&nbsp;&nbsp;&nbsp; 之前曾经<a style="text-decoration: underline" href="http://www.cppblog.com/vczh/archive/2010/04/28/113836.html" target="_blank">为Parser Combinator写过一篇教程</a>。这次为了处理<a style="text-decoration: underline" href="http://vlpp.codeplex.com" target="_blank">Vczh Library++</a>新设计的ManagedX托管语言，我为Parser Combinator新增了三个组合子。<br /><br />&nbsp;&nbsp;&nbsp; 第一个是def，第二个是let。它们组合使用。def(pattern, defaultValue)的意思是，如果pattern成功了那么返回pattern的分析结构，否则返回defaultValue。let(pattern, value)的意思是，如果pattern成功了则返回value，否则失败。因此他们可以一起使用。举个例子，ManagedX跟C#一样具有5种type accessor：public, protected, protected internal, private, internal。其中四种accessor的文法类型是token，剩下的protected internal则是tuple&lt;token, token&gt;。因此我们无法很方便地为它写一个记号到语法树的转换函数。而且对于缺省情况要返回private的这种行为，在EBNF+handler上直接表达出来也比较困难。当def和let还不存在的时候，我们需要这么写：<br /><br />&nbsp;&nbsp;&nbsp; accessor = (PUBLIC[ToAccessor] | PROTECTED[ToAccessor] | PRIVATE[ToAccessor] | INTERNAL[ToAccessor] | (PROTECTED + INTERNAL)[ToProtectedInternal])[ToAccessorWithDefault];<br /><br />&nbsp;&nbsp;&nbsp; 这个时候我们需要创建三个函数，分别是ToAccessor、ToProtectedInternal和ToAccessorWithDefault。因为accessor本身不是一个重要的语法元素，所以我们不需要为accessor记录一些源代码的位置信息。表达式则需要位置信息，这可以在我们产生错误信息的时候知道错误发生在源代码中的位置。而accessor总是直接属于某一个重要的语法元素的，所以不需要保存。如果不需要保存位置信息的话，那么一个ToXXX的函数其实就是没有必要的。这个时候可以让def和let来简化操作：<br /><br />&nbsp;&nbsp;&nbsp; accessor = def(<span style="color: #0000ff">let(PUBLIC, acc::Public) | let(PROTECTED, acc::Protected) | let(PRIVATE, acc::Private) | let(INTERNAL, acc::Internal) | let(PROTECTED+INTERNAL</span><span style="color: #0000ff">, acc::ProtectedInternal)</span>, acc::Private);<br /><br />&nbsp;&nbsp;&nbsp; 看起来好像差不多，但实际上我们已经减少了那三个不需要存在的函数。<br /><br />============================无耻的分割线====================================<br /><br />&nbsp;&nbsp;&nbsp; 第三个是binop。做这个主要是因为那个通用的lrec（左递归组合子）在对付带大量括号的表达式的时候性能表现不好。这里稍微解释一下原因。假设我们的语言有&gt;、+、*和()四种操作符，那文法一般都写成：<br /><br />&nbsp;&nbsp;&nbsp; exp0 = NUMBER | '(' exp3 ')'<br />&nbsp;&nbsp;&nbsp; exp1 = exp1 '*' exp0 | exp0<br />&nbsp;&nbsp;&nbsp; exp2 = exp2 '+' exp1 | exp1<br />&nbsp;&nbsp;&nbsp; exp3 = exp3 '&gt;' exp2 | exp2<br /><br />&nbsp;&nbsp;&nbsp; 因此可以很容易的知道，当我们分析1*2*3的时候，走的是下面的路子：<br />&nbsp;&nbsp;&nbsp; exp3<br />&nbsp;&nbsp;&nbsp;&nbsp;= exp2<br />&nbsp;&nbsp;&nbsp; = exp1<br />&nbsp;&nbsp;&nbsp; = exp1 '*' exp0<br />&nbsp;&nbsp;&nbsp; = exp1 '*' exp1 '*' exp0<br />&nbsp;&nbsp;&nbsp; = '1' '*' '2' '*' '3'<br /><br />&nbsp;&nbsp;&nbsp; 现在我们做一个简单的变换，把1*2*3变成((1*2)*3)。意义不变，但是分析的路径却完全改变了：<br />&nbsp;&nbsp;&nbsp; exp3<br />&nbsp;&nbsp;&nbsp; = exp2<br />&nbsp;&nbsp;&nbsp; = exp1<br />&nbsp;&nbsp;&nbsp; = exp0<br />&nbsp;&nbsp;&nbsp; = '(' exp3 ')'<br />&nbsp;&nbsp;&nbsp; = '(' exp2 ')'<br />&nbsp;&nbsp;&nbsp; = '(' exp1 ')'<br />&nbsp;&nbsp;&nbsp; = '(' exp1 '*' exp0 ')'<br />&nbsp;&nbsp;&nbsp; = '(' exo0 '*' exp0 ')'<br />&nbsp;&nbsp;&nbsp; = '(' '(' exp3 ')' '*' exp0 ')'<br />&nbsp;&nbsp;&nbsp; = '(' '(' exp2 ')' '*' exp0 ')'<br />&nbsp;&nbsp;&nbsp; = '(' '(' exp1 ')' '*' exp0 ')'<br />&nbsp;&nbsp;&nbsp; = '(' '(' exp1 '*' exp0 ')' '*' exp0 ')'<br />&nbsp;&nbsp;&nbsp; = '(' '(' exp0 '*' exp0 ')' '*' exp0 ')'<br />&nbsp;&nbsp;&nbsp; = '(' '(' '1' '*' '2' ')' '*' '3' ')'<br /><br />&nbsp;&nbsp;&nbsp; 咋一看好像没什么区别，但是对于ManagedX这种有十几个优先级的操作符的语言来说，如果给一个复杂的表达式的每一个节点都加上括号，等于一下子增加了上千层文法的递归分析。由于Parser Combinator是递归向下分析器，因此路径有这么长，那么递归的层次也会有这么长。而且为了避免boost::Spirit那个天杀的超慢编译速度的问题，这里牺牲了一点点性能，将组合字的Parse函数做成了虚函数，所以编译速度提高了超多。一般来说一个需要编译一个半小时的boost::Spirit语法分析器用我的库只需要几秒钟就可以编译完了。不过现在却带来了问题。括号一多，性能下降的比较明显。但是我们显然不能因噎废食，因此我决定往Parser Combinator提供一个手写的带优先级的左右结合一二元操作符语法分析器。为了将这个手写的分析器插入框架并变得通用，我决定采用下面的结构。下面的代码是从ManagedX的语法分析器中截取出来的： 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expression&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;binop(exp0)<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.pre(ADD_SUB,&nbsp;ToPreUnary).pre(NOT_BITNOT,&nbsp;ToPreUnary).pre(INC_DEC,&nbsp;ToPreUnary).precedence()<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(MUL_DIV_MOD,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(ADD_SUB,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(LT&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;LT,&nbsp;ToBinaryShift).lbin(GT&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;GT,&nbsp;ToBinaryShift).precedence()<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(LT,&nbsp;ToBinary).lbin(LE,&nbsp;ToBinary).lbin(GT,&nbsp;ToBinary).lbin(GE,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.post(AS&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type,&nbsp;ToCasting).post(IS&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type,&nbsp;ToIsType).precedence()<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(EE,&nbsp;ToBinary).lbin(NE,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(BITAND,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(XOR,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(BITOR,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(AND,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(OR,&nbsp;ToBinary).precedence()<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(QQ,&nbsp;ToNullChoice).precedence()<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.lbin(QT&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;(expression&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;COLON(NeedColon)),&nbsp;ToChoice).precedence()<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.rbin(OPEQ,&nbsp;ToBinaryEq).rbin(EQ,&nbsp;ToAssignment).precedence()<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;</span></div><br />&nbsp;&nbsp;&nbsp; binop组合子的参数代表整个带优先级的最高优先级表达式组合字（参考上面给出的&gt;+*()文法，可以知道这里的exp0是什么意思）。binop给出了四个子组合子，分别是pre（前缀一元操作符）、post（后缀一元操作符）、lbin（左结合二元操作符）和rbin（右结合二元操作符）。precedence代表一个优先级的所有操作符定义结束。这里我做了一个小限制，也就是每一个precedence只能包含pre、post、lbin和rbin的其中一种。实践表明这种限制不会带来任何问题。因此这里我们得到了一张操作符和优先级的关系表。到了这里我们就可以在Parser Combinator的框架下写一个手写的语法分析器（下载<a style="text-decoration: underline" href="http://vlpp.codeplex.com" target="_blank">源代码</a>并打开Library\Combinator\_Binop.h）来做了。至于如何手写语法分析器，我之前给出了<a style="text-decoration: underline" href="http://www.cppblog.com/vczh/archive/2008/06/15/53373.html" target="_blank">一篇文章</a>，大家可以参考这个来阅读_Binop.h。<br /><br />&nbsp;&nbsp;&nbsp; binop比起简单的用lrec做同样的事情，性能在debug下提高了100多倍，release下面则少一点。到了这里，Parser Combinator重新满足了性能要求，我们可以放心大胆的用一点点无所谓的性能换取一千多倍的编译时间了。在这里贴出当binop还没出现的时候我用lrec给出的操作符文法的实现： 
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;exp0<br /></span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;((ADD_SUB&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;NOT_BITNOT&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;INC_DEC)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp1)[ToUnary]<br /></span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br /></span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp1&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((MUL_DIV_MOD&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp1)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp2&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((ADD_SUB&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp2)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp3&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((((LT&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;LT)&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;(GT&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;GT))&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp3)[ToBinaryShiftLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp4&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(((LT&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;LE&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;GT&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;GE)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp4)[ToBinaryLrec]&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;(AS&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type)[ToCastingLrec]&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;(IS&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;type)[ToIsTypeLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp5&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(((EE&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;NE)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp5)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp6&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((BITAND&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp6)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp7&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((XOR&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp7)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp8&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((BITOR&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp8)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp9&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((AND&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp9)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp10&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((OR&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp10)[ToBinaryLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp11&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((QQ&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;exp11)[ToNullChoiceLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exp13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;lrec(exp12&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">((QT&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;(exp12&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;(COLON(NeedColon)&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;exp12)))[ToChoiceLrec]),&nbsp;ToLrecExpression);<br /></span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expression&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(exp13&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;OPEQ&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;expression)[ToBinaryEq]<br /></span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;(exp13&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;EQ&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;expression)[ToAssignment]<br /></span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">|</span><span style="color: #000000">&nbsp;exp13<br /></span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br /></span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000"><br /></span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000"></span></div><br /><br /></div><img src ="http://www.cppblog.com/vczh/aggbug/148106.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-06-05 13:45 <a href="http://www.cppblog.com/vczh/archive/2011/06/05/148106.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0托管语言语法树完成</title><link>http://www.cppblog.com/vczh/archive/2011/05/28/147476.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 28 May 2011 08:33:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/05/28/147476.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/147476.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/05/28/147476.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/147476.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/147476.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 经历了大约一个多星期的挑选，Vczh Library++3.0托管语言的语法树大约就定下来了。跟本地语言有一个缺省的语法叫NativeX一样，这次的语法就叫ManagedX了。当然ManagedX只是设计来直接反映托管语言语法树的一门语言，如果愿意的话，这个语法树还能被编译成其他长得像（嗯，只能是像，因为必须是托管的，有类没指针等）Basic啦Pascal那样...&nbsp;&nbsp;<a href='http://www.cppblog.com/vczh/archive/2011/05/28/147476.html'>阅读全文</a><img src ="http://www.cppblog.com/vczh/aggbug/147476.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-05-28 16:33 <a href="http://www.cppblog.com/vczh/archive/2011/05/28/147476.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0第一阶段宣告结束</title><link>http://www.cppblog.com/vczh/archive/2011/05/15/146419.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 15 May 2011 09:59:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/05/15/146419.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/146419.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/05/15/146419.html#Feedback</comments><slash:comments>21</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/146419.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/146419.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 我至今依稀还记得毕业前做<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>的伟大目标，就是实现把动态语言通过&#8220;动态语言&#8221;-&gt;&#8220;托管语言&#8221;-&gt;&#8220;本地语言&#8221;-&gt;&#8220;低级中间指令&#8221;-&gt;&#8220;X86代码&#8221;最终编译成机器码，同时开放出所有中间过程。这样的话添加一个就变成一个写parser的简单工作，添加一个类库会惠及所有语言，添加一个运行是目标（譬如说可以输出ARM等）可以让在这上面的所有语言都能运行在该目标是。现在第一个阶段完成了，就是把本地语言和低级中间指令给做了。<br><br>&nbsp;&nbsp;&nbsp; 其实现在叫本地语言不太合适，只是那个东西就是C+泛型+concept mapping的组合体，可以轻易被翻译成X86，所以才这么叫的。暂时还是写了个虚拟机直接执行低级中间指令。在整个开发过程中，我还给这种语言写了一个基本的函数库：字符串、数学函数、内存管理、垃圾收集（只是函数库，而不是语法，目前只有简单的暂时的实现）、线程、同步原语和线程池。有了这些设施之后就可以开始做托管语言了。<br><br>&nbsp;&nbsp;&nbsp; 托管语言比较麻烦的地方在于类库是必需的。譬如说字符串、数组和函数对象这些东西其实是无法靠语言本身做出来的，所以只能成为预定义的类库。那这些类库用什么写呢？当然是我们的本地语言（之前还写了一个叫NativeX的parser）啦。现在的设想就有，先把预定义的类库的声明用托管语言本身写出来，然后编译器会提供一个功能将托管语言编译成本地语言（目标箭头之一），然后把所有标记成&#8220;外部函数&#8221;的函数跳过。每一个函数在生成本地语言的时候都会给出一个经过计算的名字。然后只需要再用NativeX写出这些同名的函数实现就好了。剩下的一些能够用托管语言自己实现的函数，就可以整个被编译成本地语言。编译出来的本地语言会依赖与之前写出来的一个垃圾收集函数库。这种函数库在本地语言只有一个声明，脚本引擎在运行的时候可以给这些名字bind上一个实现。所以实际上垃圾收集函数库的实现是可以替换的（只是必须在初始化的时候指定）。将来万一我重写的实现不够好，人们还能自己搞一套出来换掉，达到他们不可告人的目的。<br><br>&nbsp;&nbsp;&nbsp; 至于托管语言本身有什么功能，肯定是抄自这个世界上最先进的<strong style="COLOR: red">弱类型以面向对象作为主要范式的托管语言</strong>——C#啦，啊哈哈哈哈。Java的<strong style="COLOR: red">语言本身</strong>根本没有被抄的价值。至于之后的动态语言，肯定是被编译到托管语言的。只是这个过程不会跟DLR那么简单直接把类型和表达式拿去映射。这里面可以做很多有趣的事情的，譬如尽量推导出动态语言里面每一个变量的类型约束（我们很多时候其实都知道动态语言里面的某个变量是有限若干个类型的集合的），然后为他们产生出更加有效的代码。这里可能会将一个函数编译成目的相同但是类型不同的几份（注意这里不是在做泛型展开）。<br><br>&nbsp;&nbsp;&nbsp; 第二个阶段就开始了。
<img src ="http://www.cppblog.com/vczh/aggbug/146419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-05-15 17:59 <a href="http://www.cppblog.com/vczh/archive/2011/05/15/146419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0开发纪事之流式xml和json读写</title><link>http://www.cppblog.com/vczh/archive/2011/04/18/144497.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Mon, 18 Apr 2011 13:34:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/04/18/144497.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/144497.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/04/18/144497.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/144497.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/144497.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 每次完成一个任务的时候，都要看看有没有什么潜在的可以把功能是现成库的地方。这十分有利于提高自己的水平。但至于你写出来的库会不会有人用，那是另一回事情了。</p>
<p>&nbsp;&nbsp;&nbsp; 这次为了完成一个多编程语言+多自然语言的文档编写工具，不得不做一个可以一次生成一大批文本文件的模板结构出来。有了模板必然有元数据，元数据必然是类似字符串的东西，所以顺手就支持了xml和json。为了应付巨大的xml和json，必然要做出xml和json的流式读写。大家应该听说过SAX吧，大概就是那样的。</p>
<p>&nbsp;&nbsp;&nbsp; 有了xml和json之后，就可以在上面实现query了。把xml和json统一起来是一个比较麻烦的问题，因为本身从结构上来看他们是不相容的。而且为了便于给vlscript.dll添加compiler service的支持，势必要在dll上面做出字符串到语法树或者语法树到字符串这样子的操作。本地dll接口显然不可能做出一个顺眼的异构树结构，因此势必要把语法树表示成xml或者json。因此就有了下面的结构：</p>
<p>&nbsp;&nbsp;&nbsp; 1、一颗简洁但是功能强大的字符串，在上面可以存放xml、json和强类型数据。<br>&nbsp;&nbsp;&nbsp; 2、可以把xml和树相互转换。<br>&nbsp;&nbsp;&nbsp; 3、可以把json和树相互转换。<br>&nbsp;&nbsp;&nbsp; 4、当树存放的是强类型数据（基本类型都会用字符串存放）的时候，树可以映射到一个带有约束的xml或者json结构上去。</p>
<p>&nbsp;&nbsp;&nbsp; 在这里可以展示一下什么是强类型数据。我们知道json表达的结构是弱类型的。当你拿到一个object的时候你不知道它的类型，你只知道他有多少个成员变量。强类型结构要求object有一个类型标记，数组也有一个类型标记（因为我们不能从数组的元素类型推断出数组本身的类型——因为类型可以拥有继承关系），基本类型还要可扩展（json只支持数字、字符串、布尔值和null，显然是不够的）。下面贴一个强类型数据结构的xml和json的表现形式：<br></p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Developer</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Languages</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">array:String</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">primitive:String&nbsp;</span><span style="COLOR: #ff0000">value&nbsp;</span><span style="COLOR: #0000ff">=&nbsp;"C++"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">primitive:String&nbsp;</span><span style="COLOR: #ff0000">value&nbsp;</span><span style="COLOR: #0000ff">=&nbsp;"C#"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">primitive:String&nbsp;</span><span style="COLOR: #ff0000">value&nbsp;</span><span style="COLOR: #0000ff">=&nbsp;"F#"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">primitive:String&nbsp;</span><span style="COLOR: #ff0000">value&nbsp;</span><span style="COLOR: #0000ff">=&nbsp;"Haskell"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">array:String</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Languages</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">primitive:String&nbsp;</span><span style="COLOR: #ff0000">value&nbsp;</span><span style="COLOR: #0000ff">=&nbsp;"vczh"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Project</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Project</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Host</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">primitive:String&nbsp;</span><span style="COLOR: #ff0000">value&nbsp;</span><span style="COLOR: #0000ff">=&nbsp;"Codeplex"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Host</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Language</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">primitive:String&nbsp;</span><span style="COLOR: #ff0000">value&nbsp;</span><span style="COLOR: #0000ff">=&nbsp;"C++"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Language</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Project</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Project</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Developer</span><span style="COLOR: #0000ff">&gt;</span></div>
<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$object</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Developer</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Languages</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$array</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;[{<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$primitive</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C++</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$primitive</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C#</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;{<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$primitive</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">F#</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;{<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$primitive</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Haskell</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}]<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;},<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Name</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;{<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$primitive</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">vczh</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;},<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Project</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;{<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$object</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Project</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Host</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;{<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$primitive</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Codeplex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Language</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;{<br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">$primitive</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">C++</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 上面的xml和json都是对一个相同的强类型数据结构的表示。我们可以看到$array、$object和$primitive是用来区分他们的实际类型的。<br><br>&nbsp;&nbsp;&nbsp; 下面是流式xml和json的读写的接口。可以很容易的看出用这种方法来读写xml和json必须将代码做成一个超级复杂的状态机才可以。这里太长贴不下，如果大家有兴趣的话可以去<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>下载最新代码并打开<br>&nbsp;&nbsp;&nbsp; Library\Entity\TreeXml.cpp<br>&nbsp;&nbsp;&nbsp; Library\Entity\TreeJson.cpp<br>&nbsp;&nbsp;&nbsp; Library\Entity\TreeQuery.cpp<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;XmlReader<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">enum</span><span style="COLOR: #000000">&nbsp;ComponentType<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ElementHeadOpening,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;name</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ElementHeadClosing,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ElementClosing,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attribute,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;name,&nbsp;value</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Text,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;value</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CData,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;value</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Comment,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;value</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BeginOfFile,<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EndOfFile,<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WrongFormat,<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;XmlReader(stream::TextReader</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_reader);<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">XmlReader();<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ComponentType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CurrentComponentType()</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;componentType;&nbsp;}<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CurrentName()</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;name;&nbsp;}<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CurrentValue()</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;value;&nbsp;}<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Next();<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsAvailable()</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;componentType</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">EndOfFile&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;componentType</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">WrongFormat;&nbsp;}<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;XmlWriter<br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;XmlWriter(stream::TextWriter</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_writer,&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;_autoNewLine</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_space</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">XmlWriter();<br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OpenElement(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;name);<br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseElement();<br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteElement(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;name,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteAttribute(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;name,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">39</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteText(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">40</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteCData(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteComment(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">42</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">43</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">44</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;JsonReader<br></span><span style="COLOR: #008080">45</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">46</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">47</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">enum</span><span style="COLOR: #000000">&nbsp;ComponentType<br></span><span style="COLOR: #008080">48</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">49</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectOpening,<br></span><span style="COLOR: #008080">50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectClosing,<br></span><span style="COLOR: #008080">51</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Field,<br></span><span style="COLOR: #008080">52</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayOpening,<br></span><span style="COLOR: #008080">53</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayClosing,<br></span><span style="COLOR: #008080">54</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bool,<br></span><span style="COLOR: #008080">55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Int,<br></span><span style="COLOR: #008080">56</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Double,<br></span><span style="COLOR: #008080">57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String,<br></span><span style="COLOR: #008080">58</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Null,<br></span><span style="COLOR: #008080">59</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">60</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BeginOfFile,<br></span><span style="COLOR: #008080">61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EndOfFile,<br></span><span style="COLOR: #008080">62</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WrongFormat,<br></span><span style="COLOR: #008080">63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">64</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">65</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;JsonReader(stream::TextReader</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_reader);<br></span><span style="COLOR: #008080">66</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">JsonReader();<br></span><span style="COLOR: #008080">67</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">68</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ComponentType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CurrentComponentType()</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;componentType;&nbsp;}<br></span><span style="COLOR: #008080">69</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CurrentValue()</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;value;&nbsp;}<br></span><span style="COLOR: #008080">70</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Next();<br></span><span style="COLOR: #008080">71</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsAvailable()</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;componentType</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">EndOfFile&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;componentType</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">WrongFormat;&nbsp;}<br></span><span style="COLOR: #008080">72</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">73</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">74</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;JsonWriter<br></span><span style="COLOR: #008080">75</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">76</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">77</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;JsonWriter(stream::TextWriter</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_writer,&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;_autoNewLine</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_space</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">78</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">JsonWriter();<br></span><span style="COLOR: #008080">79</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">80</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OpenObject();<br></span><span style="COLOR: #008080">81</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseObject();<br></span><span style="COLOR: #008080">82</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddField(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;name);<br></span><span style="COLOR: #008080">83</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OpenArray();<br></span><span style="COLOR: #008080">84</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseArray();<br></span><span style="COLOR: #008080">85</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteBool(</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">86</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteInt(vint&nbsp;value);<br></span><span style="COLOR: #008080">87</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteDouble(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">88</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteString(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;WString</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;value);<br></span><span style="COLOR: #008080">89</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteNull();<br></span><span style="COLOR: #008080">90</span>&nbsp;<span style="COLOR: #000000">};</span></div>
<br>&nbsp;&nbsp;&nbsp; 有xml自然要有xpath，只不过xpath用来处理json和强类型数据结构都有点力不从心，所以我打算修改xpath，做成适合查询我这种跟它们稍微有点不同的树的查询语句，然后加入到Vczh Library++3.0里面去。有了这个之后就可以做很多事情了，譬如说在模板生成器里面使用query来查询复杂的配置，譬如说在脚本语言里面支持xml和json，还有很多其他的等等。query写完之后就可以开始写一个可以一次生成一大批文本文件的模板生成器了。我会将模板生成本身写成一个可以扩展功能的库，最后再写一个DocWrite.exe利用这个库实现一个文档生成器。
<img src ="http://www.cppblog.com/vczh/aggbug/144497.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-04-18 21:34 <a href="http://www.cppblog.com/vczh/archive/2011/04/18/144497.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0第一个Release提供下载！</title><link>http://www.cppblog.com/vczh/archive/2011/03/20/142261.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 20 Mar 2011 05:07:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/03/20/142261.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/142261.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/03/20/142261.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/142261.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/142261.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 项目主页：<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>http://vlpp.codeplex.com</a><br>&nbsp;&nbsp;&nbsp; 下载页面：<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/releases/view/62850" target=_blank>http://vlpp.codeplex.com/releases/view/62850</a><br>&nbsp;&nbsp;&nbsp; 该Release对应的源代码：<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/SourceControl/changeset/view/70602" target=_blank>http://vlpp.codeplex.com/SourceControl/changeset/view/70602</a><br><br>&nbsp;&nbsp;&nbsp; 第一个release没有文档，因此接下去我得做一个双语的文档生成工具了，然后会在下一个release里面添加完整的NativeX语言和脚本引擎API的文档。因此现在要学习如何使用NativeX和脚本引擎的API的话，可以下载源代码然后到下面的目录寻找资料：<br>&nbsp;&nbsp;&nbsp; 1、UnitTest\Binary\TestFiles\Code：我的单元测试工程使用的NativeX脚本代码<br>&nbsp;&nbsp;&nbsp; 2、UnitTest\Binary\ScriptCoreLibrary：NativeX预定义函数库的源代码<br>&nbsp;&nbsp;&nbsp; 3、Tools\Release\VleSource\VlScriptDotNet：vlscript.dll的.NET封装<br>&nbsp;&nbsp;&nbsp; 4、Tools\Release\VleSource\VlTurtle：使用vlscriptdotnet.dll开发的&#8220;强大的乌龟&#8221;<br><br>&nbsp;&nbsp;&nbsp; 因此下载release之后，可以打开Turtle\VlTurtle.exe，然后玩之。一个简单的方法是，打开内置的sample然后点Run，如图：<br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/vczh/Turtle_Sample_07.jpg" width=1147 height=768><br><br>
<img src ="http://www.cppblog.com/vczh/aggbug/142261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-03-20 13:07 <a href="http://www.cppblog.com/vczh/archive/2011/03/20/142261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0之乌龟画图Demo接近完工</title><link>http://www.cppblog.com/vczh/archive/2011/03/11/141611.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Fri, 11 Mar 2011 14:20:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/03/11/141611.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/141611.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/03/11/141611.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/141611.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/141611.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 这是一个小Demo，用来介绍如何使用C#来调用我C++给出的NativeX编译器和虚拟机的。具体的代码可以在<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>里面找到。<br><br>&nbsp;&nbsp;&nbsp; VlTurtle.exe的工作原理十分简单。首先界面由Ribbon和Intellisense构成（超难写，难免会有些问题&#8230;&#8230;），其次按Run的时候会将代码保存到Script\NativeX\NativeX.txt里面，使用Vle.exe编译Script\NativeX\Make.txt，生成assembly文件。如果编译失败，就会出现Error.txt，然后这个编辑器将这个文件读回去显示在界面上。编译成功之后，使用参数&#8220;Execute&#8221;再启动自己一次，新进程会读生成的assembly文件并使用vlscript.dll的虚拟机函数初始化，寻找main函数并执行。<br><br>&nbsp;&nbsp;&nbsp; 第一个alpha版本的Release我并不打算把编译器也做进vlscript.dll（其实代码都在，就是没extern），而打算让Vle.exe充当编译器的作用。目前这个破Demo还没做完，New/Open/Save/Save As/Stop点了没反应，而且Run是阻塞的——也就是执行进程没退出，编辑器就会假死。先偷懒了，过几天再改好他，顺便给那只破乌龟加点功能美化一下&#8230;&#8230;<br><br>&nbsp;&nbsp;&nbsp; 下面先贴图。<br><br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/vczh/Turtle_Sample_06.jpg" width=488 height=768><br><br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/vczh/Turtle_Sample_05.jpg" width=816 height=638><br><br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/vczh/Turtle_Sample_04.jpg" width=816 height=638> 
<img src ="http://www.cppblog.com/vczh/aggbug/141611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-03-11 22:20 <a href="http://www.cppblog.com/vczh/archive/2011/03/11/141611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>着手给Vczh Library++ 3.0的脚本引擎制作第一个Release</title><link>http://www.cppblog.com/vczh/archive/2011/02/20/140330.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 20 Feb 2011 07:29:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/02/20/140330.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/140330.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/02/20/140330.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/140330.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/140330.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; <a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++ 3.0</a>这破东西也做了一年半了，因此打算给它制作第一个Release。这个Release将计划包含下面的东西：<br><br>&nbsp;&nbsp;&nbsp; 1、vle.exe。这是一个编译器和虚拟机的命令行程序。通过这个程序可以把NativeX程序编译成assembly、可以执行基于控制台的assembly程序、以及运行我为这个平台开发的一个单元测试工具。这些是已经开发完成的了。接下来还要给vle.exe添加链接功能。所谓的链接功能是指将多个assembly合并成一个，并且预先展开所有模板函数、模板变量和concept mapping等等。虽然NativeX程序跟C语言很像（多了泛型和concept mapping），也需要头文件，不过其机制并不像#include那样把文件复制进去，而是类似pascal。为了调用另一个assembly而必须的头文件可以让编译器在编译的过程中产生，不需要人去维护。<br><br>&nbsp;&nbsp;&nbsp; 2、vlscript.dll。这是一个编译器和虚拟机的函数库。这个函数库将会制作成C而不是C++的格式。我在尽可能让vlscript.dll包含vle.exe所具有的全部功能以外，还要添加一些其他的譬如可以遍历一个assembly里面各种声明什么的的一些功能，以便二次开发的时候可以利用vlscript.dll完成很多有趣的事情。<br><br>&nbsp;&nbsp;&nbsp; 3、TurtleDotNet.exe。这暂时还是一个设想。还记得旧社会的LOGO语言吧？最近新出的Microsoft Small Basic也跟LOGO一样可以使用乌龟画图。这是一个很好的教程式的函数库，因此我也打算做一个。因为时间的关系，我并不会在第一个Release里面包含一个NativeX的IDE，而只是包含一个C#写的窗口程序，可以读取assembly并提供乌龟画图的功能。这也同时展示了C#如何跟C的dll进行互操作。<br><br>&nbsp;&nbsp;&nbsp; 4、各种NativeX的demo。现在已经开发好的demo包含一个四则运算分析器的程序。这个程序从字符串生成语法树（NativeX也可以利用虚函数表来模拟多态，虽然这需要人肉完成而不是语法完成），然后做各种事情。我还附带一个四则运算分析库的单元测试程序。另一个开发好的demo是一个猜数字游戏。程序随机产生4个0-9范围内的数字，然后让你也输入4个，告诉你命中了多少，半命中（数字对位置不对）了多少，然后一直到你放弃或者猜中为止，程序结束。<br><br>&nbsp;&nbsp;&nbsp; 上面已经开发好的东西已经check in在codeplex里面了，感兴趣的话可以<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>自行下载</a>。不过那个vle.exe是以源代码的形式存放的（不像Release，都是编译好的东西），因此如果想要看到效果的话，需要装有Visual Studio 2010。编译完之后，在Tools\Release\Vlpp\和Tools\Release\Vlpp\ScriptSample\CrossAssemblyInvoking\Binary\下面有Readme.txt，会告诉你在编译完vle.exe之后如何部署他们，使得上述的两个NativeX demo可以编译和运行。<br><br>&nbsp;&nbsp;&nbsp; 拭目以待吧，哇哈哈。 
<img src ="http://www.cppblog.com/vczh/aggbug/140330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-02-20 15:29 <a href="http://www.cppblog.com/vczh/archive/2011/02/20/140330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开始为Vczh Library++3.0的NativeX写库</title><link>http://www.cppblog.com/vczh/archive/2011/01/01/137861.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 01 Jan 2011 13:14:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2011/01/01/137861.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/137861.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2011/01/01/137861.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/137861.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/137861.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 根据之前的计划，让<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>的编译器变成语言的公共后端的同时，开放几乎所有层的API让人们可以从各种基础上开发自己的DSL，所以在做完NativeX之后，接下来的事情就是写必要程度的库之后，做一些基础设施让托管语言可以被编译到NativeX上面去。因此现在需要完成的东西有：<br>&nbsp;&nbsp;&nbsp; 1、内存池，用来实现NativeX的new和delete。这个已经做完了。下一篇文章将详细描述这个内存池的结构。<br>&nbsp;&nbsp;&nbsp; 2、线程和同步对象。这个很快就做完了。NativeX的线程不仅需要有基本的功能，还需要做一个内置的消息循环。当一部分线程选择使用消息循环作为它的结构的时候，其他线程就可以把一些代码片段发送给这个线程执行了。并且要做到跟C#一样，当线程被外部强行中止的时候，线程内部会抛出一个异常，然后让线程自己去处理。<br>&nbsp;&nbsp;&nbsp; 3、基本的字符串和数学函数库<br>&nbsp;&nbsp;&nbsp; 4、垃圾收集器。这个垃圾收集器是不属于NativeX的语法的。这个垃圾收集器将被开发成一个NativeX的函数库，用于支持更高层次语言的编译。<br><br>&nbsp;&nbsp;&nbsp; 当然为了完成这个目标，我给NativeX加上了一些无关痛痒但是却会带来方便的语法：<br>&nbsp;&nbsp;&nbsp; 1、#public编译选项。只要在structure、function或者variable上面标记了#public的话，这个特殊的标志就会被记录在编译后的二进制文件的元数据里面。NativeX现在的元数据分为两种。第一种是运行时元数据。<a style="TEXT-DECORATION: underline" href="http://www.cppblog.com/vczh/archive/2010/08/26/124864.html" target=_blank>之前的文章</a>提到NativeX的模板函数和其他模板的东西都是可以直接编译进二进制文件的，因此模板函数的实例化实际上是在运行是的时候做的。不过现在我也实现了一个编译选项（不属于NativeX，需要用C++去控制），<strong style="COLOR: red">可以在编译完所有二进制文件之后，将他们合并成一个大的二进制文件并且预先展开所有需要的模板函数</strong>。这一步可以用于加快运行速度，还可以为将来运行时编译成x86或者x64做准备。当#public被记录到元数据里面之后，编译器就可以从编译好的二进制文件里面重新还原出该二进制文件的头文件。<br>&nbsp;&nbsp;&nbsp; 2、sizeof(type)、offsetof(type::member)、typeof(expression)和typeof(type::member)。这个纯粹是为了配合内存池和未来的垃圾收集器而做出来的。当你需要alloc一个东西的时候，你显然需要知道一个类型的尺寸，而这个是会跟随着不同的情况而变化的，所以就给出了这些东西，让编译器帮助你计算各种跟类型相关的数字。<br>&nbsp;&nbsp;&nbsp; 3、常量定义。这个还没实现，到时候的语法可能会是constant type name = value;。而且当他被标记上#public之后，就可以在生成头文件的时候包含该常量了。<br><br>&nbsp;&nbsp;&nbsp; 为了让C++可以给NativeX添加外部函数，我做了一个辅助类用来简化这个过程。举个例子，我们需要实现一个叫做MemCreate的创建内存池的函数。首先我们需要在NativeX里面声明它：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;__ForeignHandle<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">foreign&nbsp;function&nbsp;__ForeignHandle</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;__MemCreate()<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;SystemCoreForeignFunctions.MemCreate;</span></div>
<br>&nbsp;&nbsp;&nbsp; 这里的alias后面的一大串是外部函数的名称，而__MemCreate则是他对于NativeX的名称。接下来我们就得在C++实现这个函数了：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;&nbsp;1</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ScriptingUtilityForeignFunctions.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;2</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">..\Languages\LanguageRuntime.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;3</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">..\..\Entity\GeneralObjectPoolEntity.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;4</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">..\..\Threading.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;vl<br></span><span style="COLOR: #008080">&nbsp;&nbsp;7</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;scripting<br></span><span style="COLOR: #008080">&nbsp;&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;utility<br></span><span style="COLOR: #008080">&nbsp;11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;basicil;<br></span><span style="COLOR: #008080">&nbsp;13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;entities;<br></span><span style="COLOR: #008080">&nbsp;14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;collections;<br></span><span style="COLOR: #008080">&nbsp;15</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;SystemCoreMemoryManagerPlugin&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;LanguagePlugin<br></span><span style="COLOR: #008080">&nbsp;17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;PoolPackage<br></span><span style="COLOR: #008080">&nbsp;20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GeneralObjectPool&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pool;<br></span><span style="COLOR: #008080">&nbsp;22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cs;<br></span><span style="COLOR: #008080">&nbsp;23</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PoolPackage(vint&nbsp;poolUnitSize,&nbsp;vint&nbsp;poolUnitCount)<br></span><span style="COLOR: #008080">&nbsp;25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:pool(poolUnitSize,&nbsp;poolUnitCount)<br></span><span style="COLOR: #008080">&nbsp;26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">&nbsp;29</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pools;<br></span><span style="COLOR: #008080">&nbsp;31</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pluginCs;<br></span><span style="COLOR: #008080">&nbsp;32</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MemCreate&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Object,&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;IBasicILForeignFunction<br></span><span style="COLOR: #008080">&nbsp;34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SystemCoreMemoryManagerPlugin</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plugin;<br></span><span style="COLOR: #008080">&nbsp;37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;38</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MemCreate(SystemCoreMemoryManagerPlugin</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;_plugin)<br></span><span style="COLOR: #008080">&nbsp;39</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:plugin(_plugin)<br></span><span style="COLOR: #008080">&nbsp;40</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;42</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;43</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Invoke(BasicILInterpretor</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;interpretor,&nbsp;BasicILStack</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;stack,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;result,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;arguments)<br></span><span style="COLOR: #008080">&nbsp;44</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;45</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LanguageArgumentReader&nbsp;reader(result,&nbsp;arguments,&nbsp;stack);<br></span><span style="COLOR: #008080">&nbsp;46</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;pool</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;PoolPackage(</span><span style="COLOR: #000000">1048576</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;47</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;48</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection::Scope&nbsp;scope(plugin</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">pluginCs);<br></span><span style="COLOR: #008080">&nbsp;49</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plugin</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">pools.Add(pool);<br></span><span style="COLOR: #008080">&nbsp;50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Result</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">()</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">pool.Obj();<br></span><span style="COLOR: #008080">&nbsp;51</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;52</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">&nbsp;53</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;54</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;vint&nbsp;MemAlloc(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;result,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;arguments)<br></span><span style="COLOR: #008080">&nbsp;55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;56</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LanguageArgumentReader&nbsp;reader(result,&nbsp;arguments);<br></span><span style="COLOR: #008080">&nbsp;57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PoolPackage</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pool</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;58</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vint&nbsp;size</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">vint</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;59</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;60</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection::Scope&nbsp;scope(pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">cs);<br></span><span style="COLOR: #008080">&nbsp;61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Result</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">()</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">pool.Alloc(size);<br></span><span style="COLOR: #008080">&nbsp;62</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;reader.BytesToPop();<br></span><span style="COLOR: #008080">&nbsp;63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;64</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;65</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;vint&nbsp;MemFree(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;result,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;arguments)<br></span><span style="COLOR: #008080">&nbsp;66</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;67</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LanguageArgumentReader&nbsp;reader(result,&nbsp;arguments);<br></span><span style="COLOR: #008080">&nbsp;68</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PoolPackage</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pool</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;69</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pointer</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;70</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;71</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection::Scope&nbsp;scope(pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">cs);<br></span><span style="COLOR: #008080">&nbsp;72</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Result</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">()</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">pool.Free(pointer);<br></span><span style="COLOR: #008080">&nbsp;73</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;reader.BytesToPop();<br></span><span style="COLOR: #008080">&nbsp;74</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;75</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;76</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;vint&nbsp;MemIsValidHandle(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;result,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;arguments)<br></span><span style="COLOR: #008080">&nbsp;77</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;78</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LanguageArgumentReader&nbsp;reader(result,&nbsp;arguments);<br></span><span style="COLOR: #008080">&nbsp;79</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PoolPackage</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pool</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;80</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pointer</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;81</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;82</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection::Scope&nbsp;scope(pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">cs);<br></span><span style="COLOR: #008080">&nbsp;83</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Result</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">()</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">pool.IsValid(pointer);<br></span><span style="COLOR: #008080">&nbsp;84</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;reader.BytesToPop();<br></span><span style="COLOR: #008080">&nbsp;85</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;86</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;87</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;vint&nbsp;MemGetHandleSize(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;result,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;arguments)<br></span><span style="COLOR: #008080">&nbsp;88</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;89</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LanguageArgumentReader&nbsp;reader(result,&nbsp;arguments);<br></span><span style="COLOR: #008080">&nbsp;90</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PoolPackage</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pool</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;91</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pointer</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">&nbsp;92</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;93</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection::Scope&nbsp;scope(pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">cs);<br></span><span style="COLOR: #008080">&nbsp;94</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Result</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">vint</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">()</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">pool.GetSize(pointer);<br></span><span style="COLOR: #008080">&nbsp;95</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;reader.BytesToPop();<br></span><span style="COLOR: #008080">&nbsp;96</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;97</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;98</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;vint&nbsp;MemGetOwnerHandle(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;result,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;arguments)<br></span><span style="COLOR: #008080">&nbsp;99</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">100</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LanguageArgumentReader&nbsp;reader(result,&nbsp;arguments);<br></span><span style="COLOR: #008080">101</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PoolPackage</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pool</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PoolPackage</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">102</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pointer</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">reader.NextArgument</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">();<br></span><span style="COLOR: #008080">103</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">104</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CriticalSection::Scope&nbsp;scope(pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">cs);<br></span><span style="COLOR: #008080">105</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Result</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">()</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">pool</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">pool.GetHandle(pointer);<br></span><span style="COLOR: #008080">106</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;reader.BytesToPop();<br></span><span style="COLOR: #008080">107</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">108</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">109</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;RegisterForeignFunctions(BasicILRuntimeSymbol</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;symbol)<br></span><span style="COLOR: #008080">110</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">111</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">112</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">RegisterForeignFunction(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SystemCoreForeignFunctions</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MemCreate</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;MemCreate(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">))&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">113</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">RegisterLightFunction(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SystemCoreForeignFunctions</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MemAlloc</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;MemAlloc)&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">114</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">RegisterLightFunction(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SystemCoreForeignFunctions</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MemFree</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;MemFree)&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">115</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">RegisterLightFunction(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SystemCoreForeignFunctions</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MemIsValidHandle</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;MemIsValidHandle)&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">116</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">RegisterLightFunction(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SystemCoreForeignFunctions</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MemGetHandleSize</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;MemGetHandleSize)&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">117</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">RegisterLightFunction(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SystemCoreForeignFunctions</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MemGetOwnerHandle</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;MemGetOwnerHandle);<br></span><span style="COLOR: #008080">118</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">119</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">120</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">121</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LanguagePlugin</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;CreateMemoryManagerPlugin()<br></span><span style="COLOR: #008080">122</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">123</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;SystemCoreMemoryManagerPlugin();<br></span><span style="COLOR: #008080">124</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">125</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">126</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">127</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 外部函数分两种，一种是需要全局状态的，而另一种不需要。在不需要的时候，我提供了一个不会跟虚函数打交道的接口来加快（虽然其实可以忽略，只是为了满足那些有畸形性能欲望的人的心理而已）运行时的性能。<br><br>&nbsp;&nbsp;&nbsp; 就先说到这里了。NativeX函数库的测试用例已经开始在做了，可以去<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>下载最新代码之后，在下面的目录找到：<br>&nbsp;&nbsp;&nbsp; Library\Scripting\Utility\：这里是外部函数的实现。<br>&nbsp;&nbsp;&nbsp; UnitTest\Binary\ScriptCoreLibrary\：这里是NativeX将外部函数简单的封装起来之后的函数库，以及他们的测试用例。我为NativeX实现了一个简单的单元测试框架。<br>&nbsp;&nbsp;&nbsp; UnitTest\UnitTest\TestScripting_Utility_System_CoreNative.cpp：这个是NativeX单元测试框架的host。<br>
<img src ="http://www.cppblog.com/vczh/aggbug/137861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2011-01-01 21:14 <a href="http://www.cppblog.com/vczh/archive/2011/01/01/137861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++的NativeX语言最后一个特性完成——异常处理</title><link>http://www.cppblog.com/vczh/archive/2010/08/28/125062.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 28 Aug 2010 09:14:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/08/28/125062.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/125062.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/08/28/125062.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/125062.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/125062.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 因为在开发<a style="TEXT-DECORATION: underline" href="http://www.cppblog.com/vczh/archive/2009/05/22/85424.html" target=_blank>CMinus</a>的过程中为了异常处理（最终没有实现进CMinus），曾经学习了一下<a style="TEXT-DECORATION: underline" href="http://www.cppblog.com/vczh/archive/2009/03/03/75432.html" target=_blank>怎么用汇编语言写try-catch</a>，因此这个CPU相关的处理方法就被我偷了哈，实现在了<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>NativeX</a>的虚拟机里。<br><br>&nbsp;&nbsp;&nbsp; 在NativeX里面，try-catch和throw非常简单。throw你可以加一个值当异常数据，也可以不加（不会修改上次的异常数据，可以当rethrow用）。catch的话没办法跟C++一样根据类型来判断，因此我会给你一个异常数据的指针，你自己看着办哈，因为NativeX跟C一样没有RTTI。因此throw就很简单了，就是恢复栈顶和栈底指针之后跳转到最近的异常处理程序里面去。try和catch就是用来创建和销毁异常处理程序的。所有的异常处理程序构成了一个链表，这个链表被我记在了堆栈里面，而最近的异常处理节点的指针则被我放在了整个堆栈控件的最顶部，接在后面的是异常对象的数据。你每次throw的东西的尺寸可以不同，因此占用的&#8220;堆栈最顶部空间&#8221;也不同。当然如果你函数递归太深而导致栈顶覆盖了异常对象的数据区域时，就会触发&#8220;堆栈溢出&#8221;事件。在NativeX里面堆栈溢出代表你这程序已经废了，因此这个是不能catch的，虚拟机返回给宿主程序一个信号然后就停止执行了。<br><br>&nbsp;&nbsp;&nbsp; 我们来看一个简单的例子，如何throw之后把异常对象的返回给函数，首先是代码：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">NativeX&nbsp;Code</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;nativex_program_generated;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;main()<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;10s32);<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throw();<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">int32</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(exception)));<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Throw()<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000">&nbsp;20s32;</span></div>
<br>&nbsp;&nbsp;&nbsp; main函数首先将函数返回值设置成10，然后调用throw函数。throw函数会把20给throw出来，然后main函数catch了，把结果返回。NativeX使用了关键字exception来表达异常对象的地址。当然你如果要throw各种不同的东西的话，你得自己做标记（亲自实现RTTI）了。好了，我们看看产生的指令：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result&nbsp;=&nbsp;10s32);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;try</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">:&nbsp;exception_handler_push&nbsp;</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Throw();</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">:&nbsp;stack_top&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">:&nbsp;call&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;try</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">:&nbsp;exception_handler_pop<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">:&nbsp;jump&nbsp;</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">:&nbsp;exception_handler_pop<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result&nbsp;=&nbsp;(&nbsp;*&nbsp;cast&lt;int32*&gt;(exception)));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">:&nbsp;exception_object_address<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">17</span><span style="COLOR: #000000">:&nbsp;copymem&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">19</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;void&nbsp;Throw()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;throw&nbsp;20s32;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">:&nbsp;exception_object_reserve&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">22</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">:&nbsp;exception_object_address<br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">25</span><span style="COLOR: #000000">:&nbsp;exception_raise<br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;void&nbsp;Throw()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">39</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">27</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span></div>
<br>&nbsp;&nbsp;&nbsp; try首先会将catch之后的第一个指令给exception_handler_push了，在try的结尾当然要取消掉这个异常处理函数了，因此pop一下，然后jump到catch后面。当然catch的第一件事也是exception_handler_pop。exception_object_reserve在栈顶预留指定的空间来存放异常对象，exception_object_address则是获得异常对象的地址，exception_raise就是跳转到最近的异常处理函数了。raise不会把异常处理函数的记录给pop掉，所以要靠catch自己去pop。<br><br>&nbsp;&nbsp;&nbsp; NativeX已经完成了，接下来就可以开始打造周边工具了哇哈哈。将来的目标是将类似C#和Javascript的语言都编译到NativeX上，然后为这三类语言写很多语法分析器，然后他们就变成很多语言了。当然这些语言只是demo。<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++</a>的目的是提供实现编译器的中间每一层的类库，因此想干嘛就可以干嘛了哈。
<img src ="http://www.cppblog.com/vczh/aggbug/125062.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-08-28 17:14 <a href="http://www.cppblog.com/vczh/archive/2010/08/28/125062.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0完成了NativeX语言的所有泛型语法</title><link>http://www.cppblog.com/vczh/archive/2010/08/26/124864.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Thu, 26 Aug 2010 11:09:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/08/26/124864.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/124864.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/08/26/124864.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/124864.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/124864.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 如上一篇文章所说，Vczh Library++3.0的NativeX语言实现了计划的所有泛型语法。让我们来看一个简单的例子：我们为类型写一个Equals函数。我们可以为普通类型，譬如int32写一个Equals函数。我们有Vector&lt;T&gt;类型，只要T类型拥有一个Equals函数，那么Vector&lt;T&gt;显然也可以有Equals函数。问题...&nbsp;&nbsp;<a href='http://www.cppblog.com/vczh/archive/2010/08/26/124864.html'>阅读全文</a><img src ="http://www.cppblog.com/vczh/aggbug/124864.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-08-26 19:09 <a href="http://www.cppblog.com/vczh/archive/2010/08/26/124864.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>三个星期没有更新博客了</title><link>http://www.cppblog.com/vczh/archive/2010/08/07/122510.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 07 Aug 2010 02:31:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/08/07/122510.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/122510.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/08/07/122510.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/122510.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/122510.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 最近在忙一些其他的事情。因为工作的关系我稍微花了点时间研究了一下C#，因此就没往博客上写文章了。<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++ 3.0</a>的工作也暂停了半个月，下个星期就要开始恢复了。最近Codeplex服务器的URL修改了导致项目连接不上，后来还是修掉了，主要是得手动更改sln文件的内容，花了好久才知道怎么做。<br><br>&nbsp;&nbsp;&nbsp; 目前的进度是实现了generic constraint的数据结构但是没有加入语法分析和语义分析的内容。generic constraint比较简单，就如同C#的那个where，我可以写：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;T&nbsp;:&nbsp;IEq<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;T&nbsp;:&nbsp;ISort<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;where&nbsp;T&nbsp;:&nbsp;IEq<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">where&nbsp;T&nbsp;:&nbsp;ISort<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Sort(T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;values,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;count)<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 这是很重要的，因为没有了where，在Sort下面就没办法使用ISort和IEq里面定义的函数了。在NativeX可以成为一门真正可以使用的中间语言之前，还必须实现下面的功能：<br><br>&nbsp;&nbsp;&nbsp;1、 generic constraint<br>&nbsp;&nbsp;&nbsp;&nbsp;2、concept instance函数调用<br>&nbsp;&nbsp;&nbsp; 3、异常处理<br>&nbsp;&nbsp;&nbsp; 4、外部函数接口<br>&nbsp;&nbsp;&nbsp; 5、调试器接口<br>&nbsp;&nbsp;&nbsp; 6、装载的时候检查元数据引入表是否匹配了所有已经加载的assembly<br><br>&nbsp;&nbsp;&nbsp; 剩下的事情也不多了，就慢慢做吧。做完之后就可以开始写一些parser来验证这个NativeX究竟行不行了，我可以将Python和Basic都修改成一个类似C的语言（可以处理指针，没有垃圾收集，等），然后把它编译成NativeX的语法树，这样就可以开发一个支持多语言的编程接口并测试它了。
<img src ="http://www.cppblog.com/vczh/aggbug/122510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-08-07 10:31 <a href="http://www.cppblog.com/vczh/archive/2010/08/07/122510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0实现泛型全局存储</title><link>http://www.cppblog.com/vczh/archive/2010/07/18/120688.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 18 Jul 2010 05:28:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/07/18/120688.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/120688.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/07/18/120688.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/120688.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/120688.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 根据之前的文章的讨论，Vczh Library++3.0泛型全局存储是一个大型的映射。假设你有下面的代码：1&nbsp;generic&lt;T&gt;2&nbsp;structure&nbsp;StorageType3&nbsp;{4&nbsp;&nbsp;&nbsp;wchar*&nbsp;name;5&nbsp;&nbsp;&nbsp;T&nbsp;...&nbsp;&nbsp;<a href='http://www.cppblog.com/vczh/archive/2010/07/18/120688.html'>阅读全文</a><img src ="http://www.cppblog.com/vczh/aggbug/120688.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-07-18 13:28 <a href="http://www.cppblog.com/vczh/archive/2010/07/18/120688.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0之NativeX语言泛型最终稿</title><link>http://www.cppblog.com/vczh/archive/2010/07/13/120248.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Tue, 13 Jul 2010 12:26:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/07/13/120248.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/120248.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/07/13/120248.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/120248.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/120248.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; <a style="TEXT-DECORATION: underline" href="http://www.cppblog.com/vczh/archive/2010/06/19/118247.html" target=_blank>第三篇草稿</a>讲了泛型concept的概念，这篇最终稿可以确定<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++ 3.0</a>的NativeX所要支持的泛型concept的比较精确的特性了。<br><br>&nbsp;&nbsp;&nbsp; 泛型的concept的概念还是比较清晰的，这次我们便通过一个例子来讲解他。假如在NativeX里面实现一个列表，显然因为NativeX只有指针，所以写起来大概就是：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;List<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;items;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;count;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 于是我们想写一个函数判断两个List是否相等。因为<a style="TEXT-DECORATION: underline" href="http://www.cppblog.com/vczh/archive/2010/07/12/120141.html" target=_blank>NativeX现在已经有模板函数了</a>，所以我们很简单的一个想法是，传入两个List&lt;T&gt;*，然后再传入一个函数指针function bool(T,T)，就可以写出下面的函数了：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;ListEquals(List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000">&nbsp;xs,&nbsp;List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000">&nbsp;ys,&nbsp;function&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">(T,T)&nbsp;comparer)<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(xs</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">yx</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count)<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;current</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">xs</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(current</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">comparer(xs</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">items[current],&nbsp;yx</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">items[current]))<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 这个做法咋一看好像没什么问题，但是如果我们要比较List&lt;List&lt;int&gt;&gt;怎么办呢？我们可以先写一个function bool IntEquals(int a, int b);，然后再写一个function bool IntListEquals(List&lt;T&gt; a, List&lt;T&gt; b);，这个函数里面用IntEquals加上ListEquals&lt;int&gt;来实现，最后将他传进ListEquals&lt;List&lt;int&gt;&gt;。到了这里还好，如果我们还想比较List&lt;List&lt;double&gt;&gt;、List&lt;List&lt;char&gt;&gt;等等，我们就要被迫搞出很多函数了。而且最大的问题是，当我们写好这么多东西以后，我们想实现一个Find函数来查找List里面的对象的话，面对List&lt;List&lt;int&gt;&gt;、List&lt;List&lt;double&gt;&gt;等等的东西，我们又得重新写一次了&#8230;&#8230;<br><br>&nbsp;&nbsp;&nbsp; 这个问题在面向对象的语言里面都很容易做到，只需要在一个类里面实现operator==就可以了。那这两种方法有什么区别呢？假设我们把C++里面的类去掉，那么我们会发现，ListEquals&lt;T&gt;的comparer参数是通过T自动找到的，而不是我们自己传进去的。因此如何设计一套可以从类型找到某一组函数的机制，就因为我们把模板函数加入NativeX语言（基本上就是C语言）而变成了一个必须实现的功能了。在这里我准备引入concept这个概念。concept跟<a style="TEXT-DECORATION: underline" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1758.pdf" target=_blank>C++0x的concept</a>以及<a style="TEXT-DECORATION: underline" href="http://www.haskell.org/tutorial/classes.html" target=_blank>haskell的type class</a>的概念基本一致。现在就让我们逐步在NativeX里面实现这套机制。<br><br>&nbsp;&nbsp;&nbsp; 我们在这里面对的问题是给一些给定的类型（或泛型类型，譬如说List&lt;T&gt;）实现Equals函数，然后每一个Equals函数里面如果需要其他类型U的Equals函数，可以直接找到，而不需要我们自己传进去。因此这个问题可以抽象为，某些类型具有可以被两两比较是否相等的能力。因此定义如下：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;Eq<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;Equals(T&nbsp;a,&nbsp;T&nbsp;b);<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 当然这些函数不能直接生出来，因此我们对于想比较的每一个类型都需要给出相应的Equals函数。下面的代码为int类型定义了Equals：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">instance&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;:&nbsp;Eq<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;Equals&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;IntEquals;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;IntEquals(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;a,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;b)<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">b;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 每比较一次数字就得调用一次函数，这个开销还是比较大的。在NativeX的所有设施都做好之后，我会开始做指令级别的优化，然后看看要不要实现自动判断并inline的功能。有了int : Eq之后，我们就可以为List&lt;T&gt;也写一个Eq了。如果我们给出了List&lt;T&gt;的Equals的话，为了使用这个Equals，T也必须有相应的Equals函数，于是我们可以写：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">instance&nbsp;List&nbsp;:&nbsp;Eq<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;where&nbsp;T&nbsp;:&nbsp;Eq<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;Equals&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ListEquals</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 最后就是实现ListEquals了，注意ListEquals函数内部是如何拿到类型T的Equals函数的：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;where&nbsp;T&nbsp;:&nbsp;Eq<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;ListEquals(List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;xs,&nbsp;List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;ys)<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(xs</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">ys</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count)<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;current</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">xs</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(current</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">Eq</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::Equals(xs</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">items[current],&nbsp;yx</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">items[current]))<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit;<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 这里引入了一个新的语法：Eq&lt;T&gt;::Equals，用于自动搜索自己dll或者其他dll实现的这个函数。搜索会在虚拟机里面完成，编译器只负责提供符号，并检查类型。因此就大功告成了。<br><br>&nbsp;&nbsp;&nbsp; 这个instance的设计基本上来源于Haskell的type class，其实跟C++0x的那个concept关系还是比较小，毕竟NativeX没有类，C++有类，Haskell没有类。当然其缺点是你不能在定义了Eq&lt;List&lt;T&gt;&gt;::Equals的同时，专门为Eq&lt;List&lt;bool&gt;&gt;::Equals定义一个特殊的版本，就如同C++的偏特化一样，这个就过于复杂了。虽然偏特化在C++的用处非常大，而且也十分常用，但是在NativeX里面就因为NativeX的模板可以编译成二进制而会因为找不到高性能的实现方法被砍掉。 
<img src ="http://www.cppblog.com/vczh/aggbug/120248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-07-13 20:26 <a href="http://www.cppblog.com/vczh/archive/2010/07/13/120248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0实现二进制模板函数</title><link>http://www.cppblog.com/vczh/archive/2010/07/12/120141.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Mon, 12 Jul 2010 11:12:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/07/12/120141.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/120141.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/07/12/120141.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/120141.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/120141.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 经过一个星期的奋斗，二进制模板函数终于实现了，当然这还是没有generic concept的版本。现在NativeX已经支持跟C#一样的模板函数了：可以被编译进独立的二进制文件，然后另外一个代码引用该二进制文件，还能实例化新的模板函数。现在先来看debug log输出的二进制结构。首先是被编译的代码。下面的代码因为是直接从语法树生成的，所以括号什么的会比较多，...&nbsp;&nbsp;<a href='http://www.cppblog.com/vczh/archive/2010/07/12/120141.html'>阅读全文</a><img src ="http://www.cppblog.com/vczh/aggbug/120141.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-07-12 19:12 <a href="http://www.cppblog.com/vczh/archive/2010/07/12/120141.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0之NativeX语言泛型草稿（三）</title><link>http://www.cppblog.com/vczh/archive/2010/06/19/118247.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 19 Jun 2010 08:07:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/06/19/118247.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/118247.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/06/19/118247.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/118247.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/118247.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 大概都是要定稿了罢，想了这么久&#8230;&#8230;前人果然是前人啊，C++的concept也好，Haskell的type class也好，C#的generic interface也好，都非常精确地描述出了NativeX的泛型所应该有的形式。设计语言什么的，还是大部分要抄啊&#8230;&#8230;<br><br>&nbsp;&nbsp;&nbsp; 接<a style="TEXT-DECORATION: underline" href="http://www.cppblog.com/vczh/archive/2010/06/14/117877.html" target=_blank>上一篇文章</a>。昨天晚上<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++</a>的泛型结构体以及泛型类型重命名已经搞定了。这部分先做是因为泛型结构体以及泛型类型重命名都不需要在链接的时候产生新的指令表，因此完全是编译器的事情，不需要修改虚拟机。先来看看泛型结构体以及泛型类型重命名的样子。这次我仍然在单元测试用例里面生成了一个语法树，然后反编译成NativeX代码，然后再一次编译成语法树，最后给生成的指令自动加注释：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">NativeX&nbsp;Code</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;nativex_program_generated;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">type&nbsp;Unit&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;T;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;Vector<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Unit</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;x;<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Unit</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;y;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">function&nbsp;Unit</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">int32</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;main()<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;Unit</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">int32</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;v;<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(v.x</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(v.y</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(v.x</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">v.y));<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">Assembly</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">.data<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">.label<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;instruction&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">.code<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;Unit&lt;int32&gt;&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(v.x=10);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">39</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">40</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(v.y=20);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">41</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">42</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">43</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">44</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">45</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">46</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">47</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result=(v.x+v.y));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">48</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">49</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">17</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">51</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">19</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">52</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">53</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">54</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">22</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">56</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">25</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">58</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">59</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;Unit&lt;int32&gt;&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">60</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">27</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">28</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">62</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; 在这里可以看出实际上编译完了之后，指令集里面根本不会包含有关反省的任何信息，甚至是原先的类型也都丢掉了。当然为了解决这个问题，我给Assembly加了&#8220;资源&#8221;，那是一种通过C++的技巧封装之后，你可以不断地构造越来越大的只读数据结构，方便二进制形式的序列化和反序列化。所有的信息都存在里面，供以后使用（反正虚拟机不需要读）。<br><br>&nbsp;&nbsp;&nbsp; 但是泛型的全局变量、函数和契约就不一样了。泛型全局变量还是很容易做的因此我就忽略掉了。泛型的函数需要把契约的类型完整保留在指令表里面，这样在特化的时候才知道哪些地方需要被替换掉。总的来说最终的设计是这个样子的：<br><br>&nbsp;&nbsp;&nbsp; 首先是契约，跟上次差不多，只是命名契约被我删除了，只剩下匿名契约。总的来说我只需要在链接的时候进行检查就好了，如果发现新来的Assembly重复实现了旧Assembly已经特化过的一个契约，那就会出现链接错误。至于特化要实现在哪里，我就不在编译器上座约束了，因为这个代价更大，而且约束了灵活性。<br><br>&nbsp;&nbsp;&nbsp; 其次是函数。函数的泛型头现在被我修改成了：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;Comparable<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;Compare(T&nbsp;a,&nbsp;T&nbsp;b);<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;with<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">Comparable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;ct<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;AreEqual(T&nbsp;a,&nbsp;T&nbsp;b)<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ct::Compare(a,&nbsp;b)</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 你会发现最终concept变成了对一个类型或者一组类型附加的属性。泛型的函数除了这些属性以外，就只能用一些基本的东西了（当然如果你把一个变量T的地址拿出来，强转&#8230;&#8230;）。这些时候所有泛型参数类型的参数、变量和结构体的地址都变成了一个表达式，譬如说&amp;a == stack_offset+sizeof(int)*4而&amp;b == stack_offset+sizeof(int)*4+sizeof(T)等等。而且如果AreEqual要调用其它关于T的泛型函数的话，如果其他的泛型函数对concept的要求比Comparable更多，那么就变成了编译错误。当然最简单的解决办法就是在AreEqual函数上把所有用到的concept全部加满。<br><br>&nbsp;&nbsp;&nbsp; 当然，最后一个泛型函数还是可以被编译成指令表和一组待计算向量的，只是链接的时候，会查看新来的Assembly需要多少还没特化的函数，然后一一为他们生成。于是现在最难的问题就变成了重构已有代码，以及如何判断concept instance是否被多个Assembly重复特化了&#8230;&#8230;
<img src ="http://www.cppblog.com/vczh/aggbug/118247.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-06-19 16:07 <a href="http://www.cppblog.com/vczh/archive/2010/06/19/118247.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0之NativeX语言泛型草稿（二）</title><link>http://www.cppblog.com/vczh/archive/2010/06/14/117877.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Mon, 14 Jun 2010 07:50:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/06/14/117877.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/117877.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/06/14/117877.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/117877.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/117877.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 接<a style="TEXT-DECORATION: underline" href="http://www.cppblog.com/vczh/archive/2010/06/13/117795.html" target=_blank>上一篇文章</a>。自从昨天设计了<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>NativeX语言</a>的泛型之后，今天又对昨天的草稿做了一下修改。设计语言的语法总是这样，首先对你自己的需求提出直接的解决方法，然后看看是不是有些新的概念跟其他概念可以合并起来变成更抽象的概念，而且又不会在实现上导致困难，也不会让编译器变的突然难写许多。经过了昨天晚上和今天早上的思考，我决定简化一下泛型的语法以及concept的内容。<br><br>&nbsp;&nbsp;&nbsp; 首先说语法上的。上一篇文章在定义泛型头的时候采用了generic&lt;type T1, type T2, concept C1, concept C2&gt;这样子的语法。本着尽量减少关键字的原则，我决定去掉type，变成generic&lt;T1, T2, concept C1, concept C2&gt;。原因是concept关键字还能用来定义一个契约，而type则毫无用处。而且一个契约有了concept关键字作开头，也不会跟没有type关键字的类型参数混淆。<br><br>&nbsp;&nbsp;&nbsp; 其次是concept。昨天定义了concept instance和concept series。其实总结到最后，concept instance无非就是concept series的一个特例。根据昨天的说法，把所有的instance都替换成series其实结果还是一样的。唯一的区别就是concept series不允许在既不是concept定义所在的Assembly也不是特化所涉及类型的Assembly里面出现它的一个特化。如果单纯去掉了concept instance的话显然会带来问题：我在AssemblyA处声明了一个concept Sortable&lt;T&gt;之后，没办法在AssemblyB处声明一个concept series IntSortable : Sortable&lt;int&gt;。因此某一些限制需要放宽一点：<br>&nbsp;&nbsp;&nbsp; 1、concept series的原始版本可以在一个既不包含concept声明和也不包含涉及的类型声明的地方声明。<br>&nbsp;&nbsp;&nbsp; 2、concept series的特化版本则必须出现在包含concept声明或者包含涉及类型声明的地方声明。<br><br>&nbsp;&nbsp;&nbsp; 那么其实series关键字也不需要了，因此会获得下面的写法：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;GSortable<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000">&nbsp;LessThan(T&nbsp;a,&nbsp;T&nbsp;b);<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">instance&nbsp;Sortable&nbsp;:&nbsp;GSortable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;LessThan&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;BinaryLessThen</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">instance&nbsp;Sortable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;LessThan(a,&nbsp;b)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;b;<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; operation和function的区分实际上没什么大的价值，如果你真的需要一个函数指针的话，那就在参数传进去好了。而且constant也没什么必要，因为constant实际上是operation的一个特例，只是使用的时候需要多写一个口号罢了。我们会看到上面定义concept其中的操作的两个方法：指定函数和指定表达式。如果制定了表达是的话，那么该表达式将会被内联（啊）。所以constant存在的价值也就不存在了。因此我们甚至连function、operation和constant的区分也消失了，所以在语法上更加得到了简化。<br><br>&nbsp;&nbsp;&nbsp; NativeX每一次引入一个新的特性的时候都是迫不得已而为之，而且一旦引入之后我总是力图将该特性设计成跟其他所有的特性正交。例如这里的泛型，所有的东西都可以加上泛型，譬如结构体、全局变量、函数、契约和契约实例。所有的东西都可以是非泛型的，也可以是泛型的。有时候我们的确需要定义一个非泛型的concept，这其实也不是什么大问题。<br><br>&nbsp;&nbsp;&nbsp; 不过当前的语法还会遇到C++那经典的&gt;&gt;问题（一直到了C++0x才正式纳入标准- -b）。这个问题有三种解决办法，第一种是不允许写成vector&lt;vector&lt;int&gt; &gt;，第二种是允许写a&gt;&gt;b也允许写a&gt; &gt;b（中间有个空格），第三种是跟VC++一样一概支持。最后一个比较困难，第二个比较奇怪，第一个比较恶习。不过结合了各种因素之后，其实我觉得支持第二个倒是最简单的办法：你仍然可以写出漂亮的代码，而且你如果自己受得了a&gt; &gt;b而自己恶心自己的话，那也是你自己的事&#8230;&#8230;<br><br>&nbsp;&nbsp;&nbsp; 至于其它问题，NativeX没有逗号表达式，声明NativeX的变量需要加上variable关键字，声明NativeX的函数需要加上function关键字，所以全部迎刃而解。 
<img src ="http://www.cppblog.com/vczh/aggbug/117877.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-06-14 15:50 <a href="http://www.cppblog.com/vczh/archive/2010/06/14/117877.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0之NativeX语言泛型草稿</title><link>http://www.cppblog.com/vczh/archive/2010/06/13/117795.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 13 Jun 2010 07:58:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/06/13/117795.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/117795.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/06/13/117795.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/117795.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/117795.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 为了让更高级的语言可以编译到<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++ 3.0</a>上面的NativeX语言，原生的泛型支持是必须有的。泛型不仅仅是一堆代码的填空题那么简单，因为编译之后的Assembly（dll）必须可以容纳泛型声明，而且其他的Assembly可以实例化包含在其他Assembly里面的泛型声明。这是非常麻烦的（被.net搞定了，jvm则由于种种原因搞不定，大概是因为jvm对assembly version的支持太差导致的，你知道.net 2.0的东西是不能引用4.0的dll的&#8230;&#8230;）。不过先抛开这个不讲，虽然如何在Assembly里面实现泛型我已经心里有数了，但是这里还是从语义的层面上来考虑泛型的设计。<br><br>&nbsp;&nbsp;&nbsp; 在讨论之前还是要强调一下一个大前提：<span style="COLOR: red"><strong>NativeX基本上就是一个语法更加容易看懂的C语言而已</strong></span>，功能完全是等价的。于是我要在NativeX上加泛型，其实也就是等于在C上面加泛型。我们使用泛型完成的事情可以有很多，譬如说定义泛型的结构体，定义泛型的函数，还有泛型的存储空间等等。首先让我们讨论泛型的结构体。最终的语法可能会跟现在不一样，因为NativeX的使命是作为一棵语法树出现的，所以做得太漂亮的价值其实不是很大。<br><br>&nbsp;&nbsp;&nbsp; <strong>一、泛型结构体</strong><br><br>&nbsp;&nbsp;&nbsp; 泛型的结构体还是比较容易理解的，举个小例子：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;Vector<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;T&nbsp;x;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;T&nbsp;y;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 这样子我们就创建了一个泛型的结构体。任何熟悉C++或C#的人都知道这是什么意思，我就不做解释了。使用的时候跟我们的习惯是一样的：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">Vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;v;<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">v.x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1.0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">v.y&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2.0</span><span style="COLOR: #000000">;</span></div>
<br>&nbsp;&nbsp;&nbsp; 于是我们创建了一个泛型的变量，然后修改了它的成员。<br><br>&nbsp;&nbsp;&nbsp; <strong>二、泛型全局存储空间</strong><br><br>&nbsp;&nbsp;&nbsp; 其实泛型的全局存储空间基本上等于编译器替你做好的一个key为类型的大字典。有些时候我们需要给类型加上一些附加的数据，而且是按需增长的。这就代表在编译的时候提供泛型全局存储空间的Assembly并不知道将来有多少个key要提供支持，所以创建它们的工作应该是虚拟机在链接一个想使用其他Assembly提供的全局空间的新Assembly的时候创建的。这里带来了一个问题是不同的Assembly使用相同的类型可以访问相同的全局存储空间，这里先不讨论具体实施的手段。<br><br>&nbsp;&nbsp;&nbsp; 语法上可能比较混淆：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;TypeStorage<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;wchar</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;name;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;function&nbsp;T()&nbsp;builderFunction;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这是函数指针</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">9</span>&nbsp;<span style="COLOR: #000000">TypeStorage</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;typeStorage;</span></div>
<br>&nbsp;&nbsp;&nbsp; 在一个变量上面加泛型可能会有点奇怪，不过这里的定义还是很明确的。typeStorage是全局变量的泛型，因此typeStorage&lt;int&gt;、typeStorage&lt;double&gt;甚至typeStorage&lt;Vector&lt;Vector&lt;wchar*&gt;&gt;&gt;等等（啊，&gt;&gt;问题）是代表不同的全局变量。不同的Assembly访问的typeStorage&lt;int&gt;都是相同的全局变量。<br><br>&nbsp;&nbsp;&nbsp; <strong>三、泛型函数</strong><br><br>&nbsp;&nbsp;&nbsp; 泛型函数我们也都很熟悉了。一个简单的例子可以是：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">T&nbsp;Copy(T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;pt)<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pt;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 需要指出的是，NativeX并没有打算要支持泛型结构、全局存储和函数的特化或偏特化。因此我们会很惊讶的发现这样的话泛型函数唯一能做的就是复制东西了，因为它调用不了其他的非泛型函数（跟C++不一样，NativeX的泛型函数更接近于C#：编译的时候进行完全的语义分析）。虽然泛型函数可以调用其他的泛型函数，但是最终也只能做复制。因此我们要引入一个新的（其实是旧的）概念，才可以避免我们为了提供各种操作在泛型函数的参数上传入一大堆的函数指针：&#8220;概念&#8221;。<br><br>&nbsp;&nbsp;&nbsp; <strong>四、泛型concept</strong><br><br>&nbsp;&nbsp;&nbsp; 泛型结构体和全局存储仅仅用来保存数据，所以泛型concept只能在泛型函数上面使用。这个concept跟C++原本打算支持的concept还是很接近的，只是NativeX没有class，因此只好做一点小修改。<br><br>&nbsp;&nbsp;&nbsp; 泛型concept主要是为了指定一套操作的接口，然后让编译器可以完成比调用函数指针更加高效的代码。偷偷告诉大家，把他叫concept只是因为NativeX跟C很像，但其实这个概念是从Haskell来的&#8230;&#8230;我们还是来看看concept怎么写吧。<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;Addable<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;add(T&nbsp;a,&nbsp;T&nbsp;b);<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;sub(T&nbsp;a,&nbsp;T&nbsp;b);<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;constant&nbsp;T&nbsp;zero;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;Multible&nbsp;:&nbsp;Addable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;mul(T&nbsp;a,&nbsp;T&nbsp;b);<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;div(T&nbsp;a,&nbsp;T&nbsp;b);<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;constant&nbsp;T&nbsp;one;<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 这里定义了加法和乘法的两个concept。我们可以看出concept是可以继承的，其实也是可以多重继承的。concept里面可以放操作（operation），也可以放常数（constant）。这里的常数跟全局存储的机制不同，全局存储可以自动为新类型产生可读写的空间，而concept的常数不仅是只读的，而且还不可自动产生空间。之前考虑到的一个问题就是，我们可能需要把外界提供的某个concept的operation的函数指针提取出来，有这种需要的operation可以把这个关键字替换成function，这样在实例化concept的时候，那个标记了function的操作就只能绑定一个函数而不是一个表达式了。我们可以尝试为int创建一个Multible的concept：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;instance&nbsp;IntMultible&nbsp;:&nbsp;Multible</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;add(T&nbsp;a,&nbsp;T&nbsp;b)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">b;<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;sub(T&nbsp;a,&nbsp;T&nbsp;b)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">b;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;mul(T&nbsp;a,&nbsp;T&nbsp;b)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">b;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;div(T&nbsp;a,&nbsp;T&nbsp;b)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">b;<br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;constant&nbsp;T&nbsp;zero&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;constant&nbsp;T&nbsp;one&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">9</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 于是我们可以写一个函数计算a+b*c：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T,&nbsp;concept&nbsp;Multible</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;multible</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">function&nbsp;T&nbsp;AddMul(T&nbsp;a,&nbsp;T&nbsp;b,&nbsp;T&nbsp;c)<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;multible.add(a,&nbsp;multible.mul(b,&nbsp;c));<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 然后调用它：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;r&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;AddMul</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,&nbsp;IntMultible</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">);</span></div>
<br>&nbsp;&nbsp;&nbsp; <strong>五、另一种concept instance</strong><br><br>&nbsp;&nbsp;&nbsp; 虽然我们不允许泛型的结构体、全局存储和函数进行特化，但是因为特化实在是一个好东西。上面的concept instance是没有弹性的，因为你不可能通过一个concept instance拿到另外一个concept instance。考虑一下delphi的带引用计数的嵌套数组，如果我们想让delphi可以编译到NativeX上，则势必要支持那种东西。主要的困难在于delphi支持的带有引用计数的数组和字符串，因此在对array of array of string进行释放的时候，我们首先要拿到array of array of string的concept instance，其次在释放函数里面要拿到array of string的concept instance，最后还要拿到string的concept instance。这个用上面所提出来的方法是做不了的。因此我们引进了一种新的concept instance：叫concept series。这个跟haskell的东西又更接近了一步了，因为haskell的concept instance其实是匿名但是可特化的&#8230;&#8230;<br><br>&nbsp;&nbsp;&nbsp; 于是现在让我们来实现Array和String，并写几个类型的Increase和Decrease的函数（函数体一部分会被忽略因为这里只是为了展示concept）：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;String<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;reference;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;wchar</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;content;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;Array<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;reference;<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;length;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;items;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 我们从这里可以看出，string跟array的区别就是在于长度上面，string有0结尾而array只能通过记录一个长度来实现。现在我们来写一个用于构造缺省数值、增加引用计数和减少引用计数的concept series：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;Referable<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;T&nbsp;GetDefault();<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Increase(T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;t);<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Decrease(T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;t);<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;series&nbsp;DelphiTypeReferable&nbsp;:&nbsp;Referable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; concept series其实就是专门用来特化的concept instance。但是为了防止不同的Assembly特化出同一个concept series所带来的麻烦，我可能会规定允许特化concept series的地方，要么是在声明该concept series的Assembly，要么是声明涉及的类型的Assembly。因为我的Assembly不允许循环引用，因此对于同一个concept series C&lt;T,U&gt;来讲，就算T和U分别在不同的Assembly出现，那么也只能有一个有权限特化出它。下面来看特化具体要怎么做。首先我们特化一个简单的，string的DelphiTypeReferable：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;series&nbsp;DelphiTypeReferable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">String</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;GetDefault&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;StringGetDefault;<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;Increase&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;StringIncrease;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;Decrease&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;StringDecrease;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; StringGetDefault、StringIncrease和StringDecrease都是一些普通的函数，内容很简单，不用写出来。现在让我们来看看Array应该怎么做：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;series&nbsp;DelphiTypeReferable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Array</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;Array</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;GetDefault()&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ArrayGetDefault</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;Increase&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ArrayIncrease</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;Decrease&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ArrayDecrease</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 看起来好像没什么特别，不过只要想一想ArrayDecrease的实现就知道了，现在我们需要在ArrayDecrease里面访问到未知类型T的DelphiTypeReferable&lt;T&gt;这个concept instance。因为当自己要被干掉的时候，得将引用到的所有对象的引用计数都减少1：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ArrayDecrease(Array</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;*</span><span style="COLOR: #000000">&nbsp;array)<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(array</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">reference</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)exit;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">array</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">reference</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;array</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">length<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;i</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;DelphiTypeReferable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">.Decrease(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">array</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">items[i]);<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;free(array</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">items);<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;array</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">length</span><span style="COLOR: #000000">=-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;array</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">items</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 这样一大堆concept series的特化组合在一起就成为会根据类型的变化而采取不同行为的concept instance了。于是我们还剩下最后的一个问题，那么其他类型的DelphiTypeReferable应该怎么写呢？其实只需要玩一个小技巧就行了，不过在这里将会看到NativeX支持泛型的最后一个功能：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">concept&nbsp;series&nbsp;DelphiTypeReferable</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;GetDefault&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;GenericGetDefault</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;Increase&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;operation&nbsp;Decrease&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">generic</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">type&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">T&nbsp;GenericGetDefault()<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 返回null的operation可以赋值成null以表示不需要执行任何东西。如果你将一个有副作用的表达式传进去当参数的话，副作用会保证被执行。<br><br>&nbsp;&nbsp;&nbsp; 关于语义上的泛型就讲到这里了。
<img src ="http://www.cppblog.com/vczh/aggbug/117795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-06-13 15:58 <a href="http://www.cppblog.com/vczh/archive/2010/06/13/117795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0之实现跨Assembly调用函数内幕</title><link>http://www.cppblog.com/vczh/archive/2010/06/11/117664.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Fri, 11 Jun 2010 15:13:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/06/11/117664.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/117664.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/06/11/117664.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/117664.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/117664.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; <a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++ 3.0</a>终于实现跨Assembly调用函数了。其实在设计之初架构就已经允许了这个东西，只是一直都留着没做。现在先看两段代码，然后逐一解释指令的内容。<br><br>&nbsp;&nbsp;&nbsp; 首先是第一个Assembly（可以认为是dll，概念是一样的），实现了一个全局变量，然后有一个单参数的函数，返回参数跟全局变量的和（代码是从语法树生成出来的，主要是为了实现指令集里面的自动加注释功能）：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">NativeX&nbsp;Code</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;nativex_program_generated;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">variable&nbsp;int32&nbsp;leftOperand&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;add(int32&nbsp;rightOperand)<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(leftOperand</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">rightOperand));<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">Assembly</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">.data<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #000000">0x00000000</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #000000">00</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">00</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">00</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">00</span><span style="COLOR: #000000">&nbsp;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">.label<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;instruction&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">.code<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;variable&nbsp;int32&nbsp;leftOperand&nbsp;=&nbsp;0;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">:&nbsp;link_pushdata&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;add(int32&nbsp;rightOperand)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result=(leftOperand+rightOperand));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">:&nbsp;link_pushdata&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;add(int32&nbsp;rightOperand)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #000000"></span></div>
<p><br>&nbsp;&nbsp;&nbsp; 这段简单的加法代码没什么好解释的。窥孔优化还没做，因此会有一些垃圾在里面。在这里可以看到全局变量的访问跟参数访问的不同。全局变量使用link_pushdata，而参数使用stack_offset。link_开头的都是链接时指令，链接器会把这些东西给转换成真正的指令。因为在编译的时候并不知道全局空间的实际指针，因此只好链接的时候再做，这个时候全局空间已经生成出来了。最终link_pushdata会被转换成一个push ptr x指令，x是一个常数。<br><br>&nbsp;&nbsp;&nbsp; 下面是调用这个Assembly里面的另一个Assembly的main函数：</p>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">NativeX&nbsp;Code</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;nativex_program_generated;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">variable&nbsp;int32&nbsp;adder&nbsp;alias&nbsp;programAdd.leftOperand;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;add(int32&nbsp;offset)&nbsp;alias&nbsp;programAdd.add;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;main()<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(adder</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">add(</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">));<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">Assembly</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">.data<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">.label<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;instruction&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">.code<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(adder=1);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">:&nbsp;link_pushforeigndata&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result=add(2));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">:&nbsp;link_callforeignfunc&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; 这里主要是看看一个Assembly里面的代码是如何操作另外一个Assembly的东西的。首先定义链接符号，譬如说variable int32 adder alias programAdd.leftOperator。programAdd是第一个Assembly的名字（没有反应在代码里），然后leftOperator明显就是变量名了。因为Assembly的数据里面还保留了所有变量、函数、结构类型的声明的全部内容，因此不会出现&#8220;Dll地狱&#8221;。链接的时候可以比较一下被链接的符号的声明以及定义的连接符号的声明是否吻合，不吻合则代表要么Assembly版本有问题，要么Assembly就是错的，因此直接抛出异常不允许加载。<br><br>&nbsp;&nbsp;&nbsp; 在这个代码里面我们有两个符号：programAdd.leftOperator和programAdd.add。他们按照顺序分别被套上ID：0和1。因此在对adder，也就是programAdd.leftOperator赋值的时候，这里使用了链接时指令link_pushforeigndata 0，用来读入该变量的地址。调用add的时候，先push一个参数2，然后将存放结果的变量的指针也push进去，最后调用函数programAdd.add，也就是ID为1的符号了：link_callforeignfunc 1。<br><br>&nbsp;&nbsp;&nbsp; 链接器会把所有link_开头的指令全部通过已经加载的信息重新替换成运行是指令。显然link_pushforeigndata 0和link_callforeignfunc 1都是缺少加载时才有的信息才写成这样子的，最后会被翻译成push ptr x和call assembly_id instruction_address。<br><br>&nbsp;&nbsp;&nbsp; 既然可以调用外部Assembly的函数，那么把外部Assembly的函数的函数指针存放起来供以后调用也是完全可能的：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">NativeX&nbsp;Code</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;nativex_program_generated;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;add(int32&nbsp;a,&nbsp;int32&nbsp;b)<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(a</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">b));<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">Assembly</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">.data<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">.label<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;instruction&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">.code<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;add(int32&nbsp;a,&nbsp;int32&nbsp;b)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result=(a+b));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;add(int32&nbsp;a,&nbsp;int32&nbsp;b)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; 这个我就不废话了，更加简单，连全局变量都没有了，就一个加法函数。接下来的main函数会把这个加法函数和自己的加法函数的函数指针存下来，然后调用：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">NativeX&nbsp;Code</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;nativex_program_generated;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;main()<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;function&nbsp;int32(int32,&nbsp;int32)&nbsp;padd1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;add1;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;function&nbsp;int32(int32,&nbsp;int32)&nbsp;padd2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;add2;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;int32&nbsp;a&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;padd1(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;int32&nbsp;b&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;padd2(</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">((a</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">b));<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;add1(int32&nbsp;a,&nbsp;int32&nbsp;b)&nbsp;alias&nbsp;programAdd.add;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;add2(int32&nbsp;a,&nbsp;int32&nbsp;b)<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(a</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">b));<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">Assembly</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">.data<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">.label<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;instruction&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;instruction&nbsp;</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">.code<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;variable&nbsp;function&nbsp;int32(int32,&nbsp;int32)&nbsp;padd1&nbsp;=&nbsp;add1;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">:&nbsp;link_pushforeignfunc&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">:&nbsp;write&nbsp;u32<br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;variable&nbsp;function&nbsp;int32(int32,&nbsp;int32)&nbsp;padd2&nbsp;=&nbsp;add2;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">:&nbsp;link_pushfunc&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">:&nbsp;write&nbsp;u32<br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;variable&nbsp;int32&nbsp;a&nbsp;=&nbsp;padd1(1,&nbsp;2);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">39</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">40</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">42</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">43</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">44</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">45</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">:&nbsp;read&nbsp;u32<br></span><span style="COLOR: #008080">46</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">17</span><span style="COLOR: #000000">:&nbsp;label<br></span><span style="COLOR: #008080">47</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">:&nbsp;call_indirect<br></span><span style="COLOR: #008080">48</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;variable&nbsp;int32&nbsp;b&nbsp;=&nbsp;padd2(3,&nbsp;4);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">49</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">19</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">51</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">52</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">22</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">53</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">54</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">25</span><span style="COLOR: #000000">:&nbsp;read&nbsp;u32<br></span><span style="COLOR: #008080">56</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">:&nbsp;label<br></span><span style="COLOR: #008080">57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">27</span><span style="COLOR: #000000">:&nbsp;call_indirect<br></span><span style="COLOR: #008080">58</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result=((a*10)+b));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">59</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">28</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">60</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">29</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">30</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">62</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">31</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">64</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">33</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">65</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">34</span><span style="COLOR: #000000">:&nbsp;mul&nbsp;s32<br></span><span style="COLOR: #008080">66</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">35</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">67</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">36</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">68</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">37</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">69</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">70</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">38</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">71</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">39</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">72</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;add2(int32&nbsp;a,&nbsp;int32&nbsp;b)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">73</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">74</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result=(a+b));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">75</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">41</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">76</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">42</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">77</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">43</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">78</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">44</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">79</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">45</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">80</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">46</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">81</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">47</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">82</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;add2(int32&nbsp;a,&nbsp;int32&nbsp;b)</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">83</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">48</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">84</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">49</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">85</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; 哇哈哈。<br><br>&nbsp;&nbsp;&nbsp; 最新代码可以在<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>这里</a>获得。
<img src ="http://www.cppblog.com/vczh/aggbug/117664.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-06-11 23:13 <a href="http://www.cppblog.com/vczh/archive/2010/06/11/117664.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0之成功将源代码注释进指令列表</title><link>http://www.cppblog.com/vczh/archive/2010/06/05/117217.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 05 Jun 2010 03:49:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/06/05/117217.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/117217.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/06/05/117217.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/117217.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/117217.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 经过昨天的艰苦奋斗我终于在<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++ 3.0</a>里完成这么一个功能了。假设我现在用代码组装了一个语法树：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BasicProgramNode&nbsp;program;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;program.DefineStructure(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Complex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;t_int())<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;t_int());<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;program.DefineFunction(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">main</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).ReturnType(t_int()).Statement(<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s_var(t_type(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Complex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_var(t_type(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Complex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_var(t_type(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Complex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Assign(e_prim(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)))<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Assign(e_prim(</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)))<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Assign(e_prim(</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">)))<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Assign(e_prim(</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">)))<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_var(t_type(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Complex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">x</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">))<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_var(t_type(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Complex</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">y</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">y</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Assign(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)))<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Assign(<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">x</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">y</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;))<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Assign(<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">x</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">y</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;))<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">s_expr(e_result().Assign(<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">r</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">e_prim(</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;e_name(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).Member(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">i</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;))<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);</span></div>
<br>&nbsp;&nbsp;&nbsp; 于是最近写的N个函数终于可以发挥作用了。首先我会拿这个program编译成指令集先跑一次，如果答案跟测试用例给出的一致那就继续往下走。接下来就将这个program还原成一个NativeX语言的字符串，然后调用NativeX的语法分析器再编译一次，这样每一个语法树的节点都有一个指向记号的属性了。这样语法树生成指令集的时候，每一个指令原本属于哪颗语法树也就都记录下来了。这个时候，将指令集输出成文本文件的时候，就可以根据位置信息使用NativeX的源代码打上注释，然后再跑一次。这样还可以通过丰富的测试用例来测试NativeX的语法分析器，而且还不会被语法分析器影响。因为program编译了一次，program-&gt;NativeX-&gt;newProgram又编译了一次，哇哈哈。结果如下：<br><br>&nbsp;&nbsp;&nbsp; （窥孔优化在这个时候就可以大展身手了，不过我还没做&#8230;&#8230;）<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">NativeX&nbsp;Code</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;2</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;nativex_program_generated;<br></span><span style="COLOR: #008080">&nbsp;&nbsp;3</span>&nbsp;<span style="COLOR: #000000">structure&nbsp;Complex<br></span><span style="COLOR: #008080">&nbsp;&nbsp;4</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;&nbsp;5</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;int32&nbsp;r;<br></span><span style="COLOR: #008080">&nbsp;&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;int32&nbsp;i;<br></span><span style="COLOR: #008080">&nbsp;&nbsp;7</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;9</span>&nbsp;<span style="COLOR: #000000">function&nbsp;int32&nbsp;main()<br></span><span style="COLOR: #008080">&nbsp;10</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;Complex&nbsp;a;<br></span><span style="COLOR: #008080">&nbsp;12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;Complex&nbsp;b;<br></span><span style="COLOR: #008080">&nbsp;13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;Complex&nbsp;c;<br></span><span style="COLOR: #008080">&nbsp;14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(a.r</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(a.i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(b.r</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(b.i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;Complex&nbsp;x&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a;<br></span><span style="COLOR: #008080">&nbsp;19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;variable&nbsp;Complex&nbsp;y;<br></span><span style="COLOR: #008080">&nbsp;20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(y</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">b);<br></span><span style="COLOR: #008080">&nbsp;21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(c.r</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(x.r</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">y.r));<br></span><span style="COLOR: #008080">&nbsp;22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(c.i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(x.i</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">y.i));<br></span><span style="COLOR: #008080">&nbsp;23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;(result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">((c.r</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">c.i));<br></span><span style="COLOR: #008080">&nbsp;24</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">&nbsp;25</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;26</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;27</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">Assembly</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;28</span>&nbsp;<span style="COLOR: #000000">.data<br></span><span style="COLOR: #008080">&nbsp;29</span>&nbsp;<span style="COLOR: #000000">.label<br></span><span style="COLOR: #008080">&nbsp;30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;instruction&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;31</span>&nbsp;<span style="COLOR: #000000">.code<br></span><span style="COLOR: #008080">&nbsp;32</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;unit&nbsp;nativex_program_generated;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;33</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;36</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;37</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;38</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(a.r=1);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;39</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;40</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">&nbsp;41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;42</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;43</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;44</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;45</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(a.i=2);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;46</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;47</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">&nbsp;48</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;49</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;51</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;52</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(b.r=3);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;53</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;54</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">17</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">&nbsp;55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;56</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">19</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;58</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;59</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(b.i=4);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;60</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">22</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">&nbsp;62</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">25</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;64</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;65</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">27</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;66</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;variable&nbsp;Complex&nbsp;x&nbsp;=&nbsp;a;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;67</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">28</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;68</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">29</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;69</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">30</span><span style="COLOR: #000000">:&nbsp;copymem&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;70</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(y=b);</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;71</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">31</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;72</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;73</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">33</span><span style="COLOR: #000000">:&nbsp;copymem&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;74</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(c.r=(x.r+y.r));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;75</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">34</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;76</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">35</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;77</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">36</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;78</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">37</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;79</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">38</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;80</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">39</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;81</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;82</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">41</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;83</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">42</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;84</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">43</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;85</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">44</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;86</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">45</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;87</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">46</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;88</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(c.i=(x.i+y.i));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;89</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">47</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;90</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">48</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;91</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">49</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;92</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;93</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">51</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;94</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">52</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;95</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">53</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;96</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">54</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;97</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">55</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">&nbsp;98</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">56</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;99</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">57</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">100</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">58</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">101</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">59</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">102</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;(result=((c.r*100)+c.i));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">103</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">60</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">104</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">61</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">105</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">62</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">106</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">63</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">107</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">64</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s8&nbsp;</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">108</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">65</span><span style="COLOR: #000000">:&nbsp;convert&nbsp;s32&nbsp;s8<br></span><span style="COLOR: #008080">109</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">66</span><span style="COLOR: #000000">:&nbsp;stack_offset&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">110</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">67</span><span style="COLOR: #000000">:&nbsp;push&nbsp;s32&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">111</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">68</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">112</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">69</span><span style="COLOR: #000000">:&nbsp;read&nbsp;s32<br></span><span style="COLOR: #008080">113</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">70</span><span style="COLOR: #000000">:&nbsp;mul&nbsp;s32<br></span><span style="COLOR: #008080">114</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">71</span><span style="COLOR: #000000">:&nbsp;add&nbsp;s32<br></span><span style="COLOR: #008080">115</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">72</span><span style="COLOR: #000000">:&nbsp;resptr<br></span><span style="COLOR: #008080">116</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">73</span><span style="COLOR: #000000">:&nbsp;write&nbsp;s32<br></span><span style="COLOR: #008080">117</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;function&nbsp;int32&nbsp;main()</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">118</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">74</span><span style="COLOR: #000000">:&nbsp;stack_reserve&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">40</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">119</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">75</span><span style="COLOR: #000000">:&nbsp;ret&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">120</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; 最新的代码可以在<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>这里</a>获得。 
<img src ="http://www.cppblog.com/vczh/aggbug/117217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-06-05 11:49 <a href="http://www.cppblog.com/vczh/archive/2010/06/05/117217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 3.0之NativeX语言反向编译与一些优化</title><link>http://www.cppblog.com/vczh/archive/2010/06/01/116849.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Mon, 31 May 2010 16:05:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/06/01/116849.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/116849.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/06/01/116849.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/116849.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/116849.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; <a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++ 3.0</a>终于开始正式进行优化的工作了。当然这里的优化指的是不更改抽象语法树的情况下尽量进行更加好的代码生成。根据经验这一个部分对于程序的影响最为突出。因为一个程序员可能因为具备了编译器的一些知识而写出更加高效的代码，但是却控制不了如何将一个具体的表达式转换成汇编指令的过程。因此这部分不得不尽我所能做到最好。<br><br>&nbsp;&nbsp;&nbsp; 目前的进度是将表达式的代码生成分为以下几大类：<br>&nbsp;&nbsp;&nbsp; 1、计算引用地址<br>&nbsp;&nbsp;&nbsp; 2、计算引用地址的同时不运行副作用<br>&nbsp;&nbsp;&nbsp; 3、计算结果<br>&nbsp;&nbsp;&nbsp; 4、仅运行副作用<br>&nbsp;&nbsp;&nbsp; 5、将结果保存至某某地址<br><br>&nbsp;&nbsp;&nbsp; 除了一些非左值的表达式不具备1和2，或者一些特别复杂的左值表达式不具备2以外，每一种表达是都具有以上5种代码生成算法。这样可以尽可能将无效代码降至最少。举个例子，假设我们为表达式e生成了一串指令is，那么语句s：e;的指令显然应该是is&nbsp;+ {pop typeof(e)}。有可能e其实是++i;，那么按照这个方法生成的代码就会有无效代码：<br>&nbsp;&nbsp;&nbsp; push addressof(i)<br>&nbsp;&nbsp;&nbsp; read int<br>&nbsp;&nbsp;&nbsp; push 1<br>&nbsp;&nbsp;&nbsp; add<br>&nbsp;&nbsp;&nbsp; <span style="COLOR: red"><strong>duplicate-stack-top-item int</strong></span><br>&nbsp;&nbsp;&nbsp; push addressof(i)<br>&nbsp;&nbsp;&nbsp;&nbsp;write<br>&nbsp;&nbsp;&nbsp; <span style="COLOR: red"><strong>pop int</strong></span><br>&nbsp;&nbsp;&nbsp; 我们知道红色的那些指令是不需要的。因为在编译s的时候，我们并不需要知道++i之后的结果，仅仅是想执行这个表达式的副作用。根据类似的思路，于是就有了上面的5大分类。当然每一个分类还会有自己细微的部分。如何让代码生成模块易于维护就成为一个挑战了。代码越复杂，测试也就越复杂。现在只能通过编写足够多的测试用例来尽可能覆盖更多的代码来使代码更加稳定。在修改算法的过程中还会引入新的分支，所以测试用例并不能够总是及时的跟进。于是就有了下面这个设想。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;测试用例总是要人写的，在面对编译器这么复杂的东西的时候，还没什么有效的方法可以来自动生成测试用例。因为我们需要把代码以及生成的指令集都log到一个文件里面，这样当一个用例发生了错误的时候，我们可以更加迅速地知道究竟是哪里出了问题。但是编写测试用例的时候，为了不让语法分析部分的错误导致代码生成的测试结果出错，因此只好在调用代码生成的同时不去运行语法分析的代码。于是我们需要一个将语法树转换成字符串的过程，然后将每一个语句的字符串（可以控制一个基本语句只占用一行代码）变成注释添加到汇编指令的log部分。这样我们就可以轻松知道哪些代码是属于哪个语句的。<br><br>&nbsp;&nbsp;&nbsp; 目前这个部分正在开发，但已经距离胜利不远了。当这个部分完成之后，就可以添加很多新的测试用例来测试被分成5类的算法了。目前的测试用例仅能保证每一种表达式都被运行过一次，但是不能保证每一个表达式的每一个代码生成算法都被执行过。<br><br>&nbsp;&nbsp;&nbsp; 详尽的测试可以在早期发现最大量的bug，这样可以在后续的语言种类继续建立起来的时候可以专注于该语言种类自己的测试，而不让其基层的错误让测试变得更加麻烦。<br>&nbsp;&nbsp;&nbsp; 
<img src ="http://www.cppblog.com/vczh/aggbug/116849.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-06-01 00:05 <a href="http://www.cppblog.com/vczh/archive/2010/06/01/116849.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>升级到Visual Studio 2010</title><link>http://www.cppblog.com/vczh/archive/2010/05/20/115893.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Thu, 20 May 2010 03:27:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/05/20/115893.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/115893.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/05/20/115893.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/115893.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/115893.html</trackback:ping><description><![CDATA[<p>决定把<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>的项目的主要工程升级到VC++ 2010。新的VC++智能提示变得无敌顺畅，无论我怎么模板怎么宏乱嵌套，结果都是正确的。娃哈哈。不过反正语法是兼容的，使用<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>的也无法直接使用那个单元测试用的工程文件，所以我想影响应该不大。</p>
<img src ="http://www.cppblog.com/vczh/aggbug/115893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-05-20 11:27 <a href="http://www.cppblog.com/vczh/archive/2010/05/20/115893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>美帝出差最后一天</title><link>http://www.cppblog.com/vczh/archive/2010/05/07/114754.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Fri, 07 May 2010 06:56:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/05/07/114754.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/114754.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/05/07/114754.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/114754.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/114754.html</trackback:ping><description><![CDATA[<p>跟老外聊天果然是不流利啊，就算英文可以看文章写wiki，说起话来还是不够爽。特别是非美帝且非天朝的人说起英语，口音跟天朝有一拼，就互相听不懂了。<br></p>
四个星期。第一个周末去了批发市场买名牌，当然我只是看，同事在买。第二个周末去了看郁金香展，拍了些图。第三个星期去了Orcas岛（这个M$产品的code name就是喜欢用这些湖啊岛啊山啊&#8230;&#8230;）等到山顶，那个比上海北京都好得多的空气让我们可以直接用眼睛看到加拿大的山。第四个星期同事出去玩，我就在写代码了。还是写代码爽啊，游山玩水什么的都是浮云。当然战利品是有的，带了一盒明信片，还有人体工学键盘鼠标。M$卖给自己人还要打5折，压榨了我们的剩余价值应该送个才对，后来打听到了，美帝的人要键盘是不用钱的，天朝的人就得自己花钱了，虽然打折&#8230;&#8230;<br><br>Vczh Library++的C囧（NativeX，拿C改了点语法，当中间语言用，功能基本没有减少）编译器一直在重构。昨天晚上终于做了一个功能，可以把二进制格式的assembly转成文本文件供查阅了。虽然做了点代码生成的优化，不过其实还是不够好。接下来就是慢慢看文本文件里面记录的指令集，慢慢想办法优化输出的指令了。给C囧语言加上点泛型的想法开始成型了，虽然这主要是为了高级语言编译到低级的C囧语言所做的准备，不过还是有点麻烦。Vczh Library++的最终目的就是提供本地强类型语言、垃圾收集的面向对象强类型语言和动态语言三种语言的编译器和一些辅助类，让这三种语言可以编译到相同的assembly，互相调用，并且提供大量工具可以让用户们基于这三种语言的编译器轻松开发出自己的语言。最后只要把最低级的C囧语言的JIT给做了，就等于所有语言同时享受JIT带来的好处。革命尚未成功，同志仍需努力。<br><br>明天上飞机，美帝的人民群众对食物果然还是没有追求啊，还是天朝好&#8230;&#8230; 
<img src ="http://www.cppblog.com/vczh/aggbug/114754.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-05-07 14:56 <a href="http://www.cppblog.com/vczh/archive/2010/05/07/114754.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++ 语法分析器开发指南</title><link>http://www.cppblog.com/vczh/archive/2010/04/28/113836.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Wed, 28 Apr 2010 04:05:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/04/28/113836.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/113836.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/04/28/113836.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/113836.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/113836.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Vczh Library++ 语法分析器开发指南陈梓瀚&nbsp;前言在日常的开发工作中我们总是时不时需要写一些语法分析器。语法分析器不一定指的是一门语言的编译器前端，也有可能仅仅是一个自己设计格式的配置文件的读写程序，或者是一门用来简化我们开发的DSL（领域专用语言）。我们可以选择使用XML，不过因为XML的噪音实在是太多，所以自己写语法分析器在有些情况下是必要的，特别是那种经常...&nbsp;&nbsp;<a href='http://www.cppblog.com/vczh/archive/2010/04/28/113836.html'>阅读全文</a><img src ="http://www.cppblog.com/vczh/aggbug/113836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-04-28 12:05 <a href="http://www.cppblog.com/vczh/archive/2010/04/28/113836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0之使用Performance Wizard检查性能瓶颈</title><link>http://www.cppblog.com/vczh/archive/2010/04/17/112840.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sat, 17 Apr 2010 04:42:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/04/17/112840.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/112840.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/04/17/112840.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/112840.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/112840.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 这几天使用Performance Wizard搞了一下我的那个东西，结果发现瓶颈在一个很不可思议的地方，当然总的原因是因为虚函数调太多了，所以得修改修改。不过还好，还是有不破坏设计的办法的。<br><br>&nbsp;&nbsp;&nbsp; Performance Wizard是Visual Studio自带的一个工具。使用的时候很简单，首先找Analyze -&gt; Launch Performance Wizard...，出来一个向导。第一个页面选你要做检查的工程，第二个页面在Sampling和Instrumentation之间作选择（我一般选择后面的），完成了之后就会出来一个叫Performance Explorer的窗口，里面有建立好的性能检测文件，当然是不保存的，一般来说也不用保存。Performance Explorer的根节点跟你的解决方案同名，右键选择Properties，在Sampling的Sample Event里面选择Performance Counter，好了大功告成。<br><br>&nbsp;&nbsp;&nbsp; 想启动很简单，首先将你的编译指向Release，然后选择Performance Explorer根节点下面Targets目录下面的一个跟工程同名的节点，点击Performance Explorer工具栏上有绿色箭头的按钮，然后就开始了。上面的配置将性能分析指到了最精确的一种方法，因此运行的时候慢，而且产生的文件特别大，建议在超级好的机器上使用。不然的话就只好使用Sampling而不是Instrumentation了。这个时候Performance Wizard会编译你的工程然后执行一直到结束，执行的过程中记录下很多信息。注意在Vista或以上操作系统，Visual Studio要用管理员权限打开才能正常使用Performance Wizard。<br><br>&nbsp;&nbsp;&nbsp; 之后就一直等，完了就会有一张超级详细的报表出来，这个时候切换到&#8220;Call Tree&#8221;报表，上面一个火苗样子的工具栏按钮按下去就自定寻找性能瓶颈并定位。这个Call Tree就是Call Stack在整个程序执行过程中的变化情况，附加信息非常详细，非常好用。<br><br>&nbsp;&nbsp;&nbsp; 慢慢享受吧，啊哈哈。
<img src ="http://www.cppblog.com/vczh/aggbug/112840.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-04-17 12:42 <a href="http://www.cppblog.com/vczh/archive/2010/04/17/112840.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0之C++调用NativeX脚本函数Demo（就算去美帝出差也要坚持写代码）</title><link>http://www.cppblog.com/vczh/archive/2010/04/11/112234.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Sun, 11 Apr 2010 07:19:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/04/11/112234.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/112234.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/04/11/112234.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/112234.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/112234.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 今晚在<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/" target=_blank>Vczh Library++3.0</a>里面实现了C++调用NativeX脚本函数的单元测试代码，这个Demo其实是从单元测试里面抽出来的。<br><br>&nbsp;&nbsp;&nbsp; 因为代码可以在<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/SourceControl/list/changesets" target=_blank>这里</a>下载到，所以这里只列出当前版本C++调用NativeX脚本函数的例子。首先我们假设有下面的字符串，然后存放在const WString&amp; code;的变量里面：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">unit&nbsp;simple_function;<br></span><span style="COLOR: #008080">2</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;Add(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;a,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;b){<br></span><span style="COLOR: #008080">3</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">b;<br></span><span style="COLOR: #008080">4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;exit;<br></span><span style="COLOR: #008080">5</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">6</span>&nbsp;<span style="COLOR: #000000">function&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;Sub(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;a,&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;b){<br></span><span style="COLOR: #008080">7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;result</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">b;<br></span><span style="COLOR: #008080">8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;exit;<br></span><span style="COLOR: #008080">9</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<br>&nbsp;&nbsp;&nbsp; 因为NativeX基本上是用来被更加高级的语言做编译媒介的中间语言，或者拿来写一点脚本引擎的库用的，因此语法并没有设计得十分的简练。大部分还是从便于分析，并且接近C语言的角度出发。现在的NativeX支持数组、指针、自定义函数和结构体，不过这个Demo为了显露出本质，就简单化了，只实现了一个加法函数和减法函数。<br><br>&nbsp;&nbsp;&nbsp; 那么假设这段代码已经保存在变量code里面，那么可以通过下面的方法来调用Add和Sub函数：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LanguageAssembly</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;references;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">WString</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;codes;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">List</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LanguageException</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;errors;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">codes.Add(code);<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ILanguageProvider</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;provider</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">GetNativeXProvider().provider;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LanguageAssembly</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;assembly</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">provider</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Compile(references.Wrap(),&nbsp;codes.Wrap(),&nbsp;errors.Wrap());<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">BasicLanguageMetadata</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;metadata</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">assembly</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">GetBasicLanguageMetadata();<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">BasicDeclarationInfo&nbsp;add</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">metadata</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">GetDeclaration(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">BasicDeclarationInfo&nbsp;sub</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">metadata</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">GetDeclaration(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">LanguageHost&nbsp;host(</span><span style="COLOR: #000000">65536</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">host.LoadAssembly(assembly);<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">Ptr</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">LanguageState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;state</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">host.CreateState();<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">BasicFunctionExecutor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;addFunc(add,&nbsp;state);<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">BasicFunctionExecutor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;subFunc(sub,&nbsp;state);<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">TEST_ASSERT(addFunc(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">TEST_ASSERT(subFunc(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">==-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);</span></div>
<br>&nbsp;&nbsp;&nbsp; 不通过BasicFunctionExecutor而想自己设置返回值指针和自己挨个把参数Push进堆栈也行，其实BasicFunctionExecutor的实现正是调用了这些原始接口来做到的。<br><br>&nbsp;&nbsp;&nbsp; 例子就分享到这里了，完整的代码请去<a style="TEXT-DECORATION: underline" href="http://vlpp.codeplex.com/SourceControl/list/changesets" target=_blank><font color=#800080>这里</font></a>下载。
<img src ="http://www.cppblog.com/vczh/aggbug/112234.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-04-11 15:19 <a href="http://www.cppblog.com/vczh/archive/2010/04/11/112234.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Vczh Library++3.0开发纪事之明天出发去美帝出差一个月</title><link>http://www.cppblog.com/vczh/archive/2010/04/09/112018.html</link><dc:creator>陈梓瀚(vczh)</dc:creator><author>陈梓瀚(vczh)</author><pubDate>Thu, 08 Apr 2010 16:16:00 GMT</pubDate><guid>http://www.cppblog.com/vczh/archive/2010/04/09/112018.html</guid><wfw:comment>http://www.cppblog.com/vczh/comments/112018.html</wfw:comment><comments>http://www.cppblog.com/vczh/archive/2010/04/09/112018.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/vczh/comments/commentRss/112018.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/vczh/services/trackbacks/112018.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 因为项目原因去美帝出差，codeplex的速度估计就下降了&#8230;&#8230;之前刚刚把NativeX写完，但是还剩下最后一个接口没在Language Provider上实现，因此还有一些Test Case没写完。现在把一个NativeX编译完之后，可以从LanguageAssembly上面反射出NativeX所有的接口。于是在这个基础之上就可以做ABI了。<br><br>&nbsp;&nbsp;&nbsp; 整个项目的大方向是将本地语言、托管强类型语言和托管动态语言有机的结合在一起，因此采取的路线是动态语言编译成托管语言，然后再编译成本地语言，在之后编译成指令集，就可以用虚拟机执行了。指令集还可以做JIT，最终让CPU直接执行x86的代码。<br><br>&nbsp;&nbsp;&nbsp; 在美帝一两天安顿好之后，将会做完第一个Language Provider对NativeX的支持，然后优化parser combinator和regular expression lexer，再补充好文档，然后发布第一个alpha preview binary。当然这个alpha preview binary距离项目的目标是相当远的，只是做一下将这一整套东西变成dll的试验。 
<img src ="http://www.cppblog.com/vczh/aggbug/112018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/vczh/" target="_blank">陈梓瀚(vczh)</a> 2010-04-09 00:16 <a href="http://www.cppblog.com/vczh/archive/2010/04/09/112018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>