Squirrel 3.1 参考手册

Squirrel 3.1 参考手册

首先到http://squirrel-lang.org/ 下载3.1版

压缩包解压后,里面直接有工程文件,用VS打开。

squirrel是脚本的引擎库

sqstdlib 是脚本的标准库,不是必须的,但是包含了很多基础操作

sq    编译后是一个exe,控制台程序

首先:工程默认是多字节字符集,我们全部改成Unicode字符集,因为现在的程序基本都是Unicode的了。

其次:在预处理里面添加_CRT_SECURE_NO_WARNINGS 宏,这不是必须的,可以取消警告

最后:编译Debug版本时,需要将c/c++ -> 常规 -> 调试信息格式 改为 程序数据库(/Zi),当然在 库管理器->常规->输出文件,可以将文件名后面增加一个d,用于区分Debug版和Release版

编译后就会在lib目录下生成lib文件,include 目录就是包含目录,这样我们就能使用这个库了。

——————————————————————————————————————————-

下面是官方文档的说明(翻译不一定准确,但是基本能看懂):

嵌入Squirrel

1、内存管理

Squirrel使用引用计数(RC)作为系统主要的内存管理;但是,虚拟机(VM)具有可根据需要调用的辅助标记和清除垃圾收集器。

编译时有两种可能的选项:

默认配置包括RC加上标记和清除垃圾收集器。宿主程序可以调用sq_collectgarbage()函数并在程序执行期间执行垃圾收集循环。 VM不会调用垃圾收集器,必须由宿主程序显式调用。

第二种情况仅包括RC(定义NO_GARBAGE_COLLECTOR);在这种情况下,VM无法检测参考周期,因此程序员必须明确地解决它们以避免内存泄漏。

第二个选项引入的唯一优势是在默认配置中使用垃圾收集器(32位系统为8个字节)保存2个必须为每个对象存储的附加指针。涉及的类型有:tables, arrays, functions, threads, userdata 和 generators; 其他类型都不受影响。这些选项不会影响执行速度。

2、构建配置

Unicode

通过在C ++预处理器中定义SQUNICODE 宏则采用UCS2编码,也就是Unicode

x64

通过在C ++预处理器中定义 SQ64宏,可以在64位体系结构上编译Squirrel。 该标志应该在包含’squirrel.h’的任何项目中定义。

用户数据对齐

类实例和userdata都可以有一个与之关联的缓冲区。 Squirrel通过定义SQ_ALIGNMENT的peroprocessor指定对齐(以字节为单位)。 默认情况下,SQ_ALIGNMENT被定义为4表示32位构建,8表示64位构建和构建使用64位浮点数。 可以覆盖遵循以下规则的SQ_ALIGNMENT的值。 SQ_ALIGNMENT应小于或等于SQ_MALLOC对齐,并且它应为2的幂。

注意

这仅适用于VM分配的userdata,通过sq_setclassudsize()指定或属于userdata对象。 用户指定的用户指针不受alignemnt规则的影响。

没有编译器的独立VM

通过在C ++预处理器中定义”NO_COMPILER”,可以在没有编译器的情况下编译Squirrel的VM。 当定义’NO_COMPILER’时,与编译器相关的所有函数(例如sq_compile)都将失败。 有条件地加载预编译字节码或编译文件(例如sqstd_dofile)的其他函数仅适用于预编译的字节码。

3、错误约定

API中的大多数函数返回SQRESULT值; SQRESULT指示函数是否成功完成。 宏SQ_SUCCEEDED()和SQ_FAILED()用于测试函数的结果:

if(SQ_FAILED(sq_getstring(v,-1,&s)))

    printf(“getstring failed”);

4、虚拟机初始化

主机应用程序必须做的第一件事是创建一个虚拟机。 宿主应用程序可以通过sq_open()函数创建任意数量的虚拟机。 使用sq_open()创建的每个VM必须在不再需要时使用sq_close()函数释放:

int main(int argc, char* argv[])

{

    HSQUIRRELVM v;

    v = sq_open(1024); //creates a VM with initial stack size 1024

    //do some stuff with squirrel here

    sq_close(v);

}

5、栈 Stack

Squirrel通过栈与虚拟机交换值。 这种机制继承自Lua语言。 例如,要从C调用Squirrel函数,必须将函数和参数压入堆栈然后调用函数; 当Squirrel调用C函数时,参数也将在堆栈中。

栈索引:

许多API函数可以通过索引任意引用栈中的任何元素。 栈索引遵循以下约定:

1是栈底部

负索引被认为是从栈顶部的偏移量。 例如,-1是栈的顶部。

0是无效索引

下面是一个例子(让我们假设这个表是VM堆栈)

正索引 父索引
“test” 4 -1(top)
1 3 -2
0.5 2 -3
“foo” 1(base) -4

在这种情况下,函数sq_gettop将返回4;

栈操作:

API提供了几种从Squirrel栈中推送和检索数据的功能。

要将栈中已存在的值推到顶部位置:

void sq_push(HSQUIRRELVM v,SQInteger idx);

要弹出任意数量的元素:

void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);

要从栈中删除元素:

void sq_remove(HSQUIRRELVM v,SQInteger idx);

要检索当前虚拟栈的顶部索引(和大小),必须调用sq_gettop

SQInteger sq_gettop(HSQUIRRELVM v);

要将栈强制为特定大小,可以调用sq_settop

void sq_settop(HSQUIRRELVM v,SQInteger newtop);

如果新顶部大于前一个顶部,则栈中的新位置将填充空值。

以下函数将C值压入堆栈:

void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);

void sq_pushfloat(HSQUIRRELVM v,SQFloat f);

void sq_pushinteger(HSQUIRRELVM v,SQInteger n);

void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);

void sq_pushbool(HSQUIRRELVM v,SQBool b);

此函数将null压入栈:

void sq_pushnull(HSQUIRRELVM v);

返回栈中任意位置的值的类型:

SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);

结果可以是以下值之一:

OT_NULL,OT_INTEGER,OT_FLOAT,OT_STRING,OT_TABLE,OT_ARRAY,OT_USERDATA,

OT_CLOSURE,OT_NATIVECLOSURE,OT_GENERATOR,OT_USERPOINTER,OT_BOOL,OT_INSTANCE,OT_CLASS,

OT_WEAKREF

以下函数将栈中的squirrel值转换为C值:

SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);

SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);

SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);

SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);

SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);

SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *p);

函数sq_cmp比较栈中的2个值并返回它们的关系(如ANSI C中的strcmp()):

SQInteger sq_cmp(HSQUIRRELVM v);

6、运行时错误处理

当使用带有try / catch语句的Squirrel代码处理异常时,会引发运行时错误并中断当前程序的执行。 可以设置回调函数来拦截来自主程序的运行时错误; 这对于向脚本编写器显示有意义的错误以及实现可视化调试器很有用。 以下API调用从栈中弹出Squirrel函数并将其设置为错误处理程序:

SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);

使用2个参数,环境对象(this)和对象调用错误处理程序。 对象可以是任何Squirrel类型。

7、编译脚本

您可以使用sq_compile函数编译Squirrel脚本:

typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer userdata);

SQRESULT sq_compile(HSQUIRRELVM v,SQREADFUNC read,SQUserPointer p,

            const SQChar *sourcename,SQBool raiseerror);

为了编译脚本,主机应用程序必须实现一个读取器函数(SQLEXREADFUNC); 此函数用于向编译器提供脚本数据。 每次编译器需要一个字符时都会调用该函数; 如果成功则必须返回字符代码,如果源码完成则返回0。

如果sq_compile成功,则编译后的脚本将作为Squirrel函数压入到栈中。

这是一个从文件中读取的”read”函数的示例:

SQInteger file_lexfeedASCII(SQUserPointer file)

{

    int ret;

    char c;

    if( ( ret=fread(&c,sizeof(c),1,(FILE *)file )>0) )

        return c;

    return 0;

}

int compile_file(HSQUIRRELVM v,const char *filename)

{

    FILE *f=fopen(filename,”rb”);

    if(f)

    {

         sq_compile(v,file_lexfeedASCII,f,filename,1);

         fclose(f);

         return 1;

    }

    return 0;

}

当编译器因语法错误而失败时,它将尝试调用”编译器错误处理程序”; 此函数必须声明如下:

typedef void (*SQCOMPILERERROR)(HSQUIRRELVM /*v*/,const SQChar * /*desc*/,const SQChar * /*source*/, SQInteger /*line*/,SQInteger /*column*/);

并且可以使用以下API调用进行设置:

void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);

8、调用函数

要调用squirrel函数,必须在栈中压入函数跟参数后,然后调用函数sq_call。 如果最后一个sq_call参数> 0,该函数将弹出参数并压入返回值。

sq_pushroottable(v);

sq_pushstring(v,”foo”,-1);

sq_get(v,-2); //从根表获取函数

sq_pushroottable(v); //’this’ (函数环境对象)

sq_pushinteger(v,1);

sq_pushfloat(v,2.0);

sq_pushstring(v,”three”,-1);

sq_call(v,4,SQFalse);

sq_pop(v,2); //弹出根表和函数

这相当于以下Squirrel代码:

foo(1,2.0,”three”);

如果在执行squirrel代码期间发生运行时错误(或抛出异常),则sq_call将失败。

9、创建C函数

本机C函数必须具有以下原型:

typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);

参数是调用VM的句柄,返回值是一个遵循以下规则的整数:

如果函数返回值,则返回1

如果函数未返回值,则为0

抛出SQ_ERROR运行时错误

为了从C函数指针获取新的可调用squirrel函数,需要调用sq_newclosure()将C函数传递给它;新的Squirrel函数将被压入栈。

调用该函数时,stackbase是函数的第一个参数,top是最后一个参数。为了返回一个值,函数必须将其压入栈并返回1。

函数参数位于从位置1(’this’)到n的栈中。 sq_gettop()可用于确定参数的数量。

如果函数具有自由变量,那么在显式参数之后,这些变量可以作为普通参数处理。另请注意,sq_gettop()返回的值将受自由变量的影响。 sq_gettop()将返回参数数量加上自由变量数量。

这里有一个例子,下面的函数打印每个参数的值并返回参数个数。

SQInteger print_args(HSQUIRRELVM v)

{

    SQInteger nargs = sq_gettop(v); //number of arguments

    for(SQInteger n=1;n<=nargs;n++)

    {

        printf(“arg %d is “,n);

        switch(sq_gettype(v,n))

        {

            case OT_NULL:

                printf(“null”);

                break;

            case OT_INTEGER:

                printf(“integer”);

                break;

            case OT_FLOAT:

                printf(“float”);

                break;

            case OT_STRING:

                printf(“string”);

                break;

            case OT_TABLE:

                printf(“table”);

                break;

            case OT_ARRAY:

                printf(“array”);

                break;

            case OT_USERDATA:

                printf(“userdata”);

                break;

            case OT_CLOSURE:

                printf(“closure(function)”);

                break;

            case OT_NATIVECLOSURE:

                printf(“native closure(C function)”);

                break;

            case OT_GENERATOR:

                printf(“generator”);

                break;

            case OT_USERPOINTER:

                printf(“userpointer”);

                break;

            case OT_CLASS:

                printf(“class”);

                break;

            case OT_INSTANCE:

                printf(“instance”);

                break;

            case OT_WEAKREF:

                printf(“weak reference”);

                break;

            default:

                return sq_throwerror(v,”invalid param”); //throws an exception

        }

    }

    printf(“\n”);

    sq_pushinteger(v,nargs); //push the number of arguments as return value

    return 1; //1 because 1 value is returned

}

这里有一个如何注册函数的例子:

SQInteger register_global_func(HSQUIRRELVM v,SQFUNCTION f,const char *fname)

{

    sq_pushroottable(v);

    sq_pushstring(v,fname,-1);

    sq_newclosure(v,f,0,0); //create a new function

    sq_newslot(v,-3,SQFalse);

    sq_pop(v,1); //pops the root table

}

10、表和数组操作

创建一个新表调用sq_newtable,该函数在栈中压入一个新表:

void sq_newtable(HSQUIRRELVM v);

要创建新插槽:

SQRESULT sq_newslot(HSQUIRRELVM v,SQInteger idx,SQBool bstatic);

设置或获取表委托:

SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);

SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);

创建一个新数组调用sq_newarray,该函数在栈中压入一个新数组; 如果参数size大于0,则元素初始化为null:

void sq_newarray (HSQUIRRELVM v,SQInteger size);

要将值附加到数组的后面:

SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);

要从数组后面删除值:

SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQInteger pushval);

要调整数组大小:

SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);

要获取表或数组的大小,必须使用sq_getsize():

SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);

要在数组或表中设置值:

SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);

要从数组或表中获取值:

SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);

从没有使用委托的表中获取或设置值:

SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);

SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);

迭代表或数组:

SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);

这是一个如何执行迭代的示例:

//在这里压入你的 table/array

sq_pushnull(v)  // null iterator

while(SQ_SUCCEEDED(sq_next(v,-2)))

{

    //这里-1是值,-2是键

    sq_pop(v,2); //在下一次迭代之前弹出键和值

}

sq_pop(v,1); //pops the null iterator

11、用户数据和用户指针(Userdata和UserPointers)

Squirrel允许宿主应用程序将任意数据块放入Squirrel值,这可以通过数据类型userdata:

SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);

当调用sq_newuserdata函数时,Squirrel会分配一个具有指定大小的新用户数据,返回指向其有效缓冲区的指针并将该对象压入堆栈中; 此时应用程序可以使用此内存块执行任何操作,VM将自动执行内存释放的操作,就像其他所有内置类型一样。 用户数据可以传递给函数或存储在表槽中。 默认情况下,Squirrel无法直接操纵userdata; 但是可以为其分配一个委托并定义一个类似于表的行为。应用程序可能希望对存储在userdata对象在删除时,对数据执行某些操作,因此可以在删除某个用户数据之前分配将由VM调用的回调。 这是通过API调用sq_setreleasehook完成的:

typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);

void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);

另一种用户数据是用户指针; 这种类型不像普通用户数据那样是一个内存块,而只是一个’void *’指针。 它不能有委托并且按值传递,因此推送用户指针不会导致任何内存分配:

void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);

12、注册表( registry table )

注册表是vm和他所有线程(朋友vms)之间共享的隐藏表。 此表只能通过C API访问,并且是本机C库实现的实用程序结构。 例如,sqstdlib(squirrel标准库)使用它来存储配置和共享对象委托。 可以通过API调用sq_pushregistrytable()访问注册表:

void sq_pushregistrytable(HSQUIRRELVM v);

13、维护对C API中Squirrel值的引用

Squirrel允许通过C API引用值; 函数sq_getstackobj()获取一个squirrel对象(任何类型)的句柄。 对象句柄可用于通过添加或删除对象的引用来控制对象的生命周期(请参阅sq_addref()和sq_release())。 也可以使用sq_pushobject()将对象重新推送到VM堆栈中:

HSQOBJECT obj;

sq_resetobject(v,&obj) // 初始化对象句柄

