摘要: 今天上完课回来继续把昨天晚上剩下的using字句完成。使用Syngram写编译器真是舒服啊,直接在代码里面加两条推导式就完成了。昨天发现了InsertEnv指令的bug以后,改过来了。不过InsertEnv不能用在using身上,只好另外写了一个UsingEnv指令,把环境以及上游的链表而不是多个环境插进当前的环境中。这里展示了class和namespace是如何通过闭包(函数)来实现的,以及他们的构造过程。
class以及namespace都是通过在return的跳转目标后添加指令而保证return结束但是不修改class和namespace表达式的返回值。
class函数的参数是父类的构造子,class函数在所有代码之前首先构造好一个父类的链表,然后通过InsertEnv将这个表引用到自己身上,从而实现了正确的scope。然后让constructor为空函数。ClassName.new()的时候首先运行class函数(使用callctor而不是invoke来自动找到父类并添加到参数中),然后复制堆栈,获取construct
阅读全文
posted @
2008-05-11 21:37 陈梓瀚(vczh) 阅读(1513) |
评论 (4) |
编辑 收藏
摘要: 今天抓到了一个隐藏了3个月的bug。这个bug以前一直没有被找到,因为以前写的用于测试脚本的代码都没有出现类成员函数使用非全局的外部对象的情况。Vampire.Kiss用我的Vczh Free Script代替PHP开发了一个网站,过程中也向我提了不少要求。其中有一套就是想在脚本中加入namespace。其实这是相当合理的,只是我没想到脚本第一次应用就会被用来开发库。因此今晚就加上了namespace。
实际上在目前的结构中添加namespace并不复杂,因为namespace也可以用闭包来模拟。其实闭包不仅仅是函数,而是一段带了上下文的指令表。因为namespace本身也是用于控制符号在上下文中解释方法工具,因此使用闭包来做也就是十分合适的了。想到以前是用闭包模拟class的时候,曾经实现了一个把一堆环境链接到上下文中的指令。类的继承实际上也是控制符号在类成员函数的符号在上下文解释方法的工具,因此我使用了如下方法来让闭包可以顺利地模拟class的继承:
阅读全文
posted @
2008-05-11 10:07 陈梓瀚(vczh) 阅读(1829) |
评论 (5) |
编辑 收藏
摘要: 有个同学近来一直在做一个魔兽世界战况分析(名字好像叫DeusCraft),说是很火。只是用C#觉得不是很爽,想移植到C++上面来。但是那个东西在分析的时候用了好多正则表达式,于是只好找了些正则表达式引擎来测。
测试的文件一共有27万多行,首先通过一个检查时间的正则表达式。如果成功,则在接下来的20几条正则表达式中验证字符串命中哪一条,然后开始做剩余的工作。原先在C#上花了12秒分析,后来换了boost的正则表达式花费40秒,然后从MSR上找了一个号称比boost快4倍的正则表达式引擎,结果还是40秒(都是微软的,咋差距这么大……)。于是同学用他自己做的正则表达式引擎花了23秒(此数据不太记得),我用我以前那个东西花费108秒(-_-|||)。
于是我们这几天就在优化正则表达式引擎,到了今天同学那个花费13秒,我那个12秒。Visual Studio 2008 Team System上有一个Performance Wizard,用于在程序执行的过程中统计各个函数所占用的时间,可以方便定位,看出效率瓶颈,非常好用。
阅读全文
posted @
2008-05-07 05:21 陈梓瀚(vczh) 阅读(15391) |
评论 (21) |
编辑 收藏
摘要: 华南理工大学软件学院本科05级3班,陈梓瀚(vczh)
游戏规则:
1:地图上可以建立三种炮塔塔,游戏有上、左两个敌人的起始点,两个起始点的敌人分别到下、右两个终止点。
2:每一盘有1000个等级分别从1-200的敌人从起始点出发自动寻路前往终止点。如果有10个敌人到达了终止点的话则游戏结束,玩家输。如果所有的敌人都被消灭或到达终止点之后,到达终止点的敌人没有10个的话则游戏结束,玩家赢。
3:建立炮塔的方格敌人不能通过。在建立一个炮塔的时候,如果程序发现这个炮塔的建立会导致敌人找不到任何路径前往各自的终止点的话,则建立被禁止。
4:炮塔可以是用金钱建立或升级,可以卖出货的金钱。消灭敌人能够获得金钱。
5:三种炮塔分别是
·升级后数量变多,射程变长,攻击力变强
·升级后速度变快,射程变长,攻击力变强
·升级后一次爆炸伤害的范围变大,射程变长,攻击力变强
·升级一次后减速范围变大,减速因子变大
6:炮弹在 阅读全文
posted @
2008-05-02 21:46 陈梓瀚(vczh) 阅读(9504) |
评论 (27) |
编辑 收藏
摘要: 第一次用C#写游戏。在C#上写算法果然是一个挑战,时间复杂度太大的话造成的后果比C++明显好多,于是总是尽量把东西做成O(n)或者O(nlogn)。这次就在上面实现了一个寻路算法。
这个寻路算法是这样的:在16×16的方格上有一些终点,东西在格子上只能上下左右行动。每一个格子需要记录到其中一个终点的最近的路的第一个方向(就像三层循环的寻路算法一样,最后给出矩阵的那个)。 阅读全文
posted @
2008-04-30 05:29 陈梓瀚(vczh) 阅读(4427) |
评论 (5) |
编辑 收藏
摘要: Lazy Compile使用Syngram动态创建语法分析器的代码实在是太慢了,debug竟然需要8秒钟来处理91条比较长的文法。于是我打开了Visual Studio 2008的Performance Wizard查看运行时消耗的资源,结果发现竟然都消耗在自己那个array类的operator[]里面了。那一段代码是用来检查文法的左递归引用关系是否出现环的。结果就把用到的四个array全部换成bool*了,当时只是为了创建二维数组方便使用了array类。
过后,debug的时间立刻降为2秒钟不到,于是我又打开Performance Wizard看了一次,这次消耗的瓶颈终于转移到一个合理的地方了。
结果:array竟然比指针慢了无穷多倍,得找个时候重新写一次。不过这段代码好象是去年写的,也没经过什么性能测试,也难怪发现不了问题。在此帖上代码,等Lazy Script写完了重新审查一下自己的那套模板库(NTL,Non-standard Template Library,娃哈哈)。 阅读全文
posted @
2008-04-27 19:53 陈梓瀚(vczh) 阅读(2621) |
评论 (6) |
编辑 收藏
摘要: 这几天一直在忙学校的比赛,到了今天终于有空了。
Lazy Script的语法实在是很复杂,因此不得不在进行第一步的名字检查之后把原本的语言转换为内部使用的一种元语言。这种元语言设计的原则是尽量简单。譬如列表构造和do-end语句就需要被转换掉。进行了转换以后,就需要对元语言进行一个类型方程组的建立。这一步暂时还没有建模好,而且实际工作需不需要真的构造出一组方程组还不知道。目前还比较没有头绪的就是如何对模板函数的类型方程建模。
举个例子,譬如我们对上一篇文章中提到的代码进行类型方程组的构造: 阅读全文
posted @
2008-04-27 10:16 陈梓瀚(vczh) 阅读(2123) |
评论 (0) |
编辑 收藏
摘要: 花了两天的时间终于完成了Vczh Lazy Script的语法分析工作。语法分析是编译的第一步,旨在把输入的字符串(代码)分析称跟代码结构一致的语法树,以便后续工作。
藉着去年开发的Syngram工具包,这两天过得还算轻松,仅仅对语言做了一份配置,不过这份配置也花掉了1200多行代码。语法分析其余的部分是数据结构。目前的数据结构仅仅用于再现语言的结构,而没有附加任何的数据。接下来的工作是检查所有的identifier,看看有没有哪些identifier是使用错误的。一般来说都是在左值使用函数、类构造标签参数不全、转移运算符指向的函数并没有声明成函数等等比较基本的东西。但是后续的工作就相当地麻烦了。
作为一门lazy+pure的函数范式程序语言,我模仿了Haskell的大部分语法,加上自己的一点点修改(因为Haskell的语法实在是太诡异了),但是主要功能是没有变化的。等上面所说的identifier完成以后,我就要开始写Lazy的类型推导程序了。类型推导程序用于计算出代码中省略的类型声明,相当于把整份代码转换成类型方程然后求解 阅读全文
posted @
2008-04-22 04:03 陈梓瀚(vczh) 阅读(2538) |
评论 (4) |
编辑 收藏
摘要: 已经忘了是去年还是前年听到微软说要在C# 3.0里为C#添加lambda表达式,与此同时Java的团队也一直在说想为Java添加lambda表达式。到了今天,C#似乎已经把这个特性加进去了,Java还没有。Java说这个特性还在计划列表之中,不过暂时可以使用匿名类来代替。想必是因为在Java中表示函数指针的方法比较奇怪罢……
其实无论是lambda表达式(事实上应该叫匿名函数)或是匿名类,都能归属到一种叫闭包的东西上面。闭包原来是代数中的用语,只是那些研究理论的老大们觉得这玩意儿也能拉到“闭包”里面去,于是就叫闭包了。匿名函数原本是丘奇发明的一个lambda-calculus的其中一部分,后来计算机的老大们突然发现lambda-calculus非常适合用来充当程序设计语言的模型,于是就对它进行了非常多的扩充,还弄了个什么类型理论出来。好像扯远了。
想象一下如下使用闭包的代码:
MyClosure=func(Number1)
{
return func(Numbe 阅读全文
posted @
2008-04-20 21:55 陈梓瀚(vczh) 阅读(7701) |
评论 (5) |
编辑 收藏
摘要: ExpCmList -> Expression ["," ExpList]
ArrCmList -> [LeftValue "<-"] Expression ["," ArrList]
CaseList -> LeftValue ":" Expression ";" [CaseList]
DoList -> ([LeftValue "="]Expression | LeftValue "::" TypeDes ) ";" [DoList]
WhereList -> (FuncHead | FuncBody) ";" [WhereList]
Exp0 ->
Exp0 -> FuncName
Exp0 -> "(" [ExpCmList] ")"
Exp0 -> "[" [ExpCmList] "]"
Exp0 -> "[" Expression "|" ArrCmList "]"
Exp0 阅读全文
posted @
2008-04-20 20:50 陈梓瀚(vczh) 阅读(1856) |
评论 (3) |
编辑 收藏