轻量级脚本语言 Squirrel

openkk 13年前
     Squirrel是一种高级的面向对象的编程语言,Squirrel是一个强大的脚本工具,Squirrel可以用于开发对文件大小、内存占用、带宽以及实时性要求非常严格的程序(例如游戏,偶很纳闷游戏需要这么高的要求嘛?)。尽管Squirrel提供了大量的特性(例如支持动态数据类型,委托,函数对象,迭代器,尾递归,异常处理,自动内存管理),Squirrel包括编译器和虚拟机的全部代码只有6000行不到的代码。    <br />       它从著名的LUA语言继承了很多特性,适用的范围也与LUA语言相似。    <br /> Squirrel的作者是意大利人Alberto Demichelis,SQUIRREL开发的本意是用于替代LUA,LUA的很多语法与C/C++ 不一致,C/C++程序员写脚本时,容易犯错误,而SQUIRREL语法与C/C++很相似,因此Squirrel更适合C/C++ 程序员。    <br /> Squirrel是一种动态语言,它有一个编译器和虚拟机,代码会被动态编译成字节码,然后在虚拟机上执行。当然,这种编译比C/C++或者Java的编译要简单很多,它的虚拟机也不会有JVM这样“底层”,Squirrel的虚拟机更像是一个“函数执行队列”,这个虚拟机是建立在标准libc基础上的(也就是说标准C函数在这个虚拟机中是元操作,而JVM是建立在汇编语言基础上的)。    <br /> Squirrel在设计上就是要做到嵌入C/C++程序,因此,Squirrel虚拟机可以与C/C++工作在一个进程/线程当中,通过虚拟机的接口,C/C++的数据可以被嵌入的Squirrel代码访问,反之Squirrel的代码和数据也可以被C/C++完全控制。    <br /> 从语言结构上看,Squirrel与Lua一脉相承,Squirrel与Lua的基础都是广义表(或者说是一颗多叉树),Hash算法在这个广义表中起到一个关键的作用。    <br /> Squirrel代码和数据都是组织在一个广义表当中的。数据、函数、类(Lua不支持OO,Squirrel支持有限的OO)都是广义表的一个值,值都是采用<名称,值>的方式存储的,通过对名称的Hash,可以很方便的找到值。    <br /> Squirrel比Lua更好的支持OO,Squirrel可以定义类,允许类继承,能够自动执行构造(constructor函数),而Lua只能通过Table来模拟类。更关键的一点,Squirrel允许类产生实例(instance),每个实例拥有自己的存储空间,在这点上,比Lua的模拟类明显好用。    <br /> Squirrel支持在每个实例上设置一个Userpoint,这个特性非常有利与与C++Object的接口,一个Squirrel类可以的作为一个C++ class的影子运行,我们只需要在Squirrel上实现C++class的接口,通过Squirrel的Userpoint,即可操控这个C++ Object。    <br /> 值得关注的是Squirrel的执行速度,执行一个10000元素的数组创建及遍历,其速度大约是C++的1/4,比Lua快20%。    <br /> Squirrel的保留字与C++几乎一致,但Squirrel没有指针,内存由虚拟机管理,不需要手工申请和释放,所以没有new和delete关键字。Squirrel是弱类型的,所以也就没有char、float、int、double等关键字,值得注意到是Squirrel不支持double(Squirrel 3.0支持使用double代替float),其浮点数内部是float,这可能与Squirrel主要为游戏设计有关。    <br /> Squirrel新增了一些关键字,主要有local、typeof、instanceof、resum、yield、delegate、parent等(其中delegate、 parent关键字在Squirrel3.0Alpha版中似乎有变化),resum、yield用于Squirrel的“协程”,可以理解为非抢先式的内部线程(Squirrel虚拟机是单线程的,一个虚拟机内部不支持系统的线程,这和Lua很相似)。    <br /> 值得注意的是local关键字,Squirrel中的变量是需要定义的,和C++一样,你可以在程序的任何地方定义,但定义的时候必须使用local关键字。使用local表明变量在堆栈里创建,离开函数才会自动销毁。    <br /> Squirrel循环控制语句增加了foreach循环,而且这个foreach不像Lua一样需要什么“闭包”,可以很简单的使用,例如foreach(local i in arrayVar){},这完成对一个数组的遍历,foreach(local key,value in tableVar){}, 这完成对一个表达遍历。    <p>示例代码</p>    <pre class="brush:cpp; toolbar: true; auto-links: false;">local table = {   a = "10"   subtable = {    array = [1,2,3]   },   [10 + 123] = "expression index"  }     local array=[ 1, 2, 3, { a = 10, b = "string" } ];     foreach (i,val in array)  {   ::print("the type of val is"+typeof val);  }     /////////////////////////////////////////////     class Entity  {    constructor(etype,entityname)   {    name = entityname;    type = etype;   }              x = 0;   y = 0;   z = 0;   name = null;   type = null;  }     function Entity::MoveTo(newx,newy,newz)  {   x = newx;   y = newy;   z = newz;  }     class Player extends Entity {   constructor(entityname)   {    base.constructor("Player",entityname)   }   function DoDomething()   {    ::print("something");   }     }     local newplayer = Player("da playar");     newplayer.MoveTo(100,200,300);  </pre>    <img title="logo.gif" border="0" alt="logo.gif" src="https://simg.open-open.com/show/be649bbe23565b81bacf62ecbc7e8803.jpg" />    <p></p>