sq_getstackobj(v,-2,&obj); //从pos -2中获取一个对象句柄

sq_addref(v,&obj); //对象添加引用

… //do stuff

sq_pushobject(v,&obj); //将对象压入栈

sq_release(v,&obj); //释放对象

14、调试接口

squirrel VM提供了一个非常简单的调试接口,可以轻松构建一个功能齐全的调试器。 通过函数sq_setdebughook和sq_setnativedebughook实际上可以设置一个回调函数,该函数将在每次VM执行脚本的新行或函数被调用/返回时调用。 回调将作为参数传递当前行当前源和当前函数名称(如果有):

SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);

SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook);

以下代码显示了调试钩子(显然也可以在C中实现此功能)。

function debughook(event_type,sourcefile,line,funcname)

{

    local fname=funcname?funcname:”unknown”;

    local srcfile=sourcefile?sourcefile:”unknown”

    switch (event_type) {

    case ‘l’: //called every line(that contains some code)

        ::print(“LINE line [” + line + “] func [” + fname + “]”);

        ::print(“file [” + srcfile + “]\n”);

        break;

    case ‘c’: //called when a function has been called

        ::print(“LINE line [” + line + “] func [” + fname + “]”);

        ::print(“file [” + srcfile + “]\n”);

        break;

    case ‘r’: //called when a function returns

        ::print(“LINE line [” + line + “] func [” + fname + “]”);

        ::print(“file [” + srcfile + “]\n”);

        break;

    }

}

参数event_type可以是’l’,’c’或’r’; 对于执行的每行调用带有’l’事件的钩子,每次调用函数时调用’c’,每次函数返回时调用’r’。

功能齐全的调试器始终允许显示局部变量和调用堆栈。 通过sq_getstackinfos()检索调用堆栈信息:

SQInteger sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);

而局部变量info通过sq_getlocal():

SQInteger sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger nseq);

为了接收行回调,必须在启用调试信息的情况下编译脚本,这通过sq_enabledebuginfo();

void sq_enabledebuginfo(HSQUIRRELVM v, SQInteger debuginfo);

Squirrel语法

1、词汇结构

(1)标识符

标识符以字母字符或”_”开头,后跟任意数量的字母字符,”_”或数字([0-9])。 Squirrel是一种区分大小写的语言,这意味着同一个字母字符的小写和大写表示被视为不同的字符。 例如,”foo”,”Foo”和”fOo”将被视为3个不同的标识符。

(2)关键字

以下单词是语言的保留字,不能用作标识符:

base break case catch class clone
continue const default delete else enum
extends for foreach function if in
local null resume return switch this
throw try typeof while yield constructor
instanceof true false static __LINE__ __FILE__

(3)操作符

! != || == && >= <= >
<=> + += -= / /= *
*= % %= ++ <- = &
^ | ~ >> << >>>    

(4)其他符号

{ } [ ] . :
:: ; @”  

(5)字面常量

34 Integer number(base 10)
0xFF00A120 Integer number(base 16)
0753 Integer number(base 8)
‘a’ Integer number
1.52 Floating point number
1.e2 Floating point number
1.e-2 Floating point number
“I’m a string” String
@”I’m a verbatim string” String
@” I’m a multiline verbatim string “ String

(6)注释

// 单行注释

/* */ 多行注释

# 单行注释

2、值和数据类型

(1)Interger

整数表示32位的带符号数:

local a = 123 //decimal

local b = 0x0012 //hexadecimal

local c = 075 //octal

local d = ‘w’ //char code

(2)Float

float表示32位的浮点数:

local a=1.0

local b=0.234

(3)String

字符串是一个不可变的字符序列,修改字符串是创建一个新字符串。

Squirrel的字符串,表现得像C或C ++,用引号(”)分隔,可以包含转义序列(\ t,\ a,\ b,\ n,\ r,\ v,\ f,\\,\”, \’,\ 0,\ x <hh>,\ u <hhhh>和\ U <hhhhhhhh>)。

照字面的字符串文字以@”开头并以匹配的引号结尾。照字面的字符串文字也可以延伸到换行符。如果它们这样做,它们包括引号之间的任何空格字符:

local a = “I’m a wonderful string\n”

// 在字符串的末尾有一个换行符

local x = @”I’m a verbatim string\n”

// \ n被复制到与常规字符串中的\\ n相同的字符串中”I’m a verbatim string\n”

对于逐字字符串文字的”无转义序列”规则的唯一例外是,您可以通过两个双引号来转义双引号:

local multiline = @”

    this is a multiline string

    it will “”embed”” all the new line

    characters

(4)Null

null值是一个原始值,表示null,empty或不存在的引用。 Null类型只有一个值,称为null:

local a = null

(5)Bool

bool数据类型只能有两个。 他们是true和false的文字。 bool值表示条件的有效性(告知条件是真还是假):

(6)Table

是关联容器,实现为键/值对(称为插槽):

local t={}

local test=

{

    a=10

    b=function(a) { return a+1; }

}

(7)Array

数组是简单的对象序列,它们的大小是动态的,它们的索引始终从0开始:

local a  = [“I’m”,”an”,”array”]

local b = [null]

b[0] = a[2];

(8)Function

函数类似于其他类C语言和大多数编程语言的函数,但是有一些关键的区别(见下文)。

(9)Class

类是作为键/值对实现的关联容器。 类是通过”类表达式”或”类语句”创建的。 类成员可以在创建时从另一个类对象继承。 创建成员后,可以添加成员,直到类的实例创建。

(10)Class Instance

通过调用类对象来创建类实例。 作为表的实例是作为键/值对实现的。 无法同步添加或删除实例成员,但可以更改成员的值。

(11)Generator

生成器是可以使用语句”yield”暂停并稍后恢复的函数(请参阅生成器)。

(12)Userdata

Userdata对象是由宿主应用程序定义但存储在Squirrel变量中的内存块(或指针)(请参阅Userdata和UserPointers)。

(13)Thread

线程是表示协作执行线程的对象,也称为协同程序。

(14) Weak References

弱引用是指向另一个(非标量)对象的对象,但不具有对它的强引用。 (参见弱引用)。

3、执行上下文

执行上下文是函数栈帧和函数环境对象(this)以及函数root(根表)的并集。栈帧是栈的一部分,其中存储了在其正文中声明的局部变量。环境对象是一个隐式参数,由函数调用者自动传递。根表是在创建期间与该函数关联的表。函数的根表值是函数创建时VM的根表。使用closure.setroot()创建后,也可以更改函数的根表。在执行期间,函数体只能透明地引用其执行上下文。这意味着单个标识符可以引用局部变量,环境对象槽或闭包根表的槽;可以通过关键字this显式访问环境对象。可以通过operator ::显式访问闭包根表。

(1) 变量

Squirrel中有两种类型的变量,局部变量和表/数组槽。 因为全局变量(存储在闭包根中的变量)存储在表中,所以它们是表槽。

单个标识符是指环境对象中的局部变量或槽:

derefexp := id;

_table[“foo”]

_array[10]

使用表我们也可以使用’.’语法:

derefexp := exp ‘.’ id

_table.foo

Squirrel首先检查标识符是否是局部变量(函数参数是局部变量),如果没有查找环境对象(this)并最终查找到闭包根。

例如:

function testy(arg)

{

    local a=10;

    print(a);

    return arg;

}

在这种情况下,’foo’将等同于’this.foo’或此[“foo”]。

全局变量存储在称为根表的表中。 通常在全局范围内,环境对象是根表,但是要从另一个范围显式访问函数的闭包根,插槽名称必须以”::”(:: foo)为前缀。

例如:

function testy(arg)

{

    local a=10;

    return arg+::foo;

}

访问闭包根表中的变量’foo’。

由于Squirrel 3.1每个函数都有一个对特定根表的弱引用,这可能与当前的VM根表不同:

function test() {

    foo = 10;

}

相当于写:

function test() {

    if(“foo” in this) {

        this.foo = 10;

    }else {

        ::foo = 10;

    }

}

4、声明

Squirrel程序是一个简单的语句序列:

stats := stat [‘;’|’\n’] stats

