我早就想写一个脚本引擎了,真的。
事情可以追溯到大一的时候,很想做游戏(虽然后来发现美工成了最大的问题),于是自己写了一套GUI,用起来还挺爽,但是就是一直觉得缺了个脚本引擎。
于是,奉天承运,我开始着手脚本引擎的计划了。
话说起码得先跟字符串培养培养感情,而且也是为了以后写脚本引擎时能省些苦力,还有很多其他因素影响,我决定先写一个正则表达式引擎。为了方便,我又得封一个性格良好,功能顽强的String类,要真的实现功能顽强,又得搞好Encoding方面的事情,要方便调试程序,又得把Console和IO方面的东西封好。于是我干脆就跟他拼了,封了一个类.Net的小类库出来。为了好看,名字空间搞得跟.Net的一模一样,用起来也挺顺溜的。
1 #include "System.h"
2
3 using namespace System;
4 using namespace System::Text::RegularExpressions;
5 using namespace System::Windows::Forms;
6
7 int Program(const String& arg)
8 {
9 Application::RunConsoleApplication();
10
11 Regex exampleExp("(+\\w+):(+\\z+)");
12 String exampleString = "hello:哈喽!!!";
13
14 Int64 startTime = GetTickCount();
15 Match* m = exampleExp.Match(exampleString);
16 Int64 endTime = GetTickCount();
17
18 Console::WriteLine("---------KSystem Example Program---------");
19 Console::WriteLine("Example Regex:\t" + exampleExp.Pattern());
20 Console::WriteLine("Example String:\t" + exampleString);
21 Console::WriteLine("Matched Value:\t" + m->Value());
22 Console::WriteLine(m->Captures[0] + ":" + m->Captures[1]);
23 Console::WriteLine("Time Cost:\t" + String::ToString(endTime - startTime) + " ms");
24 Console::WriteLine("-----------------------------------------");
25
26 return 0;
27 }
不要问我为什么字符串前面不加L,也不要问我为什么没有delete那个m,我的库会干这些事情的。表达式中那个\z是匹配中文字的意思
运行结果:
做这么个正则表达式,还输掉了我一餐pizza。当时跟vczh同学打赌,他说我写完肯定有bug,我说我肯定没bug。结果不出意料地有bug,于是一餐华丽的pizza被送进了我们肚子。重要经验:是个程序必然有bug,恩恩。
这个正则表达式引擎刚写出来时性能奇差无比,主要时间耗在了内存分配上。经过一系列优化,vczh也跟着我一起优化了他那个正则表达式引擎,到最后某次性能测试时,我的花了13秒,vczh同学的花了12秒,也有时候是我的更快,视表达式写法不同而略有差别,基本上平均下来是一样的。(boost和greta花了40+N秒)
有了正则表达式引擎,也有了跟字符串几个月的感情,现在终于开始计划脚本引擎了。由于还是第一次,总有点畏首畏尾的,我决定先写一个非常菜的版本。强类型,无闭包,面向过程,支持数组,不支持自定义结构。这是我计划的CNScript的第一版本,也称CaiNiaoScript。
其实我真的想实现的是CNScript的第二个版本,ChinaScript。这会是一个类自然语言写法的中文脚本引擎。写起来变量和函数命名绝对会很不习惯,但是写完之后却会像一篇文章一样流利。
例如:现在用C++,模拟一个人使用某个交通工具去某个地方的行为。
Class TrafficTool;
Class Car : public TrafficTool;
Class Man
{
void TravelTo(Point destination, TrafficTool* trafficTool);
};
用起来就是
Man Peter;
TrafficTool* BMW = new Car();
Point beijing;
Peter.TravelTo(beijing, BMW);
虽然程序员一看就能理解个大概,但是非程序员很难使用或维护它。在将来的CNScript中,也许会是这样(估计最后不会这么罗嗦):
有一种东西叫交通工具,汽车就是一种交通工具。
有一种东西叫人。 //我承认这句话有点怪,语法细节问题需要仔细琢磨,谁有好的建议可以留言给我喔,感激万分
有一种东西叫做目的地。
有一种行为:一个人乘坐一个交通工具去往一个目的地。
//以上是声明,以下是使用这几个类的代码
有一个人叫Peter。
有一个汽车叫宝马。
有一个目的地叫北京。
Peter乘坐宝马去往北京。
这样的代码,虽然在函数和变量命名时要仔细考虑,但是写出来的代码即使是不懂程序的人也能看明白,为的是兼顾游戏开发的各个环节的人员。
好了,想法到此为止,今晚开始动工CNScript的第一版,CaiNiaoScript! 我会把我每个阶段的工作和工作原理都写在这篇日记中,有兴趣的朋友可以跟着一起玩玩喔!