Squirrel语句与C系列语言(C / C ++,Java,C#等……)相当:赋值,函数调用,程序流控制结构等。加上一些自定义语句,如yield,table和array constructors(这些将在本文档后面详细介绍。 语句可以用新行或’;’(或使用关键字case或default,如果在switch / case语句中)分隔,如果语句后跟’}’,则不需要这两个符号。

(1)语句块

stat := ‘{‘ stats ‘}’

由大括号({})分隔的一系列语句称为块; 块是一个声明本身。

(2) 控制流程语句

squirrel实现了最常见的控制流语句:

if, while, do-while, switch-case, for, foreach

(2.1)true and false

Squirrel有一个布尔类型(bool),但是像C ++一样,它认为null,0(整数)和0.0(浮点)为false,任何其他值都被认为是真的。

(2.2) if/else

stat:= ‘if’ ‘(‘ exp ‘)’ stat [‘else’ stat]

根据表达式的结果有条件地执行语句:

if(a>b)

    a=b;

else

    b=a;

////

if(a==10)

{

    b=a+b;

    return a;

}

(2.3) while

stat:= ‘while’ ‘(‘ exp ‘)’ stat

条件为真时执行语句:

function testy(n)

{

    local a=0;

    while(a<n) a+=1;

    while(1)

    {

        if(a<0) break;

        a-=1;

    }

}

(2.4)do/while

stat:= ‘do’ stat ‘while’ ‘(‘ expression ‘)’

执行一次语句,然后重复执行语句,直到条件表达式求值为false:

local a=0;

do

{

    print(a+”\n”);

    a+=1;

} while(a>100)

(2.5) switch

stat := ‘switch’ ”( exp ‘)’ ‘{‘

‘case’ case_exp ‘:’

    stats

[‘default’ ‘:’

    stats]

‘}’

Switch是一个控制语句,允许通过将控制权传递给其正文中的一个case语句来多次选择代码。 如果case都不匹配会跳转到default标签(如果存在),如果是case实例,则控制将转移到case_exp与exp匹配的case标签。switch语句可以包含多个case,如果2个case具有相同的表达式结果,则将首先考虑第一个。default标签只允许一次,必须是最后一个。 break语句将跳转到switch块之外。

(3) 循环

(3.1) for

stat:= ‘for’ ‘(‘ [initexp] ‘;’ [condexp] ‘;’ [incexp] ‘)’ statement

只要条件不等于false,就执行一个语句:

for(local a=0;a<10;a+=1)

    print(a+”\n”);

//or

glob <- null

for(glob=0;glob<10;glob+=1){

    print(glob+”\n”);

}

//or

for(;;){

    print(loops forever+”\n”);

}

(3.2) foreach

‘foreach’ ‘(‘ [index_id’,’] value_id ‘in’ exp ‘)’ stat

对包含在array, table, class, string or generator中的每个元素执行语句。 如果exp是一个生成器,它将在每次迭代时恢复,只要它是活着的; 该值将是’resume’的结果,索引是从0开始的迭代序列号:

local a=[10,23,33,41,589,56]

foreach(idx,val in a)

    print(“index=”+idx+” value=”+val+”\n”);

//or

foreach(val in a)

    print(“value=”+val+”\n”);

(4) break

stat := ‘break’

break语句终止循环的执行(for,foreach,while或do / while)或跳出switch语句;

(5) continue

stat := ‘continue’

continue运算符跳转到循环的下一次迭代,跳过以下语句的执行。

(6) return

stat:= return [exp]

return语句终止当前函数/生成器的执行,并可选择返回表达式的结果。 如果省略表达式,则函数将返回null。 如果在发生器内使用return语句,则生成器将不再可恢复。

(7) yield

stat := yield [exp]

(见生成器)

(8) 局部变量声明

initz := id [= exp][‘,’ initz]

stat := ‘local’ initz

可以在程序中的任何位置声明局部变量; 它们存在于它们的声明到它们已被声明的块的末尾之间。 EXCEPTION:允许局部变量声明语句作为for循环中的第一个表达式:

for(local a=0;a<10;a+=1)

    print(a);

(9) 函数声明

funcname := id [‘::’ id]

stat:= ‘function’ id [‘::’ id]+ ‘(‘ args ‘)’ stat

创建一个新函数

(10) 类声明

memberdecl := id ‘=’ exp [‘;’] |    ‘[‘ exp ‘]’ ‘=’ exp [‘;’] | functionstat | ‘constructor’ functionexp

stat:= ‘class’ derefexp [‘extends’ derefexp] ‘{‘

        [memberdecl]

    ‘}’

创建一个新类

(11) try/cach

stat:= ‘try’ stat ‘catch’ ‘(‘ id ‘)’ stat

try语句包含一个代码块,其中可能发生异常情况,例如运行时错误或throw语句。 catch子句提供异常处理代码。 当catch子句捕获异常时,其id绑定到该异常。

(12) throw

stat:= ‘throw’ exp

抛出异常。 可以抛出任何值。

(13) const

stat:= ‘const’ id ‘=’ ‘Integer | Float | StringLiteral

声明一个常量(请参阅常量和枚举)。

(12) enum

enumerations := ( ‘id’ ‘=’ Integer | Float | StringLiteral ) [‘,’]

stat:= ‘enum’ id ‘{‘ enumerations ‘}’

(13) 表达式

stat := exp

在Squirrel中,每个表达式也被允许作为语句,如果是这样,表达式的结果将被丢弃。

5、表达式

(1) 赋值

exp := derefexp ‘=’ exp

exp:= derefexp ‘<-‘ exp

squirrel实现了2种赋值:正常赋值(=):

a = 10;

和”新槽”赋值:

a <- 10;

新槽表达式允许在表中添加一个新槽。如果表中已存在插槽,则其行为类似于正常赋值。

(2) 操作符

(2.1) ?: 操作符

exp := exp_cond ‘?’ exp1 ‘:’ exp2

根据表达式的结果有条件地评估表达式。

(2.2) 算术操作符

exp:= ‘exp’ op ‘exp’

Squirrel支持标准算术运算符+, – ,*,/和%。 除此之外还支持联合运算符(+ =, – =,* =,/ =,%=)和递增和递减运算符(++和 – );:

a += 2;

//is the same as writing

a = a + 2;

x++

//is the same as writing

x = x + 1

所有操作符都可以正常使用整数和浮点数; 如果一个操作数是一个整数而一个是浮点数,则表达式的结果将是float。 +运算符具有字符串的特殊行为; 如果其中一个操作数是一个字符串,则operator +将尝试将另一个操作数转换为字符串并将它们连接在一起。 对于实例和表,调用_tostring。

(2.3) 关系操作符

exp:= ‘exp’ op ‘exp’

Squirrel中的关系运算符是:==, <, <=, <, <=, !=

(2.4) 三比较

exp:= ‘exp’ <=> ‘exp’

三比较运算符<=>比较2个值A和B,如果A <B则返回小于0的整数,如果A == B则返回0,如果A> B则返回大于0的整数。

(2.5) 逻辑运算符

exp := exp op exp

exp := ‘!’ exp

Squirrel中的逻辑运算符是:&&,|| ,!

如果第一个参数为null,则运算符&&(逻辑与)返回null,否则返回其第二个参数。 操作符|| (逻辑或)如果不是null则返回其第一个参数,否则返回第二个参数。

如果给定的否定值不是null,则’!’运算符将返回null,如果给定的值为null,则返回不为null的值。

(2.6) in 操作符

exp:= keyexp ‘in’ tableexp

测试表中是否存在插槽。 如果keyexp是tableexp中的有效键,则返回true

local t=

{

    foo=”I’m foo”,

    [123]=”I’m not foo”

}

if(“foo” in t) dostuff(“yep”);

if(123 in t) dostuff();

(2.7) instanceof 操作符

exp:= instanceexp ‘instanceof’ classexp

测试类实例是否是某个类的实例。 如果instanceexp是classexp的实例,则返回true。

(2.8) typeof 操作符

exp:= ‘typeof’ exp

以字符串形式返回值的类型名称:

local a={},b=”squirrel”

print(typeof a); //will print “table”

print(typeof b); //will print “string”

(2.9) 逗号操作符

exp:= exp ‘,’ exp

逗号运算符从左到右计算两个表达式,运算符的结果是右边表达式的结果; 左表达式的结果被丢弃:

local j=0,k=0;

for(local i=0; i<10; i++ , j++)

{

    k = i + j;

}

local a,k;

a = (k=1,k+2); //a becomes 3

(2.10) 位操作符

exp:= ‘exp’ op ‘exp’

exp := ‘~’ exp

Squirrel支持标准的c-like bit wise运算符&,|,^,〜,<<,>>加上无符号右移运算符<<<。 除了将左操作数视为无符号整数外,无符号右移与普通右移运算符(<<)完全相同,因此不受符号的影响。 这些运算符仅处理整数值,将任何其他操作数类型传递给这些运算符将导致异常。

(2.11) 运算符优先级

-, ~, !, typeof , ++, — 最高
/, *, %
+, –  
<<, >>, >>>  
<, <=, >, >=  
==, !=, <=>  
&  
^  
&&, in  
+=, =, -=
,(comma operator) 最低

(3) Table 构造函数

tslots := ( ‘id’ ‘=’ exp | ‘[‘ exp ‘]’ ‘=’ exp ) [‘,’]

exp := ‘{‘ [tslots] ‘}’

创建一个新表:

local a = {} //create an empty table

表构造函数也可以包含槽声明; 使用语法:

local a = {

    slot1 = “I’m the slot value”

}

替代语法可以是:

‘[‘ exp1 ‘]’ = exp2 [‘,’]

创建一个新的插槽,其中exp1为键,exp2为值:

local a=

{

    [1]=”I’m the value”

}

两种语法都可以混合使用:

local table=

{

    a=10,

    b=”string”,

    [10]={},

    function bau(a,b)

    {

        return a+b;

    }

}

插槽之间的逗号是可选的。

(3.1) Table 的json语法

因为Squirrel 3.0可以使用JSON语法声明一个表

以下JSON代码段:

local x = {

  “id”: 1,

  “name”: “Foo”,

  “price”: 123,

  “tags”: [“Bar”,”Eek”]

}

相当于以下Squirrel代码:

local x = {

  id = 1,

  name = “Foo”,

  price = 123,

  tags = [“Bar”,”Eek”]

}

(4) Clone

exp:= ‘clone’ exp

克隆表,数组或类实例执行浅拷贝(复制新对象中的所有插槽而不进行递归)。 如果源表具有委托,则同一委托将被指定为新表的委托(未复制)(请参阅委托)。

在新对象准备好之后,调用”_cloned”元方法(参见Metamethods)。

克隆类实例时,不会调用构造函数(初始化必须依赖于`_cloned`)

(5) 数组构造

exp := ‘[‘ [explist] ‘]’

创建一个新数组

a <- [] //creates an empty array

在构造期间可以使用值初始化数组:

a <- [1,”string!”,[],{}] //creates an array with 4 elements

6、Tables 表

表是关联容器,实现为键/值对(称为槽); 值可以是任何可能的类型,键是除”null”之外的任何类型。 Table是squirrel的骨架,委托和许多其他功能都是通过这种类型实现的; 甚至存储”全局”变量的环境也是一个表(称为根表)。

(1) 构造函数

表是通过表构造函数创建的(请参阅表构造函数

(2) 槽创建

在现有表中添加新插槽是通过”新插槽”操作符< – ; 此运算符的行为类似于正常赋值,但如果插槽不存在则将创建:

local a = {}

以下行将导致异常,因为表’a’中不存在名为’newslot’的插槽:

a.newslot = 1234

这将成功:

a.newslot <- 1234;

a[1] <- “I’m the value of the new slot”;

(3)槽删除

exp:= delete derefexp

删除插槽是通过关键字delete完成的; 此表达式的结果将是删除的插槽的值:

a <- {

    test1=1234

    deleteme=”now”

}

delete a.test1

print(delete a.deleteme); //this will print the string “now”

7、Arrays 数组

数组是一个由0到数组大小减去1的整数索引的值序列。数组元素可以通过它们的索引获得:

local a=[“I’m a string”, 123]

print(typeof a[0]) //prints “string”

print(typeof a[1]) //prints “integer”

调整数组和数组元素的大小,插入,删除是通过一组标准函数完成的(参见内置函数)。

8、Functions 函数

函数是类的第一个值,像整数或字符串且可以存储在表槽,局部变量、数组、且可作为函数参数传递。 函数可以用Squirrel或本机语言实现,调用约定与ANSI C兼容。

(8.1) 函数声明

函数通过函数表达式声明:

local a = function(a, b, c) { return a + b – c; }

或者用语法糖:

function ciao(a,b,c)

{

    return a+b-c;

}

这相当于:

this.ciao <- function(a,b,c)

{

    return a+b-c;

}

可以使用此语法糖声明局部函数:

local function tuna(a,b,c)

{

    return a+b-c;

}

这相当于:

local tuna = function(a,b,c)

{

    return a+b-c;

}

也可以声明类似的:

T <- {}

function T::ciao(a,b,c)

{

    return a+b-c;

}

//that is equivalent to write

T.ciao <- function(a,b,c)

{

    return a+b-c;

}

//or

T <- {

    function ciao(a,b,c)

    {

        return a+b-c;

    }

}

(8.1.1) 默认参数

Squirrel的函数可以有默认参数。

具有默认参数的函数声明如下:

function test(a,b,c = 10, d = 20)

{

    ….

}

当调用函数test并且未指定参数c或d时,VM会自动将默认值分配给未指定的参数。 默认参数可以是任何有效的squirrel表达式。 表达式在运行时进行检查。

(8.1.2) 具有可变参数数量的函数

Squirrel的函数可以有不同数量的参数(varargs函数)。

通过在参数列表的末尾添加三个点(…)来声明vararg函数。

调用该函数时,所有额外参数都可以通过名为vargv的数组访问,该数组作为隐式参数传递。

vargv是一个常规的squirrel数组,可以相应地使用:

function test(a,b,…)

{

    for(local i = 0; i< vargv.len(); i++)

    {

        ::print(“varparam “+i+” = “+vargv[i]+”\n”);

    }

  foreach(i,val in vargv)

    {

        ::print(“varparam “+i+” = “+val+”\n”);

    }

}

test(“goes in a”,”goes in b”,0,1,2,3,4,5,6,7,8);

(8.2) 函数调用

exp:= derefexp ‘(‘ explist ‘)’

表达式按以下顺序计算:expre(arguments)之后的derefexp和调用结束时的derefexp。

Squirrel中的每个函数调用都将环境对象作为隐藏参数传递给被调用函数。 ‘this’参数是函数索引的对象。

如果我们使用以下语法调用函数:

table.foo(a)

传递给foo的环境对象将是’table’:

foo(x,y) // equivalent to this.foo(x,y)

环境对象将是this(与调用函数相同)。

(8.3) 将环境绑定到函数

而默认情况下,squirrel函数调用作为环境对象’this’传递,该对象是函数索引的对象。 但是,也可以使用内置方法closure.bindenv(env_obj)将环境静态绑定到闭包。 方法bindenv()返回一个绑定环境的新实例。 当环境对象绑定到函数时,每次调用该函数时,其”this”参数将始终是先前绑定的环境。 此机制对于实现类似于C#委托的回调系统很有用。

注意:闭包保持对绑定环境对象的弱引用,因为如果删除该对象,则对闭包的下一次调用将导致null环境对象。

(8.4) Lambda 表达式

exp := ‘@’ ‘(‘ paramlist ‘)’ exp

Lambda表达式是一种快速定义由单个表达式组成的函数的同义语法糖。 应用函数式编程模式时,此功能非常方便,例如map / reduce或将compare方法传递给array.sort()。

这里有一个lambda表达式:

local myexp = @(a,b) a + b

这相当于:

local myexp = function(a,b) { return a + b; }

一个更有用的用法可能是:

local arr = [2,3,5,8,3,5,1,2,6];

arr.sort(@(a,b) a <=> b);

arr.sort(@(a,b) -(a <=> b));

本可以写成:

local arr = [2,3,5,8,3,5,1,2,6];

arr.sort(function(a,b) { return a <=> b; } );

arr.sort(function(a,b) { return -(a <=> b); } );

除了限于单个表达式,lambdas支持常规函数的所有功能。 实际上是作为编译时功能实现的。

(8.5) 自由变量

自由变量是函数作用域外部的变量,因为它不是函数的局部变量或参数。 自由变量引用外部范围的局部变量。 在下面的例子中,变量’testy’,’x’和’y’绑定到函数’foo’:

local x=10,y=20

local testy=”I’m testy”

function foo(a,b)

{

    ::print(testy);

    return a+b+x+y;

}

程序可以读取或写入自由变量。

(8.6) 尾递归

尾递归是一种将程序中的递归部分转换为迭代的方法:当函数中的递归调用是该函数中最后执行的语句(就在返回之前)时。 如果发生这种情况,松鼠解释器会在递归调用之前折叠调用者堆栈帧; 因为非常深的递归是可能的,没有堆栈溢出的风险:

function loopy(n)

{

    if(n>0){

        ::print(“n=”+n+”\n”);

        return loopy(n-1);

    }

}

loopy(1000);

9、Classes 类

Squirrel实现了类似于Java / C ++ /等语言的类机制……但是由于它的动态特性,它在几个方面有所不同。 Classes 是第一类对象,像整数或字符串一样,可以存储在表槽、局部变量,数组,且可作为函数参数传递。

(9.1) 类的声明

通过关键字”class”创建一个类对象。 类对象遵循表的相同声明语法(参见表),唯一的区别是使用’;’作为可选的分隔符而不是’,’。

例如:

class Foo {

    //构造函数

    constructor(a)

    {

        testy = [“stuff”,1,2,3,a];

    }

    //成员方法

    function PrintTesty()

    {

        foreach(i,val in testy)

        {

            ::print(“idx = “+i+” = “+val+” \n”);

        }

    }

    //属性

    testy = null;

}

以上的代码示例是一个语法糖自:

Foo <- class {

    //构造函数

    constructor(a)

    {

        testy = [“stuff”,1,2,3,a];

    }

    //成员方法

    function PrintTesty()

    {

        foreach(i,val in testy)

        {

            ::print(“idx = “+i+” = “+val+” \n”);

        }

    }

    //属性

    testy = null;

}

为了模拟名称空间,也可以声明这样的:

//只有2个常规嵌套表

FakeNamespace <- {

    Utils = {}

}

class FakeNamespace.Utils.SuperClass {

    constructor()

    {

        ::print(“FakeNamespace.Utils.SuperClass”)

    }

    function DoSomething()

    {

        ::print(“DoSomething()”)

    }

}

function FakeNamespace::Utils::SuperClass::DoSomethingElse()

{

    ::print(“FakeNamespace::Utils::SuperClass::DoSomethingElse()”)

}

local testy = FakeNamespace.Utils.SuperClass();

testy.DoSomething();

testy.DoSomethingElse();

在声明之后,可以通过遵循适用于表的相同规则(operator < – )来添加或修改方法或属性:

//添加新属性

Foo.stuff <- 10;

//修改现有属性的默认值

Foo.testy <- “I’m a string”;

//添加新方法

function Foo::DoSomething(a,b)

{

    return a+b;

}

实例化类后,不再可能添加新属性,但可以添加或替换方法。

(9.1.1) 静态变量

Squirrel的类支持静态成员变量。 静态变量在类的所有实例之间共享其值。 通过在变量声明前加上关键字static来声明静态; 声明必须在类里。

注意:静态是只读的。

class Foo {

    constructor()

    {

        //..stuff

    }

    name = “normal variable”;

    //static variable

    static classname = “The class name is foo”;

};

(9.1.2) 类属性

类允许将属性与其成员相关联。 属性是一种元数据形式,可用于存储特定于应用程序的信息,如文档字符串,IDE属性,代码生成器等等。类属性通过在成员声明之前在类体中声明,并由符号</ and />。 这是一个例子:

class Foo </ test = “我是类级别属性” />{

    </ test = “freakin attribute” /> // PrintTesty 方法的属性

    function PrintTesty()

    {

        foreach(i,val in testy)

        {

            ::print(“idx = “+i+” = “+val+” \n”);

        }

    }

    </ flippy = 10 , second = [1,2,3] /> //testy 成员的属性

    testy = null;

}

事实上,属性是一个Table。 对于属性声明,Squirrel使用</ />语法而不是花括号{}来提高可读性。

这意味着适用于Table的所有规则都适用于属性。

可以通过内置函数classobj.getattributes(membername)检索属性(参见内置函数)。 并且可以通过内置函数classobj.setattributes(membername,val)进行修改/添加。

以下代码遍历所有Foo成员的属性:

foreach(member,val in Foo)

{

    ::print(member+”\n”);

    local attr;

    if((attr = Foo.getattributes(member)) != null) {

        foreach(i,v in attr)

        {

            ::print(“\t”+i+” = “+(typeof v)+”\n”);

        }

    }

    else {

        ::print(“\t<no attributes>\n”)

    }

}

(9.2) 类实例

类对象继承了Table的几个特性,区别在于可以创建同一个类的多个实例。 类实例是一个对象,它共享创建它的表的相同结构,但保持的是自己的值。 类实例化使用函数表示法。 通过调用类对象来创建类实例。 可以想象一个类就像返回类实例的函数一样:

//创建Foo 的新实例

local inst = Foo();

创建类实例时,会使用类声明中指定的相同值初始化其成员。 这些值是浅复制的,即使值是容器或类实例,也不会执行克隆。

注意:

对于C#和Java程序员:

Squirrel不会克隆成员的默认值,也不会为每个实例执行成员声明(如C#或java)。

所以考虑这个例子:

class Foo {

  myarray = [1,2,3]

  mytable = {}

}

local a = Foo();

local b = Foo();

在上面的代码片段中,两个实例都将引用相同的数组和相同的表。为了实现C#或Java程序员将要遵循的内容,应采取以下方法。

class Foo {

  myarray = null

  mytable = null

  constructor()

  {

    myarray = [1,2,3]

    mytable = {}

  }

}

local a = Foo();

local b = Foo();

当一个类定义一个名为”constructor”的方法时,类实例化操作将自动为新创建的实例调用它。 构造函数方法可以有参数,这将影响实例化操作所需的参数数量。 作为普通函数,构造函数可以具有可变数量的参数(使用参数…):

class Rect {

    constructor(w,h)

    {

        width = w;

        height = h;

    }

    x = 0;

    y = 0;

    width = null;

    height = null;

}

// Rect的构造函数有2个参数,所以必须传递2个参数

local rc = Rect(100,100);

创建实例后,可以按照适用于Table的相同规则设置或获取其属性。 函数无法设置。

实例成员无法删除。

可以通过内置函数instance.getclass()检索创建某个实例的类对象(参见内置函数)

运算符instanceof测试类实例是否是某个类的实例:

local rc = Rect(100,100);

if(rc instanceof ::Rect) {

    ::print(“It’s a rect”);

}

else {

    ::print(“It isn’t a rect”);

}

注意:

因为如果左表达式不是类,Squirrel 3.x instanceof不会抛出异常,它只会失败

(9.3) 继承

Squirrel的类通过在类声明中添加关键字extends,后跟表达式来支持单继承。 派生类的语法如下:

class SuperFoo extends Foo {

    function DoSomething() {

        ::print(“I’m doing something”);

    }

}

声明派生类时,Squirrel首先复制新类中所有基类的成员,然后继续检查声明的其余部分。

派生类继承它的基类的所有成员和属性,如果派生类重写基类函数,则基类实现被隐藏。 通过’base’关键字获取方法,可以访问基类的重写方法。

这是一个例子:

class Foo {

    function DoSomething() {

        ::print(“I’m the base”);

    }

};

class SuperFoo extends Foo {

    //overridden method

    function DoSomething() {

        //calls the base method

        base.DoSomething();

        ::print(“I’m doing something”);

    }

}

同样的规则适用于构造函数。 构造函数是一个常规函数(除了在构造时自动调用):

class BaseClass {

    constructor()

    {

        ::print(“Base constructor\n”);

    }

}

class ChildClass extends BaseClass {

    constructor()

    {

        base.constructor();

        ::print(“Child constructor\n”);

    }

}

local test = ChildClass();

可以通过内置方法getbase()检查派生类的基类:

local thebaseclass = SuperFoo.getbase();

注意,因为方法在调用相同对象的方法时没有特殊的保护策略,所以调用同一个类的方法的基类方法最终可能会调用派生类的重写方法。

通过关键字base(如base.MyMethod())中的派生类的方法可以显式调用基类的方法:

class Foo {

    function DoSomething() {

        ::print(“I’m the base”);

    }

    function DoIt()

    {

        DoSomething();

    }

};

class SuperFoo extends Foo {

    //overridden method

    function DoSomething() {

        ::print(“I’m the derived”);

    }

    function DoIt() {

        base.DoIt();

    }

}

//creates a new instance of SuperFoo

local inst = SuperFoo();

//prints “I’m the derived”

inst.DoIt();

(9.4) 元方法

类实例允许通过元方法定制其语义的某些方面(参见Metamethods)。 对于C ++程序员:”metamethods的行为大致类似于重载运算符”。 类支持的元方法是

_add, _sub, _mul, _div, _unm, _modulo, _set, _get, _typeof, _nexti, _cmp, _call, _delslot, _tostring

类对象只支持2个元方法: _newmember 和_inherited

以下示例显示如何创建实现元方法的类_add.:

class Vector3 {

    constructor(…)

    {

        if(vargv.len() >= 3) {

            x = vargv[0];

            y = vargv[1];

            z = vargv[2];

        }

    }

    function _add(other)

    {

        return ::Vector3(x+other.x,y+other.y,z+other.z);

    }

    x = 0;

    y = 0;

    z = 0;

}

local v0 = Vector3(1,2,3)

local v1 = Vector3(11,12,13)

local v2 = v0 + v1;

::print(v2.x+”,”+v2.y+”,”+v2.z+”\n”);

从2.1版开始,类支持2个metamethods _inherited和_newmember。 当一个类继承自实现_inherited的类时,会调用_inherited。 为添加到类中的每个成员调用_newmember(在声明时)。

10、Generators生成器

包含yield语句的函数称为”生成器函数”。 当调用生成器函数时,它不执行函数体,而是返回一个新的暂停生成器。 返回的生成器可以在生存时通过resume语句恢复。 yield关键字,暂停生成器的执行,并可选择将表达式的结果返回给恢复生成器的函数。 生成器返回时会死,这可以通过显式返回语句或退出函数体来实现; 如果在生成器运行时发生未处理的异常(或运行时错误),则生成器将自动死亡。 死发生器不能再恢复了:

function geny(n)

{

    for(local i=1;i<=n;i+=1)

        yield i;

    return null;

}

local gtor=geny(10);

local x;

while(x=resume gtor) print(x+”\n”);

该代码的输出将是:

1

2

3

4

5

6

7

8

9

10

也可以使用foreach语句迭代生成器。 当foreach评估生成器时,将在每次迭代时恢复生成器,直到它返回。 return语句返回的值将被忽略。

注意:

暂停的生成器将保存对存储在其局部变量中的所有值的强引用,除了此对象只是弱引用。 正在运行的生成器也对此对象具有强引用。

11、常量和枚举

Squirrel允许将常量值绑定到将在编译时计算的标识符。 这是通过常量和枚举实现的。

(11.1) 常量

常量将特定值绑定到标识符。 常量类似于全局值,除了它们是在编译时计算的,并且它们的值不能更改。

常量值只能是整数,浮点数或字符串文字。 不允许表达。 使用以下语法声明:

const foobar = 100;

const floatbar = 1.2;

const stringbar = “I’m a contant string”;

常量始终是全局范围的,从声明它们的那一刻起,任何后续代码都可以引用它们。 常量将影响具有相同名称的任何全局槽(通过使用::语法,全局槽将保持可见):

local x = foobar * 2;

(11.2) 枚举

作为常量,枚举将特定值绑定到名称。 枚举也在编译时进行评估,其值不能更改。

枚举声明在程序中引入了新的枚举。 枚举值只能是整数,浮点数或字符串文字。 不允许表达:

enum Stuff {

  first, //this will be 0

  second, //this will be 1

  third //this will be 2

}

enum Stuff {

  first = 10

  second = “string”

  third = 1.2

}

以与访问静态类成员类似的方式访问枚举值。 必须使用枚举的名称限定成员的名称,例如Stuff.second Enumerations将影响具有相同名称的任何全局槽(使用::语法将保持全局槽可见):

local x = Stuff.first * 2;

(11.3) 实现说明

枚举和常量是编译时功能。 只有整数,字符串和浮点数可以声明为const / enum; 不允许使用表达式(因为它们必须在编译时进行检查)。 声明const或enum时,会将编译时间添加到consttable中。 此表存储在VM共享状态中,并由VM及其所有线程共享。 consttable是一个普通的squirrel 表; 以roottable相同的方式可以修改运行时。 您可以通过内置函数getconsttable()访问consttable,也可以通过内置函数setconsttable()更改它。

这里有一些例子:

//creates a constant

getconsttable()[“something”] <- 10″

//creates an enumeration

getconsttable()[“somethingelse”] <- { a = “10”, c = “20”, d = “200”};

//deletes the constant

delete getconsttable()[“something”]

//deletes the enumeration

delete getconsttable()[“somethingelse”]

该系统允许在程序上声明常量和枚举,也可以将任何squirrel类型分配给常量/枚举(函数,类等…)。 然而,这将使代码块的序列化变得不可能。

12、线程

Squirrel支持协作线程(也称为协同程序)。 协作线程是一个子程序,它可以在执行中期暂停并为调用者提供一个值而不返回程序流,然后它的执行可以在稍后从它被挂起的同一点恢复。 起初看起来Squirrel线程可能与生成器混淆,实际上它们的行为非常相似。 但是,当生成器在调用程序栈中运行并且只能挂起本地栈,线程有自己的执行栈,全局表和错误处理程序; 这允许线程挂起嵌套调用并拥有自己的错误策略。

(12.1) 使用线程

线程是通过内置函数’newthread(func)’创建的;这个函数获取一个squirrel函数作为参数并将其绑定到新的线程objecs(将是线程体)。返回的线程对象最初处于”空闲”状态。线程可以使用’threadobj.call()’函数启动;传递给’call’的参数被传递给线程函数。

一个线程可以被挂起调用函数suspend(),当发生这种情况时,唤醒(或启动)线程返回的函数(如果一个参数传递给suspend()它将是唤醒函数的返回值,如果没有参数传递的返回值将为null)。一个挂起的线程可以恢复调用函数’threadobj.wakeup’,当发生这种情况时,挂起线程的函数将返回(如果参数被传递给wakeup,它将是suspend函数的返回值,如果没有传递参数返回值为null)。

线程在其主函数返回时或在执行期间发生未处理的异常时终止:

function coroutine_test(a,b)

{

    ::print(a+” “+b+”\n”);

    local ret = ::suspend(“suspend 1”);

    ::print(“the coroutine says “+ret+”\n”);

    ret = ::suspend(“suspend 2”);

    ::print(“the coroutine says “+ret+”\n”);

    ret = ::suspend(“suspend 3”);

    ::print(“the coroutine says “+ret+”\n”);

    return “I’m done”

}

local coro = ::newthread(coroutine_test);

local susparam = coro.call(“test”,”coroutine”); //starts the coroutine

local i = 1;

do

{

    ::print(“suspend passed (“+susparam+”)\n”)

    susparam = coro.wakeup(“ciao “+i);

    ++i;

}while(coro.getstatus()==”suspended”)

::print(“return passed (“+susparam+”)\n”)

该程序的结果将是:

test coroutine

suspend passed (suspend 1)

the coroutine says ciao 1

suspend passed (suspend 2)

the coroutine says ciao 2

suspend passed (suspend 3)

the coroutine says ciao 3

return passed (I’m done).

以下是如何组合线程和尾递归的有趣示例:

function state1()

{

    ::suspend(“state1”);

    return state2(); //tail call

}

function state2()

{

    ::suspend(“state2”);

    return state3(); //tail call

}

function state3()

{

    ::suspend(“state3”);

    return state1(); //tail call

}

local statethread = ::newthread(state1)

::print(statethread.call()+”\n”);

for(local i = 0; i < 10000; i++)

    ::print(statethread.wakeup()+”\n”);

13、弱引用

弱引用允许程序员创建对象的引用,而不会影响对象本身的生命周期。 在squirrel中,弱引用是通过内置方法obj.weakref()创建的第一类对象。 除null之外的所有类型都实现了weakref()方法; 但是在bools,integer和float中,该方法只返回对象本身(这是因为这些类型总是按值传递)。 将弱引用分配给容器时(表槽,数组,类或实例)的处理方式与其他对象不同; 当获取持有弱引用的容器槽时,它总是返回弱引用而不是弱引用对象指向的值。这允许程序员忽略处理的值很弱的事实。 当弱引用指向的对象被销毁时,弱引用自动设置为null:

local t = {}

local a = [“first”,”second”,”third”]

//creates a weakref to the array and assigns it to a table slot

t.thearray <- a.weakref();

表槽’thearray’包含对数组的弱引用。 以下行打印”first”,因为表(和所有其他容器)总是返回弱ref指向的对象:

print(t.thearray[0]);

对数组的唯一强引用是由局部变量’a’拥有的,因为下面的行为’a’分配一个整数,数组被销毁:

= 123;

当弱ref引用的对象被破坏时,弱ref会自动设置为null,因此以下行将打印”null”:

::print(typeof(t.thearray))

(13.1) 明确处理弱引用

如果将弱引用分配给局部变量,则将其视为任何其他值:

local t = {}

local weakobj = t.weakref();

以下行打印”weakref”:

::print(typeof(weakobj))

weakref指向的对象可以通过内置方法weakref.ref()获得。

以下行打印”table”:

::print(typeof(weakobj.ref()))

14、委托

Squirrel支持隐式委托。 每个table或userdata都可以有一个父表(委托)。 父表是一个普通表,允许为他的子定义特殊行为。 当table(或userdata)使用与其中一个槽不对应的键索引时,解释器会自动将get(或set)操作委托给其父槽:

Entity <- {

}

function Entity::DoStuff()

{

    ::print(_name);

}

local newentity = {

    _name=”I’m the new entity”

}

newentity.setdelegate(Entity)

newentity.DoStuff(); //prints “I’m the new entity”

可以通过内置方法table.getdelegate()获取表的委托:

local thedelegate = newentity.getdelegate();

15、Metamethods 元方法

 Metamethods是一种允许定制语言语义的某些方面的机制。 这些方法是放在父表(委托)或类声明中的普通函数; 可以通过定义元方法来更改表/类实例行为的许多方面。 类对象(非实例)仅支持2个元方法_newmember,_inherited。

例如,当我们在2个表上使用”==”以外的关系运算符时,VM将检查表中是否在其父级中有一个名为”_cmp”的方法,如果是这样,它将调用它来确定表之间的关系:

local comparable={

    _cmp = function (other)

    {

        if(name<other.name)return -1;

        if(name>other.name)return 1;

        return 0;

    }

}

local a={ name=”Alberto” }.setdelegate(comparable);

local b={ name=”Wouter” }.setdelegate(comparable);

if(a>b)

    print(“a>b”)

else

    print(“b<=a”);

对于类,前面的代码变为:

class Comparable {

    constructor(n)

    {

        name = n;

    }

    function _cmp(other)

    {

        if(name<other.name) return -1;

        if(name>other.name) return 1;

        return 0;

    }

    name = null;

}

local a = Comparable(“Alberto”);

local b = Comparable(“Wouter”);

if(a>b)

    print(“a>b”)

else

    print(“b<=a”);

(15.1) _set

_set(idx,val)

当索引idx不存在于对象或其委托链中时调用。 _set必须’throw null’来通知没有找到key但是没有运行时错误(清除失败)。 这允许程序在运行时错误和”未找到索引”之间进行区分。

(15.2) _get

_get(idx,val)

当索引idx不存在于对象或其委托链中时调用。 _get必须’throw null’来通知没有找到key但是没有运行时错误(清除失败)。 这允许程序在运行时错误和”未找到索引”之间进行区分。

(15.3) _newslot

_newslot(key,value)

当脚本尝试在表中添加新插槽时调用。

如果插槽已经存在于目标表中,则不会调用该方法,且使用”new slot”操作符

(15.4) _delslot

_delslot(key)

当脚本从表中删除插槽时调用。 如果调用该方法squirrel不会尝试删除自己的插槽

(15.5) _add

_add(other)

the + 操作符

返回 this + other

(15.6) _sub

_sub(other)

– 操作符 (类似 _add)

(15.7) _mul

_mul(other)

* 操作符 (类似 _add)

(15.8) _div

_div(other)

/ 操作符 (类似 _add)

(15.9) _modulo

_modulo(other)

% 操作符 (类似 _add)

(15.10) _unm

_unm()

一元减号运算符

(15.11) _tyoeof

_tyoeof()

在表由typeof运算符,userdata和类实例上调用

将此类型作为字符串返回

(15.12) _cmp

_cmp(other)

调用以模拟<> <=> =和<=>运算符

返回一个整数,如下所示:

返回 关系
> 0 if this > other
0 if this == other
< 0 if this < other

(15.13) _call

_call(other)

调用table,userdata或类实例时调用

(15.14) _cloned

_cloned(original)

克隆表或类实例时调用(在克隆表中)

(15.15) _nexti

_nexti(previdx)

当foreach循环迭代userdata或类实例时调用

如果previdx == null,则表示它是第一次迭代。 该函数必须返回’next’值的索引。

(15.16) _tostring

_tostring(previdx)

在字符串连接期间或打印函数打印表,实例或用户数据时调用。也由sq_tostring()api调用

必须返回对象的字符串表示形式。

(15.17) _inherited

_inherited(attributes)

当一个类对象继承自实现_inherited的类时,调用this包含新类。

返回值被忽略。

(15.18) _newmember

_newmember(index,value,attributes,isstatic)

为类体中声明的每个成员调用(在声明时)。

如果实现该功能,则不会将成员添加到该类中。

16、内置函数

(16.1) 全局符号

array(size[, fill])

创建并返回指定大小的数组。如果指定了可选参数fill,则其值将用于填充新数组的插槽。 如果省略填充参数,则使用null。

seterrorhandler(func)

设置运行时错误处理程序

callee()

返回当前运行的闭包

setdebughook(hook_func)

设置调试钩子

enabledebuginfo(enable)

在编译时启用/禁用调试行信息生成。 enable != null启用。 enable == null 禁用。

getroottable()

返回VM的根表。

setroottable(table)

设置VM的根表。 并返回上一个根表。

getconsttable()

返回VM的常量表。

setconsttable(table)

设置VM的常量表。 并返回前一个常量表。

assert(exp)

如果exp为null,则抛出异常

print(x)

在标准输出中打印x

error(x)

在标准错误输出中打印x

compilestring(string[, buffername])

将包含squirrel脚本的字符串编译到函数中并返回它:

local compiledscript=compilestring(“::print(\”ciao\”)”);

//run the script

compiledscript();

collectgarbage()

运行垃圾收集器并返回找到(和删除)的引用循环数此函数仅适用于垃圾收集器构建。

resurrectunreachable()

运行垃圾收集器并返回包含找到的所有无法访问的对象的数组。 如果找不到无法访问的对象,则返回null。 此功能旨在帮助调试参考周期。 此函数仅适用于垃圾收集器构建。

type(obj)

返回对象的’raw’类型而不调用metatmethod’_typeof’。

getstackinfos(level)

返回给定调用堆栈级别的堆栈信息。 返回一个格式如下的表:

{

    func=”DoStuff”, //function name

    src=”test.nut”, //source file

    line=10,        //line number

    locals = {      //a table containing the local variables

        a=10,

        testy=”I’m a string”

    }

}

level = 0是当前函数,level = 1是调用者,依此类推。 如果堆栈级别不存在,则该函数返回null。

newthread(threadfunc)

创建一个新的协作线程对象(协同程序)并返回它

_versionnumber_

描述VM和编译器版本的整数值。 例如。 对于Squirrel 3.0.1,此值为301

_version_

描述VM和编译器版本的字符串值。

_charsize_

字符的内部VM表示的字符大小(对于UNICODE构建为2,ASCII构建为1)。

_intsize_

内部VM表示整数的大小以字节为单位(4位为32位构建,8位为64位构建)。

_floatsize_

内部VM表示浮点数的大小(以字节为单位)(对于双精度构建为8,单精度构建为4)。

(16.1.1) 默认委托

除了null和userdata之外,每个squirrel对象都有一个默认委托,其中包含一组函数来操作和检索来自对象本身的信息。

(16.2) Integer整数

integer.tofloat()

将数字转换为float并返回它

integer.tostring()

将数字转换为字符串并返回它

integer.tointeger()

返回整数的值(虚函数)

integer.tochar()

返回包含由整数表示的单个字符的字符串。

integer.weakref()

虚函数,返回整数本身。

(16.3) Float整数

float.tofloat()

返回float的值(虚函数)

float.tointeger()

将数字转换为整数并返回它

float.tostring()

将数字转换为字符串并返回它

float.tochar()

返回一个字符串,其中包含由float的整数部分表示的单个字符。

float.weakref()

虚函数,返回浮点数本身。

(16.4) Bool 逻辑

bool.tofloat()

返回1.0表示true为0.0表示false

bool.tointeger()

返回1表示true为0表示false

bool.tostring()

返回”true”表示true为”false”表示false

bool.weakref()

虚函数,返回bool本身。

(16.5) String 文本

string.len()

返回字符串长度

string.tointeger([base])

将字符串转换为整数并返回它。可以指定可选参数base,如果未指定base,则默认为base 10

string.tofloat()

将字符串转换为float并返回它

string.tostring()

返回字符串(虚函数)

string.slice(start[, end])

返回字符串的一部分作为新字符串。复制从start到end(不包含)。 如果start为负,则索引计算为length + start,如果end为负,则索引计算为length + end。 如果省略end,则end等于字符串长度。

string.find(substr[, startidx])

从索引startidx开始搜索子字符串(substr)并返回其第一次出现的索引。 如果省略startidx,则搜索操作从字符串的开头开始。 如果未找到substr,则该函数返回null。

string.tolower()

返回字符串的小写副本。

string.toupper()

返回字符串的大写副本。

string.weakref()

返回对象的弱引用。

(16.6) Table 表

table.len()

返回表中包含的槽数

table.rawget(key)

尝试从插槽’key’获取值而不使用委托

table.rawset(key, val)

使用值’val’设置插槽’key’而不使用委托。 如果插槽不存在,则会创建该插槽。

table.rawdelete()

删除槽key而不使用委托并返回值。 如果slo不存在则返回null。

table.rawin(key)

如果插槽’key’存在,则返回true。 该函数与运算符’in’具有相同的eddect,但不使用委托。

table.weakref()

返回对象的弱引用。

table.tostring()

尝试调用_tostring元方法,如果失败。 返回”(table:pointer)”。

table.clear()

从表中删除所有插槽

table.setdelegate(table)

设置表的委托,删除委托必须传递’null’给该函数。 该函数返回表本身(例如,在这种情况下,a.setdelegate(b)’a’是返回值)。

table.getdelegate()

返回表的委托,如果没有设置委托,则返回null。

(16.7) Array 数组

array.len()

返回数组的长度

array.append(val)

在数组的末尾追加值’val’

array.push(val)

在数组的末尾追加值’val’

array.extend(array)

通过附加给定数组中的所有项来扩展数组。

array.pop()

从数组后面删除一个值并返回它。

array.top()

返回索引最高的数组的值

array.insert(idx, val)

在数组中的’idx’位置插入值’val’

array.remove(idx)

删除数组中’idx’位置的值

array.resize(size[, fill])

调整数组的大小,如果指定了可选参数fill,则其值将用于填充新数组的插槽(如果指定的大小大于先前的大小)。 如果省略填充参数,则使用null。

array.sort([compare_func])

对数组进行排序。 可以选择性地传递自定义比较函数。函数原型如下:

function custom_compare(a,b)

{

    if(a>b) return 1

    else if(a<b) return -1

    return 0;

}

可以使用lambda表达式和运算符<=>编写更紧凑的自定义比较版本

arr.sort(@(a,b) a <=> b);

array.reverse()

将数组的元素反转

array.slice(start[, end])

返回数组的一部分作为新数组。 从开始到结束复制(不包括在内)。 如果start为负,则索引计算为length + start,如果end为负,则索引计算为length + end。 如果省略end,则end等于数组长度。

array.weakref()

返回对象的弱引用。

array.tostring()

返回字符串”(array:pointer)”。

array.clear()

从数组中删除所有项目

array.map(func(a))

创建一个相同大小的新数组。 对于原始数组中的每个元素,调用函数’func’并将函数的返回值赋给新创建的数组的相应元素。

array.apply(func(a))

对于数组中的每个元素,调用函数’func’并将该元素的原始值替换为函数的返回值。

array.reduce(func(prevval, curval))

将数组减少为单个值。 对于数组中的每个元素,调用函数’func’传递初始值(或前一个回调调用的值)和当前元素的值。 然后,函数的返回值用作下一个元素的”prevval”。 给定长度为0的数组,返回null。 给定长度为1的数组,返回第一个元素。 给定一个包含2个或更多元素的数组,调用前两个元素作为参数的函数,得到该结果,然后用该结果和第三个元素调用函数,得到该结果,用该结果调用函数和第四个参数 依此类推,直到所有元素都被处理完毕。 最后返回func的最后一次调用的返回值。

array.filter(func(index, val))

创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。 详细地说,它创建一个新数组,原始数组中的每个元素都调用指定的函数传递元素的索引及其值; 如果函数返回’true’,则在新创建的数组上添加相应元素的值。

array.find(value)

对数组中的值执行线性搜索。 如果找到null,则返回值的索引。

(16.8) Function 函数

function.call(_this, args…)

使用指定的环境对象(’this’)和参数调用该函数

function.pcall(_this, args…)

使用指定的环境对象(’this’)和参数调用该函数,如果发生错误,该函数将不会调用错误回调(pcall保留为’protected call’)

function.acall(array_args)

使用指定的环境对象(’this’)和参数调用该函数。 该函数接受一个包含将传递给被调用函数的参数的数组。其中array_args必须在[0]位置包含所需的’this’对象。

function.pacall(array_args)

使用指定的环境对象(’this’)和参数调用该函数。 该函数接受一个包含将传递给被调用函数的参数的数组。其中array_args必须在[0]位置包含所需的’this’对象。 如果发生错误,此函数将不会调用错误回调(pacall保留为”受保护的数组调用”)

function.weakref()

返回对象的弱引用。

function.tostring()

返回字符串”(closure:pointer)”。

function.setroot(table)

设置闭包的根表

function.getroot()

返回闭包的根表

function.bindenv(env)

克隆函数(也称为闭包)并将环境对象绑定到它(表,类或实例)。 新创建函数的this参数将始终设置为env。 请注意,创建的函数包含对其环境对象的弱引用,因此不能用于控制其生命周期。

function.getinfos()

返回一个包含函数信息的表,如参数,名称和源名称;

//the data is returned as a table is in form

//pure squirrel function

{

  native = false

  name = “zefuncname”

  src = “/somthing/something.nut”

  parameters = [“a”,”b”,”c”]

  defparams = [1,”def”]

  varargs = 2

}

//native C function

{

  native = true

  name = “zefuncname”

  paramscheck = 2

  typecheck = [83886082,83886384] //this is the typemask (see C defines OT_INTEGER,OT_FLOAT etc…)

}

(16.9) Class 类

class.instance()

返回该类的新实例。 此函数不会调用实例构造函数。 必须显式调用构造函数(例如,class_inst.constructor(class_inst))。

class.getattributes(membername)

返回指定成员的属性。 如果参数成员为null,则该函数返回类级别属性。

class.setattributes(membername, attr)

设置指定成员的属性并返回先前的属性值。 如果参数成员为null,则该函数设置类级别属性。

class.rawin(key)

如果插槽’key’存在,则返回true。 该函数与运算符’in’具有相同的eddect,但不使用委托。

class.weakref()

返回对象的弱引用。

class.tostring()

返回字符串 “(class : pointer)”.

class.rawget(key)

尝试从插槽’key’获取值而不使用委托

class.rawset(key, val)

使用值’val’设置插槽’key’而不使用委托。 如果插槽不存在,则会创建该插槽。

class.newmember(key, val[, attrs][, bstatic])

使用值’val’和属性’attrs’设置/添加插槽’key’,如果存在,则调用_newmember metamethod。 如果bstatic为true,则插槽将添加为静态。 如果插槽不存在,则会创建该插槽。

class.rawnewmember(key, val[, attrs][, bstatic])

设置/添加插槽’key’的值为’val’,属性’attrs’。如果bstatic为true,则插槽将被添加为静态。 如果插槽不存在,则会创建该插槽。 它不会调用任何元方法。

(16.10) Class Instance 类实例

instance.getclass()

返回创建实例的类。

instance.rawin(key)

如果插槽’key’存在,则返回true。 该函数与运算符’in’具有相同的eddect,但不使用委托。

instance.weakref()

返回对象的弱引用。

instance.tostring()

尝试调用_tostring元方法,如果失败。 返回”(insatnce:pointer)”。

instance.rawget(key)

尝试从插槽’key’获取值而不使用委托

instance.rawset(key, val)

使用值’val’设置插槽’key’而不使用委托。 如果插槽不存在,则会创建该插槽。

(16.11) Generator 生成器

generator.getstatus()

以字符串形式返回生成器的状态:”running”,”dead”或”suspended”。

generator.weakref()

返回对象的弱引用。

generator.tostring()

返回字符串”(generator:pointer)”。

(16.12) Thread 线程

thread.call()

使用指定的参数启动线程

thread.wakeup([wakeupval])

唤醒挂起的线程,接受一个可选参数,该参数将用作挂起线程的函数的返回值(通常为suspend())

thread.wakeupthrow(objtothrow[, propagateerror = true])

唤醒一个被挂起的线程,在唤醒线程中抛出异常,抛出对象’objtothrow’。

thread.getstatus()

返回线程的状态(”idle”,”running”,”suspended”)

thread.weakref()

返回对象的弱引用。

thread.tostring()

返回字符串”(thread:pointer)”。

thread.getstackinfos(stacklevel)

返回给定栈级别的栈帧信息(0是当前函数1是调用者,依此类推)。

(16.13) Weak Reference 弱引用

weakreference.ref()

返回弱引用指向的对象,如果指向的对象被销毁,则返回null。

weakreference.weakref()

返回对象的弱引用。

weakreference.tostring()

返回字符串”(weakref:pointer)”。

API 引用

1、虚拟机

sq_close

void sq_close(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标VM

释放一个squirrel VM和所有相关的友元VM

sq_geterrorfunc

SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v)

Parameters:  v (HSQUIRRELVM) – the target VM

Returns:  指向SQPRINTFUNCTION的指针,如果未设置任何函数,则为NULL。

sq_getforeignptr

SQUserPointer sq_getforeignptr(HSQUIRRELVM v)

Parameters:  v (HSQUIRRELVM) – 目标 VM

Returns: 当前VMs外部指针。

返回VM实例的外部指针。

sq_getprintfunc

SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标 VM

Returns: 指向SQPRINTFUNCTION的指针,如果未设置任何函数,则为NULL。

sq_getsharedforeignptr

SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标VM

Returns: 当前VM共享外部指针

sq_getprintfunc

SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Returns: 指向SQPRINTFUNCTION的指针,如果未设置任何函数,则为NULL。

返回给定虚拟机的当前打印功能。 (参见sq_setprintfunc())

sq_getsharedforeignptr

SQUserPointer sq_getsharedforeignptr(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
Returns: 当前VM共享外部指针

返回一组朋友VM的共享外部指针。

sq_getsharedreleasehook

SQUserPointer sq_getsharedreleasehook(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标VM

Returns: 当前的VM释放钩子。

返回一组朋友VM的共享释放钩子。

sq_getversion

SQInteger sq_getversion()

Returns: vm的版本号(如SQUIRREL_VERSION_NUMBER中所示)。

返回vm的版本号。

sq_getvmreleasehook

SQUserPointer sq_getvmreleasehook(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Returns: 当前 VMs 释放钩子.

返回VM实例的释放钩子。

sq_getvmstate

SQInteger sq_getvmstate(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
Returns: vm的状态编码为整数值。 定义了以下常量:SQ_VMSTATE_IDLE,SQ_VMSTATE_RUNNING,SQ_VMSTATE_SUSPENDED。

返回虚拟机的执行状态

sq_move

void sq_move(HSQUIRRELVM dest, HSQUIRRELVM src, SQInteger idx)

Parameters:

dest (HSQUIRRELVM) – 目标 VM

src (HSQUIRRELVM) – 源 VM

idx (SQInteger) – 源栈中的索引移动的值

将源栈的位置”idx”的值压入到目标栈中

sq_newthread

HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)

Parameters:
  • friendvm (HSQUIRRELVM) – 友元 VM
  • initialstacksize (SQInteger) –插槽中栈的大小(对象数)
Returns: 指向新VM的指针。
Remarks: 默认情况下,roottable与作为第一个参数传递的VM共享。 新的VM生命周期绑定到栈中压入的”线程”对象,其行为类似于普通的squirrel对象。

创建一个新的vm friendvm作为第一个参数传递的那个,并将其作为”线程”对象压入到栈中。

sq_open

HSQUIRRELVM sq_open(SQInteger initialstacksize)

Parameters:
  • initialstacksize (SQInteger) –插槽中栈的大小(对象数)
Returns: 一个 squirrel 虚拟机句柄
Remarks: 返回的VM必须与sq_releasevm一起释放

创建一个包含在新执行栈中的squirrel VM的新实例。

sq_pushconsttable

void sq_pushconsttable(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标 VM

将当前常量表压入到栈中

sq_pushregistrytable

void sq_pushregistrytable(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标 VM

将注册表压入到栈中

sq_pushroottable

void sq_pushroottable(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标 VM

将当前根表压入到栈中

sq_setconsttable

void sq_setconsttable(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标 VM

从栈弹出一个表并将其设置为const表

sq_seterrorhandler

void sq_seterrorhandler(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Remarks: 错误处理程序由友元VM共享

从栈弹出一个闭包或本机闭包,并将其设置为运行时错误处理程序。

sq_setforeignptr

void sq_setforeignptr(HSQUIRRELVM v, SQUserPointer p)

Parameters: v (HSQUIRRELVM) – 目标VM

p (SQUserPointer) – 必须设置的指针

设置某个VM实例的外部指针。 外部指针是与VM关联的任意用户定义指针(默认情况下为值id 0)。 VM忽略该指针。

sq_setprintfunc

void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc, SQPRINTFUNCTION errorfunc)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • printfunc (SQPRINTFUNCTION) –指向print func的指针或NULL以禁用输出。
  • errorfunc (SQPRINTFUNCTION) –指向错误func的指针或NULL以禁用输出。
Remarks: print func具有以下原型:

void printfunc(HSQUIRRELVM v,const SQChar *s,…)

设置虚拟机的打印功能。 内置函数’:: print()’使用此函数输出文本。

sq_setroottable

void sq_setroottable(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标 VM

从栈中弹出一个表并将其设置为根表

sq_setsharedforeignptr

void sq_setsharedforeignptr(HSQUIRRELVM v, SQUserPointer p)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • p (SQUserPointer) – 设置的指针

设置共享外部指针。 外部指针是与一组友元VM相关联的任意用户定义指针(默认情况下是值id 0)。 使用sq_open()创建”主”VM后,使用sq_newthread创建的所有友元VM共享相同的共享指针。

sq_setsharedreleasehook

void sq_setsharedreleasehook(HSQUIRRELVM v, SQRELESEHOOK hook)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • hook (SQRELESEHOOK) –  设置的钩子

设置某个VM组的释放钩子。 当组vm的最后一个vm被销毁时(通常在调用sq_close()时),将调用release钩子。 传递给函数的userpointer是共享的外部指针(请参阅sq_getsharedforeignptr())。 使用sq_open()创建”主”VM后,使用sq_newthread()创建的所有友元VM共享相同的共享释放钩子。

sq_setvmreleasehook

void sq_setvmreleasehook(HSQUIRRELVM v, SQRELESEHOOK hook)

Parameters: v (HSQUIRRELVM) – 目标 VM

hook (SQRELESEHOOK) – 设置的钩子

设置某个VM实例的释放钩子。 当vm被销毁时,将调用释放钩子。 传递给函数的userpointer是vm foreignpointer(参见sq_setforeignpointer())

sq_suspendvm

HRESULT sq_suspendvm(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
Returns: 一个SQRESULT(由C函数返回)
Remarks: sq_result只能作为C函数的返回表达式调用。 该功能将失败是通过更多C调用或元方法完成暂停。

暂停执行指定的vm。

SQInteger suspend_vm_example(HSQUIRRELVM v)

{

    return sq_suspendvm(v);

}

sq_wakeupvm

HRESULT sq_wakeupvm(HSQUIRRELVM v, SQBool resumedret, SQBool retval, SQBool raiseerror, SQBool throwerror)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • resumedret (SQBool) –如果为true,则该函数将从栈中弹出一个值,并将其用作先前暂停虚拟机的函数的返回值。
  • retval (SQBool) –如果为true,则该函数将压入暂停执行或主函数的函数的返回值。
  • raiseerror (SQBool) –如果为true,如果在执行调用期间发生运行时错误,则vm将调用错误处理程序。
  • throwerror (SQBool) –如果为true,则vm将在恢复后立即发出异常。 必须事先调用异常有效负载来调用sq_thowerror()。
Returns: HRESULT.

唤醒执行先前挂起的虚拟机。

2、编译

sq_compile

SQRESULT sq_compile(HSQUIRRELVM v, HSQLEXREADFUNC read, SQUserPointer p, const SQChar * sourcename, SQBool raiseerror)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • read (HSQLEXREADFUNC) –指向读取函数的指针,该读取函数将向编译器提供程序。
  • p (SQUserPointer) –用户定义的指针,在每次调用时由编译器传递给读取函数.
  • SQChar * sourcename (const) –程序的符号名称(仅用于更有意义的运行时错误)
  • raiseerror (SQBool) –如果此值为true,则在发生错误时将调用编译器错误处理程序
Returns: 返回SQRESULT。 如果sq_compile失败,则不会在栈中压入任何内容。
Remarks: 如果出现错误,该函数将调用sq_setcompilererrorhandler()设置的函数。

编制一个松鼠程序; 如果成功,则将编译后的脚本作为函数压入到栈中。

sq_compilebuffer

SQRESULT sq_compilebuffer(HSQUIRRELVM v, const SQChar* s, SQInteger size, const SQChar * sourcename, SQBool raiseerror)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • SQChar* s (const) – 指向要编译的缓冲区的指针。
  • size (SQInteger) – 在参数’s’中传递的缓冲区的字符大小。SQChar * sourcename (const) – 程序的符号名称(仅用于更有意义的运行时错误)raiseerror (SQBool) – 如果该值为true,则在发生错误时将调用编译器错误处理程序
Returns: 返回SQRESULT。 如果sq_compile失败,则不会在栈中压入任何内容。
Remarks: 如果出现错误,该函数将调用sq_setcompilererrorhandler()设置的函数。

从内存缓冲区编译一个松鼠程序; 如果成功,则将编译后的脚本作为函数压入到栈中。

sq_enabledebuginfo

void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • enable (SQBool) –如果为true则启用调试信息生成,如果== 0则禁用它。
Remarks: 该函数也会影响所有线程。

在编译时启用/禁用调试行信息生成。

sq_notifyallexceptions

void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • enable (SQBool) – 如果为true则启用已处理异常的错误回调通知。
Remarks: 默认情况下,仅当未处理异常(调用栈中不存在try / catch)时,VM才会调用错误回调。 如果启用了notifyallexceptions,则即使在try / catch块之间,VM也会针对任何异常调用错误回调。 此功能对于实现调试器很有用。

启用/禁用已处理异常的错误回调通知。

sq_setcompilererrorhandler

void sq_setcompilererrorhandler(HSQUIRRELVM v, SQCOMPILERERROR f)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • f (SQCOMPILERERROR) – 指向错误处理函数的指针
Remarks: 如果参数f为NULL,则在编译器错误发生时不会调用函数。 编译器错误处理程序在友元VM之间共享.

设置编译器错误处理函数

3、栈操作

sq_cmp

SQInteger sq_cmp(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
Returns: > 0 if obj1>obj2
Returns: == 0 if obj1==obj2
Returns: < 0 if obj1<obj2

比较栈中的2个对象并进行比较。

sq_gettop

SQInteger sq_gettop(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) – 目标 VM

Returns: 一个整数,表示栈顶部的索引

返回栈顶部的索引

sq_pop

void sq_pop(HSQUIRRELVM v, SQInteger nelementstopop)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • nelementstopop (SQInteger) – 要弹出的元素数量

弹出栈中的n个元素

sq_poptop

void sq_poptop(HSQUIRRELVM v)

Parameters: v (HSQUIRRELVM) –目标VM

从栈中弹出1个对象

sq_push

void sq_push(HSQUIRRELVM v, SQInteger idx)

Parameters: v (HSQUIRRELVM) – 目标 VM

idx (SQInteger) – 栈中的索引要压入的值

将索引idx中的值压入栈

sq_remove

void sq_remove(HSQUIRRELVM v, SQInteger idx)

Parameters: v (HSQUIRRELVM) – 目标 VM

idx (SQInteger) – 要删除的元素的索引

从栈中的任意位置移除元素

sq_reservestack

SQRESULT sq_reservestack(HSQUIRRELVM v, SQInteger nsize)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • nsize (SQInteger) – 所需的栈大小
Returns: SQRESULT

重置栈大小,确保剩余的栈空间至少是指定的大小。如果栈较小,它将自动增长。 如果当前正在运行memtamethod函数将失败并且栈将不会调整大小,则此情况必须被视为”栈溢出”。

sq_settop

void sq_settop(HSQUIRRELVM v, SQInteger v)

Parameters:
  • v (SQInteger) – 目标 VM
  • v – 新栈顶的索引

调整栈大小,如果new top更大,那么当前顶部函数将压入空值。

4、对象创建和处理

sq_bindenv

SQRESULT sq_bindenv(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 目标闭包栈索引
Returns: SQRESULT
Remarks: 克隆的闭包将环境对象保存为弱引用

从栈中弹出一个对象(必须是表,实例或类)克隆栈中位置idx处的闭包,并将弹出的对象设置为克隆闭包的环境。 然后将新的克隆闭包压入栈顶部。

sq_createinstance

SQRESULT sq_createinstance(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • idx (SQInteger) – 目标类的栈索引
Returns: SQRESULT
Remarks: 该函数不会调用实例构造函数。 要创建实例并自动调用其构造函数,必须使用sq_call。

在栈中的”idx”位置创建类的实例。 新类实例被压入到栈顶部。

sq_getbool

SQRESULT sq_getbool(HSQUIRRELVM v, SQInteger idx, SQBool * b)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
  • * b (SQBool) – 指向将存储值的bool的指针
Returns: SQRESULT

获取在栈中索引位置的Bool值。

sq_getbyhandle

SQRESULT sq_getbyhandle(HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE* handle)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中指向类的索引
  • handle (HSQMEMBERHANDLE*) – 成员句柄的指针
Returns: SQRESULT

使用成员句柄压入类或实例成员的值(请参阅sq_getmemberhandle)

sq_getclosureinfo

SQRESULT sq_getclosureinfo(HSQUIRRELVM v, SQInteger idx, SQUnsignedInteger * nparams, SQUnsignedInteger * nfreevars)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 目标闭包在栈中的索引
  • * nparams (SQUnsignedInteger) – 指向将存储参数数量的无符号整数的指针
  • * nfreevars (SQUnsignedInteger) – 指向无符号整数的指针,该整数将存储自由变量的数量
Returns: SQRESULT

从squirrel闭包中获取参数的数量和自由变量的数量。

sq_getclosurename

SQRESULT sq_getclosurename(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 目标闭包在栈中的索引
Returns: SQRESULT

压入在栈中的位置索引处闭包的名称。 请注意,如果闭包是匿名的,则名称可以是字符串,也可以是null,或者没有为其指定名称的本机闭包。

sq_getclosureroot

SQRESULT sq_getclosureroot(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 目标闭包在栈中的索引
Returns: SQRESULT

压入在栈中的位置索引处闭包的根表

sq_getfloat

SQRESULT sq_getfloat(HSQUIRRELVM v, SQInteger idx, SQFloat * f)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
  • * f (SQFloat) – 指向将存储值的float的指针
Returns: SQRESULT

获取浮点数在栈中的idx位置。

sq_gethash

SQHash sq_gethash(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • idx (SQInteger) – 栈索引
Returns: 栈中位置idx处的值的哈希键
Remarks: 哈希值函数与VM使用的相同。

返回栈中idx位置的值的哈希键。

sq_getinstanceup

SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer * up, SQUSerPointer typetag)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
  • * up (SQUserPointer) – 指向将存储结果的userpointer的指针
  • typetag (SQUSerPointer) – 要检查的typetag,如果此值设置为0,则忽略typetag。
Returns: SQRESULT

获取栈中位置idx处的类实例的用户指针。 如果参数’typetag’不是0,则该函数检查实例的类或基类是否用指定的标记标记; 如果不是该函数失败。 如果’typetag’为0,该函数将忽略标记检查。

sq_getinteger

SQRESULT sq_getinteger(HSQUIRRELVM v, SQInteger idx, SQInteger * i)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • idx (SQInteger) – 栈索引
  • * i (SQInteger) – 指向将存储该值的整数的指针
Returns: SQRESULT

获取栈中idx位置的整数值。

sq_getmemberhandle

SQRESULT sq_getmemberhandle(HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE* handle)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中指向类的索引
  • handle (HSQMEMBERHANDLE*) – 指向将存储句柄的变量的指针
Returns: SQRESULT
Remarks: 此方法仅适用于类和实例。 通过类获取的句柄稍后可用于设置或从其中一个类实例获取值,反之亦然。 从基类检索的句柄在派生类中仍然有效并且尊重继承规则。

从栈中弹出一个值并将其用作索引来获取类成员的句柄。 该句柄稍后可用于使用sq_getbyhandle(),sq_setbyhandle()设置或获取成员值。

sq_getreleasehook

SQRELEASEHOOK sq_getreleasehook(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
Remarks: 如果位置idx的对象不是userdata,类实例或类,则该函数返回NULL。

获取栈中位置idx处的userdata,类实例或类的release钩子。

sq_getscratchpad

SQChar * sq_getscratchpad(HSQUIRRELVM v, SQInteger minsize)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • minsize (SQInteger) –暂存器缓冲区请求的大小
Remarks: 缓冲区有效,直到下一次调用sq_getscratchpad

返回一个指向内存缓冲区的指针,该缓冲区至少与minsize一样大。

sq_getsize

SQObjectType sq_getsize(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
Returns: 栈中位置idx处的值的大小
Remarks: 此函数仅适用于字符串,数组,表,类,实例和userdata,如果该值不是有效类型,则函数将返回-1。

返回栈中idx位置的值的大小,如果值是类或类实例,则返回的大小是userdata缓冲区的大小(请参阅sq_setclassudsize)。

sq_getstring

SQRESULT sq_getstring(HSQUIRRELVM v, SQInteger idx, const SQChar ** c)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
  • SQChar ** c (const) – 指向字符串的指针的指针
Returns: SQRESULT

获取指向栈中idx位置的字符串的指针。

sq_getthread

SQRESULT sq_getthread(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM* v)

Parameters:
  • v (HSQUIRRELVM*) –目标VM
  • idx (SQInteger) –栈索引
  • v – 指向将存储线程指针的变量的指针
Returns: SQRESULT

获取一个线程指针在栈中idx位置。

sq_gettype

SQObjectType sq_gettype(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
Returns: 栈中位置idx处的值的类型

返回栈中位置idx处的值的类型

sq_gettypetag

SQRESULT sq_gettypetag(HSQUIRRELVM v, SQInteger idx, SQUserPointer * typetag)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈索引
  • * typetag (SQUserPointer) – 指向将存储标记的变量的指针
Returns: SQRESULT
Remarks: 该函数也适用于实例。 如果目标对象是实例,则获取其基类的typetag。

获取栈中位置idx处的对象(userdata或类)的typetag。

sq_getuserdata

SQRESULT sq_getuserdata(HSQUIRRELVM v, SQInteger idx, SQUserPointer * p, SQUserPointer * typetag)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
  • * p (SQUserPointer) –指向userpointer的指针,指向userdata的有效负载
  • * typetag (SQUserPointer) –指向将存储userdata标记的SQUserPointer的指针(请参阅sq_settypetag)。 参数可以为NULL。
Returns: SQRESULT

获取指向栈中idx位置的userdata值的指针。

sq_getuserpointer

SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer * p)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
  • * p (SQUserPointer) – 指向将存储值的userpointer的指针
Returns: SQRESULT

获取栈中idx位置的userpointer的值。

sq_newarray

void sq_newarray(HSQUIRRELVM v, SQInteger size)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • size (SQInteger) – 要创建的数组的大小

创建一个新数组并将其压入栈.

sq_newclass

SQRESULT sq_newclass(HSQUIRRELVM v, SQBool hasbase)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • hasbase (SQBool) – 如果参数为true,则函数需要在栈顶部的基类。
Returns: SQRESULT

创建一个新的类对象。 如果参数’hasbase’不等于0,则该函数从栈中弹出一个类,并从中继承新创建的类。

sq_newclosure

void sq_newclosure(HSQUIRRELVM v, HSQFUNCTION func, SQInteger nfreevars)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • func (HSQFUNCTION) – 指向本机函数的指针
  • nfreevars (SQInteger) – 自由变量数(可以是0)

创建一个新的本机闭包,弹出n值将它们设置为新闭包的自由变量,并在栈中压入新闭包。

create a new native closure, pops n values set those as free variables of the new closure, and push the new closure in the stack.

sq_newtable

void sq_newtable(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) –目标VM

创建一个新表并将其压入栈

sq_newtableex

void sq_newtableex(HSQUIRRELVM v, SQInteger initialcapacity)

Parameters:
  • v (HSQUIRRELVM) –目标 VM
  • initialcapacity (SQInteger) –要预分配的键/值对的数量

创建一个新表并将其压入栈。 此函数允许指定表的初始容量,以便在创建时知道所需的插槽数时防止不必要的重新散列。

sq_newuserdata

SQUserPointer sq_newuserdata(HSQUIRRELVM v, SQUnsignedInteger size)

Parameters:
  • v (HSQUIRRELVM) –目标VM
  • size (SQUnsignedInteger) – 要以字节为单位创建的userdata的大小

创建一个新的userdata并将其压入到栈中

sq_pushbool

void sq_pushbool(HSQUIRRELVM v, SQBool b)

Parameters:
  • v (HSQUIRRELVM) –目标 VM
  • b (SQBool) – 要压入的bool值(SQTrue或SQFalse)

将一个bool压入栈

sq_pushfloat

void sq_pushfloat(HSQUIRRELVM v, SQFloat f)

Parameters:
  • v (HSQUIRRELVM) –目标VM
  • f (SQFloat) – 要压入的浮点数

将一个float压入栈

sq_pushinteger

void sq_pushinteger(HSQUIRRELVM v, SQInteger n)

Parameters:
  • v (HSQUIRRELVM) –目标 VM
  • n (SQInteger) –要压入的整数

将一个integer压入栈

sq_pushnull

void sq_pushnull(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) –目标VM

将一个null压入栈

sq_pushstring

void sq_pushstring(HSQUIRRELVM v, const SQChar * s, SQInteger len)

Parameters:
  • v (HSQUIRRELVM) –目标 VM
  • SQChar * s (const) –指向要压入的字符串的指针
  • len (SQInteger) – 字符串的长度
Remarks: 如果参数len小于0,VM将使用strlen(s)计算长度

在栈中压入一个字符串

sq_pushuserpointer

void sq_pushuserpointer(HSQUIRRELVM v, SQUserPointer p)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • p (SQUserPointer) – 要压入的指针

将用户指针压入栈

sq_setbyhandle

SQRESULT sq_setbyhandle(HSQUIRRELVM v, SQInteger idx, HSQMEMBERHANDLE* handle)

Parameters:
  • v (HSQUIRRELVM) –目标 VM
  • idx (SQInteger) –栈中指向类的索引
  • handle (HSQMEMBERHANDLE*) –成员句柄的指针
Returns: SQRESULT

从栈中弹出一个值,并使用成员句柄将其设置为类或实例成员(请参阅sq_getmemberhandle)

sq_setclassudsize

SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) –栈中指向类的索引
  • udsize (SQInteger) – 用户数据保留的大小(字节)
Returns: SQRESULT

设置类的用户数据大小。 如果类”用户数据大小”大于0.当创建类的实例时,将在存储实例的内存块的末尾保留额外的空间。 实例的用户指针也将自动设置到此内存区域。 这允许最小化必须携带数据和类实例的应用程序中的分配。

sq_setclosureroot

SQRESULT sq_setclosureroot(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) –目标闭包的索引
Returns: SQRESULT

从栈中弹出一个表,并将其设置为栈中位置idx处的闭包的根

sq_setinstanceup

SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer up)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈索引
  • up (SQUserPointer) – 任意用户指针
Returns: SQRESULT

将类实例的userpointer设置在栈中的位置idx。

sq_setnativeclosurename

SQRESULT sq_setnativeclosurename(HSQUIRRELVM v, SQInteger idx, const SQChar * name)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 目标本机闭包的索引
  • SQChar * name (const) – 要设置的名称
Returns: SQRESULT

在栈中的位置idx处设置本机闭包的名称。 本机闭包的名称纯粹是为了调试pourposes。 当闭包在调用栈中时,通过函数sq_stackinfos()撤消该名称。

sq_setparamscheck

SQRESULT sq_setparamscheck(HSQUIRRELVM v, SQInteger nparamscheck, const SQChar * typemask)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • nparamscheck (SQInteger) – 定义参数号检查策略(0禁用参数检查)。 如果nparamscheck大于0,则VM确保参数的数量正好是nparamscheck中指定的数量(例如,如果nparamscheck == 3,则只能使用3个参数调用该函数)。 如果nparamscheck小于0,则VM确保至少使用nparamcheck中指定的数字的绝对值调用闭包(例如,nparamscheck == -3将检查是否使用至少3个参数调用该函数)。 隐藏的参数’this’包含在这个数字中,自由变量不是。 如果传递了SQ_MATCHTYPEMASKSTRING而不是参数个数,则该函数将自动推断要从类型掩码中检查的参数数量(例如,如果类型掩码是”.sn”就像传递3)。
  • SQChar * typemask (const) – 定义一个掩码来验证传递给函数的参数类型。 如果参数为NULL,则不应用类型检查(默认)。
Remarks: typemask包含一个零终止字符串,表示预期的参数类型。类型表示如下:’o’null,’i’integer,’f’flora,’n’integer or float,’s’string,’t’table,’a’array,’u’userdata,’ c’closure和nativeclosure,’g’generator,’p’userpointer,’v’thread,’x’instance(class instance),’y’class,’b’bool。和’.’任何类型。符号”|”可用作”或”以在同一参数上接受多个类型。可以使用的’或’数量没有任何限制。空格被忽略,因此可以在类型之间插入以提高可读性。例如,要检查将表视为’this’的函数作为第一个参数的字符串,将数字或userpointer作为第二个参数,该字符串将是”tsn | p”(table,string,number或userpointer)。如果参数mask包含的参数少于’nparamscheck’,则不会对其余参数进行类型检查。

设置栈顶部位置的本机闭包的参数验证方案。 允许验证函数接受的参数数量以及可选的类型。 如果函数调用不符合sq_setparamscheck设置的参数模式,则抛出异常。

//example

SQInteger testy(HSQUIRRELVM v)

{

    SQUserPointer p;

    const SQChar *s;

    SQInteger i;

    //no type checking, if the call comply to the mask

    //surely the functions will succeed.

    sq_getuserdata(v,1,&p,NULL);

    sq_getstring(v,2,&s);

    sq_getinteger(v,3,&i);

    //… do something

    return 0;

}

//the reg code

//….stuff

sq_newclosure(v,testy,0);

//expects exactly 3 parameters(userdata,string,number)

sq_setparamscheck(v,3,_SC(“usn”));

//….stuff

sq_setreleasehook

void sq_setreleasehook(HSQUIRRELVM v, SQInteger idx, SQRELEASEHOOK hook)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈索引
  • hook (SQRELEASEHOOK) – 指向钩子的函数指针(参见下面的示例)
Remarks: 在删除用户数据内存之前,VM会调用函数挂钩。

在栈中的位置idx处设置userdata,类实例或类的release钩子。

/* tyedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); */

SQInteger my_release_hook(SQUserPointer p,SQInteger size)

{

    /* do something here */

    return 1;

}

sq_settypetag

SQRESULT sq_settypetag(HSQUIRRELVM v, SQInteger idx, SQUserPointer typetag)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引
  • typetag (SQUserPointer) – 一个任意的SQUserPointer
Returns: SQRESULT

在栈中的位置idx处设置对象的typetag(userdata或类)。

sq_tobool

void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool * b)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈索引
  • * b (SQBool) – 指向将存储值的bool的指针
Remarks: 如果对象不是bool,则函数根据squirrel的规则将值转换为bool。 例如,数字1将导致true,数字0将导致false。

获取栈中位置idx的值为bool。

sq_tostring

void sq_tostring(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈索引

将栈中位置idx处的对象转换为字符串,并将结果字符串压入栈中。

sq_typeof

SQObjectType sq_typeof(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) –栈索引

在栈中的位置idx处压入值的类型名称,它还为实现它的表和类实例调用_typeof元方法; 在这种情况下,压入的对象可能不是字符串(取决于_typeof实现)。

5、Calls

sq_call

SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerror)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • params (SQInteger) – 函数的参数数量
  • retval (SQBool) –如果为true,则该函数的返回值将压入栈中raiseerror (SQBool) –如果为true,如果在执行调用期间发生运行时错误,则vm将调用错误处理程序。
Returns: SQRESULT
Remarks: 该函数弹出所有参数并将闭包留在栈中; 如果retval为true,则压入闭包的返回值。 如果通过sq_suspendvm()暂停执行该函数,则不会自动从栈中弹出闭包和参数。

调用闭包或原生闭包。

sq_getcallee

SQRESULT sq_getcallee(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
Returns: SQRESULT

在栈中压入当前运行的闭包。

sq_getlasterror

SQRESULT sq_getlasterror(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Returns: SQRESULT
Remarks: 压入的错误描述符可以是任何有效的松鼠类型。

将最后错误压入栈中。

sq_getlocal

const SQChar * sq_getlocal(HSQUIRRELVM v, SQUnsignedInteger level, SQUnsignedInteger nseq)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • level (SQUnsignedInteger) –调用栈中的函数索引,0是当前函数nseq (SQUnsignedInteger) – 栈帧中局部变量的索引(0是’this’)
Returns: 如果变量存在于给定级别/ seq,则为局部变量的名称,否则为NULL。

返回栈中给定栈帧和索引的局部变量的名称,并压入当前值。 自由变量被sq_getlocal()视为局部变量,并且将在它们位于栈的基础之前返回,就在真正的局部变量之前。

sq_reseterror

void sq_reseterror(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM

将虚拟机中的最后错误重置为null

sq_resume

SQRESULT sq_resume(HSQUIRRELVM v, SQBool retval, SQBool raiseerror)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • retval (SQBool) –如果为true,则该函数将推送堆栈中的返回值raiseerror (SQBool) –如果为true,如果在执行调用期间发生运行时错误,则vm将调用错误处理程序。
Returns: SQRESULT
Remarks: 如果retval != 0,则压入生成器的返回值。

在栈的顶部位置恢复生成器。

sq_throwerror

SQRESULT sq_throwerror(HSQUIRRELVM v, const SQChar * err)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • SQChar * err (const) –要抛出的错误的描述
Returns: 返回由本机闭包返回的值,以便在虚拟机中引发异常。

设置虚拟机中的最后错误,并返回本机闭包必须返回的值,以便在虚拟机中触发异常。

sq_throwobject

SQRESULT sq_throwobject(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Returns: 由本机闭包返回的值,以便在虚拟机中引发异常。

从栈中弹出一个值将其设置为虚拟机中的最后错误。返回本机闭包必须返回的值,以便在虚拟机中触发异常(也称为SQ_ERROR)。

6、对象操作

sq_arrayappend

SQRESULT sq_arrayappend(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) –栈中目标数组的索引
Returns: SQRESULT
Remarks: 仅适用于数组。

从栈中弹出一个值,并将其压入到栈中位置idx的数组后面。

sq_arrayinsert

SQRESULT sq_arrayinsert(HSQUIRRELVM v, SQInteger idx, SQInteger destpos)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标数组的索引
  • destpos (SQInteger) –数组中要插入项目的位置
Returns: SQRESULT
Remarks: 仅适用于数组。

从栈中弹出一个值并将其插入指定位置的数组中

sq_arraypop

SQRESULT sq_arraypop(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标数组的索引
Returns: SQRESULT
Remarks: 仅适用于数组。

从栈中位置idx的数组后面弹出一个值。

sq_arrayremove

SQRESULT sq_arrayremove(HSQUIRRELVM v, SQInteger idx, SQInteger itemidx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标数组的索引
  • itemidx (SQInteger) –要删除的数组中项的索引
Returns: SQRESULT
Remarks: 仅适用于数组。

从数组中删除项目

sq_arrayresize

SQRESULT sq_arrayresize(HSQUIRRELVM v, SQInteger idx, SQInteger newsize)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标数组的索引
  • newsize (SQInteger) –请求的数组大小
Returns: SQRESULT
Remarks: 仅适用于arrays. newsize如果大于当前大小,则新数组槽将填充null值。

在栈中的位置idx处调整数组的大小。

sq_arrayreverse

SQRESULT sq_arrayreverse(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标数组的索引
Returns: SQRESULT
Remarks: 仅适用于数组。

将数组反转。

sq_clear

SQRESULT sq_clear(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT
Remarks: 仅适用于表和数组。

清除栈中位置idx处的表/数组的所有元素。

sq_clone

SQRESULT sq_clone(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT

在位置idx处克隆表,数组或类实例,克隆它并在栈中压入新对象。

sq_createslot

SQRESULT sq_createslot(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标表的索引
Returns: SQRESULT
Remarks: 在表委托中调用_newslot元方法。 它只适用于table。 [此函数自版本2.0.5以来使用sq_newslot()代替]

从栈中弹出一个键和一个值,并对栈中位置idx的表或类执行set操作,如果插槽不存在则将创建它。

sq_deleteslot

SQRESULT sq_deleteslot(HSQUIRRELVM v, SQInteger idx, SQBool pushval)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – index of the target table in the stack
  • pushval (SQBool) – if this param is true the function will push the value of the deleted slot.
Returns: a SQRESULT
Remarks: invoke the _delslot metamethod in the table delegate. it only works on tables.

pops a key from the stack and delete the slot indexed by it from the table at position idx in the stack, if the slot does not exits nothing happens.

sq_get

SQRESULT sq_get(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT
Remarks: 这个调用将像普通的解引用一样调用委托系统,它只适用于表,数组和用户数据。 如果函数失败,则不会在栈中压入任何内容。

从栈中弹出一个键,并对栈中位置idx处的对象执行get操作,并将结果压入到栈中。

sq_getattributes

SQRESULT sq_getattributes(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标类的索引
Returns: SQRESULT

获取类mameber的属性。 该函数从栈中弹出一个键,并从栈中位置idx的类压入由它们键入的类成员的属性。 如果key为null,则函数获取类级别属性。

sq_getbase

SQRESULT sq_getbase(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标类的索引
Returns: SQRESULT

将存储在位置idx 的”class”的基类压入到栈中。

sq_getclass

SQRESULT sq_getclass(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标类实例的索引
Returns: SQRESULT

将存储位置idx中的”class instance”的类压入到栈中。

sq_getdelegate

SQRESULT sq_getdelegate(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT

将栈中位置idx的对象的当前委托压入到栈中

sq_getfreevariable

const SQChar * sq_getfreevariable(HSQUIRRELVM v, SQInteger idx, SQInteger nval)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标对象的索引(闭包)
  • nval (SQInteger) –基于0的自由变量索引(相对于闭包)。
Returns: 纯松鼠闭包的自由变量的名称。如果出现错误或变量索引超出范围,则为NULL。 如果目标闭包是本机闭包,则返回名称始终为”@NATIVE”。
Remarks: 该函数适用于松鼠闭包和本机闭包。

获取栈中位置idx处闭包的自由变量的值。

sq_getweakrefval

SQRESULT sq_getweakrefval(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 目标弱引用的索引
Returns: SQRESULT
Remarks: 如果函数失败,则不会在栈中压入任何内容。

在栈中的位置idx处所指向的对象压入弱引用。

sq_instanceof

SQBool sq_instanceof(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Returns: SQTrue,如果栈中位置-2处的实例是栈中位置-1处的类对象的实例。
Remarks: 该函数不会从栈中弹出任何对象。

确定对象是否是某个类的实例。

sq_newmember

SQRESULT sq_newmember(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标class的索引
  • bstatic (SQBool) – 如果SQTrue创建一个静态成员。
Returns: SQRESULT
Remarks: 在类中调用_newmember元方法。 它只适用于类。

从栈中弹出一个键,一个值和一个对象(将被设置为成员的属性),并对栈中位置idx的类执行新的插槽操作,如果插槽不存在则将是创建。

sq_newslot

SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标table的索引
  • bstatic (SQBool) – 如果SQTrue创建一个静态成员。 仅当目标对象是class时才使用此参数。
Returns: SQRESULT
Remarks: 在table委托中调用_newslot元方法。 它只适用于table和class。

从栈中弹出一个键和一个值,并对栈中位置idx的表或类执行set操作,如果插槽不存在则将创建它。

sq_next

SQRESULT sq_next(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT

向栈中压入数组,表或类槽的下一个键和值。 要开始迭代,此函数需要在栈顶部保留一个空值; 在每次调用时,函数将使用迭代器替换空值,并压入容器槽的键和值。每次迭代,应用程序都必须弹出前一个键和值,但保留迭代器(用作下一次迭代的参考点)。 迭代完所有插槽后,该函数将失败(请参阅表和数组操作)。

sq_rawdeleteslot

SQRESULT sq_rawdeleteslot(HSQUIRRELVM v, SQInteger idx, SQBool pushval)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标表的索引
  • pushval (SQBool) – 如果此参数为true,则该函数将压入已删除插槽的值。
Returns: SQRESULT

从表中删除一个槽而不使用_delslot元方法。 从栈中弹出一个键,并从栈中位置idx的表中删除由它索引的槽,如果槽不存在则没有任何反应。

sq_rawget

SQRESULT sq_rawget(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT
Remarks: 仅适用于表和数组。

从栈中弹出一个键,并对栈中位置idx的对象执行get操作,而不使用委托或元方法。

sq_rawnewmember

SQRESULT sq_rawnewmember(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标类的索引
  • bstatic (SQBool) – 如果为SQTrue创建一个静态成员。
Returns: SQRESULT
Remarks: 它只适用于类。

从栈中弹出一个键,一个值和一个对象(将被设置为成员的属性),并对栈中位置idx的类执行新的槽操作,如果槽不存在则将是创建。

sq_rawset

SQRESULT sq_rawset(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT
Remarks: 它只适用于表和数组。 如果函数失败,则不会在栈中压入任何内容。

从栈中弹出一个键和一个值,并对栈中位置idx的对象执行set操作,而不使用委托或元方法。

sq_set

SQRESULT sq_set(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT
Remarks: 此调用将像正常赋值一样调用委托系统,它仅适用于表,数组和用户数据。

从栈中弹出一个键和一个值,并对栈中位置idx处的对象执行set操作。

sq_setattributes

SQRESULT sq_setattributes(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标类的索引。
Returns: SQRESULT

设置类mameber的属性。该函数从栈中弹出一个键和一个值,并在栈中位置idx的类上设置属性(由它们键入索引)。 如果key为null,则该函数设置类级别属性。 如果函数成功,则将旧属性值压入栈中。

sq_setdelegate

SQRESULT sq_setdelegate(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT
Remarks: 要从对象中删除委托,必须使用null作为委托而不是table。

从栈中弹出一个table,并将其设置为栈中位置idx处对象的委托。

sq_setfreevariable

SQRESULT sq_setfreevariable(HSQUIRRELVM v, SQInteger idx, SQInteger nval)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
  • nval (SQInteger) – 基于0的自由变量索引(相对于闭包)。
Returns: SQRESULT

从栈中弹出一个值,并将其设置为栈中位置idx处的闭包的自由变量。

sq_weakref

void sq_weakref(HSQUIRRELVM v, SQInteger idx)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
Returns: SQRESULT
Remarks: 如果idx位置的对象是一个integer,float,bool或null,则压入对象本身而不是弱ref。

将栈中位置idx处对象的弱引用压入栈。

7、字节序列化

sq_readclosure

SQRESULT sq_readclosure(HSQUIRRELVM v, SQREADFUNC readf, SQUserPointer up)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • readf (SQREADFUNC) –指向在序列化期间由vm调用的read函数的指针。up (SQUserPointer) –传递给每次调用read函数的指针
Returns: SQRESULT

序列化(读取)一个闭包并将其压入到栈顶部,源是用户通过读回调定义的。

sq_writeclosure

SQRESULT sq_writeclosure(HSQUIRRELVM v, SQWRITEFUNC writef, SQUserPointer up)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • writef (SQWRITEFUNC) – 指向在序列化期间由vm调用的write函数的指针。
  • up (SQUserPointer) –传递给每次调用write函数的指针
Returns: a SQRESULT
Remarks: 带有自由变量的闭包无法序列化

序列化(write)栈顶部的闭包,目标是通过写回调用户定义的。

8、原始对象处理

sq_addref

void sq_addref(HSQUIRRELVM v, HSQOBJECT* po)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • po (HSQOBJECT*) – 对象句柄指针

添加对象句柄的引用。

sq_getobjtypetag

SQRESULT sq_getobjtypetag(HSQOBJECT* o, SQUserPointer* typetag)

Parameters:
  • o (HSQOBJECT*) – 对象句柄指针
  • typetag (SQUserPointer*) – 指向将存储标记的变量的指针
Returns: SQRESULT
Remarks: 该函数也适用于实例。 如果目标对象是实例,则获取其基类的typetag。

获取原始对象引用的typetag(userdata或class)。

sq_getrefcount

SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v, HSQOBJECT* po)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • po (HSQOBJECT*) – 对象句柄指针

返回给定对象的引用数。

sq_getstackobj

SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, HSQOBJECT* po)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • idx (SQInteger) – 栈中目标对象的索引
  • po (HSQOBJECT*) – 对象句柄指针
Returns: SQRESULT

从栈中获取一个对象并将其存储在对象句柄中。

sq_objtobool

SQBool sq_objtobool(HSQOBJECT* po)

Parameters:
  • po (HSQOBJECT*) – 对象句柄指针
Remarks: 如果对象非bool将始终返回false。

返回原始对象引用的bool值。

sq_objtofloat

SQFloat sq_objtofloat(HSQOBJECT* po)

Parameters:
  • po (HSQOBJECT*) – 对象句柄指针
Remarks: 如果对象是整数,则将其转换为float。 如果对象不是数字,则始终返回0。

返回原始对象引用的float值。

sq_objtointeger

SQInteger sq_objtointeger(HSQOBJECT* po)

Parameters:
  • po (HSQOBJECT*) – 对象句柄指针
Remarks: 如果对象是float,则将其转换为整数。 如果对象不是数字,则始终返回0。

返回原始对象引用的整数值。

sq_objtostring

const SQChar* sq_objtostring(HSQOBJECT* po)

Parameters:
  • po (HSQOBJECT*) – 对象句柄指针
Remarks: 如果对象未引用字符串,则返回NULL。

返回原始对象引用的字符串值。

sq_objtouserpointer

SQUserPointer sq_objtouserpointer(HSQOBJECT* po)

Parameters:
  • po (HSQOBJECT*) –对象句柄指针
Remarks: 如果对象未引用用户指针,则返回NULL。

返回原始对象引用的userpointer值。

sq_pushobject

void sq_pushobject(HSQUIRRELVM v, HSQOBJECT obj)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • obj (HSQOBJECT) – 对象句柄

将对象句柄引用的对象压入栈。

sq_release

SQBool sq_release(HSQUIRRELVM v, HSQOBJECT* po)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • po (HSQOBJECT*) – 对象句柄指针
Returns: SQTrue如果释放的对象句柄丢失了所有引用(使用sq_addref添加的引用)。否则SQFalse。
Remarks: 当函数丢失所有引用时,该函数会将对象句柄重置为null。

从对象句柄中删除引用。

sq_resetobject

void sq_resetobject(HSQOBJECT* po)

Parameters:
  • po (HSQOBJECT*) – 对象句柄指针
Remarks: 必须使用此函数初始化每个对象句柄。

重置(初始化)对象句柄。

9、垃圾回收

sq_collectgarbage

SQInteger sq_collectgarbage(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Remarks: 这个api只适用于垃圾收集器构建(NO_GARBAGE_COLLECTOR没有定义)

运行垃圾收集器并返回找到的(并删除)引用周期数

sq_resurrectunreachable

SQRESULT sq_resurrectunreachable(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Remarks: 这个api只适用于垃圾收集器构建(NO_GARBAGE_COLLECTOR没有定义)

运行垃圾收集器并在栈中压入包含找到的所有无法访问的对象的数组。如果找不到无法访问的对象,则压入null。 此功能为在帮助调试引用周期。

10、调试接口

sq_getfunctioninfo

SQRESULT sq_getfunctioninfo(HSQUIRRELVM v, SQInteger level, SQFunctionInfo * fi)

Parameters:
  • v (HSQUIRRELVM) –  目标 VM
  • level (SQInteger) – 调用栈等级
  • * fi (SQFunctionInfo) – 指向将存储闭包信息的SQFunctionInfo结构的指针
Returns: SQRESULT.
Remarks: 返回的SQFunctionInfo结构的成员’funcid’是该函数的唯一标识符; 这对于在应用程序(例如分析器)中识别特定的松鼠代码片段非常有用。 如果栈中的闭包是本机C闭包,则此方法将失败。

typedef struct tagSQFunctionInfo {

    SQUserPointer funcid; //unique idetifier for a function (all it’s closures will share the same funcid)

    const SQChar *name; //function name

    const SQChar *source; //function source file name

}SQFunctionInfo;

sq_setdebughook

void sq_setdebughook(HSQUIRRELVM v)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
Remarks: 为了接收”每行”回调,必须使用行信息编译脚本。如果没有激活行信息,则只会调用’call / return’回调。

从栈弹出一个闭包,并将其设置为调试钩子。设置调试钩子时,它会覆盖任何以前设置的本机或非本机钩子。如果钩子为null,则将禁用调试钩子。

sq_setnativedebughook

void sq_setnativedebughook(HSQUIRRELVM v, SQDEBUGHOOK hook)

Parameters:
  • v (HSQUIRRELVM) – 目标VM
  • hook (SQDEBUGHOOK) – 本机钩子函数
Remarks: 为了接收”每行”回调,必须使用行信息编译脚本。如果没有激活行信息,则只会调用’call / return’回调。

设置本机调试钩子。设置本机钩子时,它会覆盖任何以前设置的本机钩子或非本机钩子。 如果钩子为NULL,则将禁用调试钩子。

sq_stackinfos

SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos * si)

Parameters:
  • v (HSQUIRRELVM) – 目标 VM
  • level (SQInteger) – 调用栈等级
  • * si (SQStackInfos) – 指向将存储堆栈信息的SQStackInfos结构的指针
Returns: SQRESULT.

获取调用栈中某个级别的调用栈信息。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容