squirrel 语言入门教程
1、词汇结构
(1)标识符
标识符以字母字符或“_”开头,后跟任意数量的字母字符,“_”或数字([0-9])。 是一种区分大小写的语言,这意味着同一个字母字符的小写和大写表示被视为不同的字符。 例如,“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)其他符号
{ | } | [ | ] | . | : |
:: | ' | ; | " | @" |
- 常量
一些常量的表示方法:
34 --->十进制的整数
0xFF00A120 --->十六进制的整数
0753 --->八进制的整数
'a' --->整数,表示字母A所对应的ascii码
1.52 --->浮点数
1.e2 --->科学计数法表示的浮点数
1.e-2 --->也是科学计数法表示的浮点数
"I'm a string" --->常规的字符串
@"I'm a verbatim string" --->另外一种表达形式的字符串
@" I'm a multiline verbatim string
(6)注释
// 单行注释
/* */ 多行注释
2、值和数据类型
(1)Interger
整数表示32位的带符号数:
local a = 123 //十进制
local b = 0x0012 //十六进制
local c = 075 //八进制
local d = 'w' //把'w'的ascii码的数值附给d
(2)Float
float表示32位的浮点数:
local a=1.0
local b=0.234
(3)String
字符串是一个不可变的字符序列,修改字符串是创建一个新字符串。
字符串用引号(“)分隔,可以包含转义序列(\ 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两种取值
(6)Array
数组是简单的对象序列,它们的大小是动态的,它们的索引始终从0开始:
local a = ["I'm","an","array"]
local b = [null]
b[0] = a[2];
local x = []; //定义数组
x.resize(20);//调整数组的大小
(7)Function
函数类似于其他类C语言和大多数编程语言的函数,但是有一些关键的区别
函数声明
function fun1(a,b,c)
{
return a+b-c;
}
默认参数
函数可以有默认参数。
具有默认参数的函数声明如下:
function test(a,b,c = 10, d = 20)
{
....
}
当调用函数test并且未指定参数c或d时,VM会自动将默认值分配给未指定的参数。 默认参数可以是任何有效的表达式。 表达式在运行时进行检查。
函数调用
foo(x,y) ;
3、声明
程序是一个简单的语句序列:
stats := stat [';'|'\n'] stats
语句与C系列语言(C / C ++,Java,C#等......)相当:赋值,函数调用,程序流控制结构等。加上一些自定义语句,如yield,table和array constructors。 语句可以用新行或';'(或使用关键字case或default,如果在switch / case语句中)分隔,如果语句后跟'}',则不需要这两个符号。
(1)语句块
由大括号({})分隔的一系列语句称为块; 块是一个声明本身。
(2) 控制流程语句
最常见的控制流语句:
if, while, do-while, switch-case, for
(2.1)true and false
布尔类型(bool),它认为null,0(整数)和0.0(浮点)为false,任何其他值都被认为是true的。
(2.2) if/else
根据表达式的结果有条件地执行语句:
if(a>b)
a=b;
else
b=a;
if(a==10)
{
b=a+b;
return a;
}
(2.3) while
条件为真时执行语句:
function testy(n)
{
local a=0;
while(a<n) a+=1;
while(1)
{
if(a<0) break;
a-=1;
}
}
(2.4)do/while
执行一次语句,然后重复执行语句,直到条件表达式求值为false:
local a=0;
do
{
print(a+"\n");
a+=1;
} while(a>100)
(2.5) switch
Switch是一个控制语句,允许通过将控制权传递给其正文中的一个case语句来多次选择代码。 如果case都不匹配会跳转到default标签(如果存在),如果是case实例,则控制将转移到case_exp与exp匹配的case标签。switch语句可以包含多个case,如果2个case具有相同的表达式结果,则将首先考虑第一个。default标签只允许一次,必须是最后一个。 break语句将跳转到switch块之外。
Local i=0;
switch(i)
{
case 0:
break;
case 1:
break;
default:
break;
}
(3) 循环
(3.1) for
只要条件不等于false,就执行一个语句:
for(local a=0;a<10;a++)
{
print(a+"\n");
}
for(;;)
{
print(loops forever+"\n");
}
(4) break
break语句终止循环的执行(for,while或do / while)或跳出switch语句;
(5) continue
continue运算符跳转到循环的下一次迭代,跳过以下语句的执行。
(6) return
return语句终止当前函数/生成器的执行,并可选择返回表达式的结果。 如果省略表达式,则函数将返回null。 如果在发生器内使用return语句,则生成器将不再可恢复。
(7) 局部变量声明
可以在程序中的任何位置声明局部变量; 它们存在于它们的声明到它们已被声明的块的末尾之间。 允许局部变量声明语句作为for循环中的第一个表达式:
for(local a=0;a<10;a+=1)
print(a);
(8) 函数声明
创建一个新函数
function fun1(a,b,c)
{
return a+b-c;
}
(9) 常量
常量将特定值绑定到标识符。 常量类似于全局值,除了它们是在编译时计算的,并且它们的值不能更改。
常量值只能是整数,浮点数或字符串文字。 不允许表达式。 使用以下语法声明:
const foobar = 100;
const floatbar = 1.2;
const stringbar = "I'm a contant string";
常量始终是全局范围的,从声明它们的那一刻起,任何后续代码都可以引用它们。
(10) 枚举
作为常量,枚举将特定值绑定到名称。 枚举也在编译时进行评估,其值不能更改。
枚举声明在程序中引入了新的枚举。 枚举值只能是整数,浮点数或字符串文字。 不允许表达:
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) 表达式
每个表达式也被允许作为语句
4、表达式
(1) 赋值
正常赋值(=):
a = 10;
(2) 操作符
(2.1) ?: 操作符
根据表达式的结果有条件地评估表达式。
local a=0;
local x=(a>10)?1:0;
(2.2) 算术操作符
支持标准算术运算符+, - ,*,/和%。 除此之外还支持联合运算符(+ =, - =,* =,/ =,%=)和递增和递减运算符(++和 - );:
a += 2;
//is the same as writing
a = a + 2;
x++
//is the same as writing
x = x + 1
所有操作符都可以正常使用整数和浮点数; 如果一个操作数是一个整数而一个是浮点数,则表达式的结果将是float。 +运算符具有字符串的特殊行为; 如果其中一个操作数是一个字符串,则operator +将尝试将另一个操作数转换为字符串并将它们连接在一起。 对于实例和表,调用_tostring。
(2.3) 关系操作符
关系运算符是:==, <, <=, <, <=, !=
(2.4) 逻辑运算符
逻辑运算符是:&&,|| ,!
如果第一个参数为null,则运算符&&(逻辑与)返回null,否则返回其第二个参数。 操作符|| (逻辑或)如果不是null则返回其第一个参数,否则返回第二个参数。
如果给定的否定值不是null,则'!'运算符将返回null,如果给定的值为null,则返回不为null的值。
(2.6) 逗号操作符
逗号运算符从左到右计算两个表达式,运算符的结果是右边表达式的结果; 左表达式的结果被丢弃:
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.7) 位操作符
支持标准的运算符&,|,^,〜,<<,>>加上无符号右移运算符<<<。 除了将左操作数视为无符号整数外,无符号右移与普通右移运算符(<<)完全相同,因此不受符号的影响。 这些运算符仅处理整数值,将任何其他操作数类型传递给这些运算符将导致异常。
(2.8) 运算符优先级
-, ~, !, typeof , ++, -- | 最高 |
/, *, % | ... |
+, - | |
<<, >>, >>> | |
<, <=, >, >= | |
==, !=, <=> | |
& | |
^ | |
&&, in | |
+=, =, -= | ... |
,(comma operator) | 最低 |
(2.9) Integer整数
integer.tofloat()
将数字转换为float并返回它
integer.tostring()
将数字转换为字符串并返回它
integer.tochar()
返回包含由整数表示的单个字符的字符串。
(2.10) Float浮动数
float.tointeger()
将数字转换为整数并返回它
float.tostring()
将数字转换为字符串并返回它
float.tochar()
返回一个字符串,其中包含由float的整数部分表示的单个字符。
(2.11) Bool 逻辑
bool.tofloat()
返回1.0表示true为0.0表示false
bool.tointeger()
返回1表示true为0表示false
bool.tostring()
返回“true”表示true为“false”表示false
(2.12) 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()
返回字符串的大写副本。
format 格式化字符串
format(formatstr, ...)
返回根据formatstr格式化的字符串以及其后的可选参数。 格式字符串遵循与标准C函数的printf系列相同的规则(不支持“*”)。
sq> print(format("%s %d 0x%02X\n","this is a test :",123,10));
this is a test : 123 0x0A
格式化字符串:
function OnDraw(handle)
{
local b = format("当班产量:%d",Yx(1093));
SetText(handle,b);
}
abs(x)
以整数形式返回x的绝对值
acos(x)
返回x的反余弦值
asin(x)
返回x的反正弦值
atan(x)
返回x的反正切值
atan2(x, y)
返回x / y的反正切值
ceil(x)
返回一个浮点值,表示大于或等于x的最小整数
cos(x)
返回x的余弦值
exp(x)
返回float参数x的指数值
fabs(x)
返回x作为float的绝对值
floor(x)
返回一个浮点值,表示小于或等于x的最大整数
log(x)
返回x的自然对数
log10(x)
回x的对数基数-10
pow(x, y)
将x提升到y的幂
rand()
返回0到RAND_MAX范围内的伪随机整数
sin(x)
返回x的正弦值
sqrt(x)
返回x的平方根
srand(seed)
设置生成一系列伪随机整数的起点
tan(x)
返回x的正切值
RAND_MAX
rand()函数可以返回的最大值
PI
数值常数pi(3.141592)是圆周长与直径之比
clock()
返回一个浮点数,表示自进程启动以来经过的秒数
date([time[, format]])
返回一个表,其中包含在槽中拆分的日期/时间:
sec | 秒(0 - 59). |
min | 分钟 (0 - 59). |
hour | 小时(0 - 23). |
day | 日 (1 - 31). |
month | 月 (0 - 11; 一月= 0). |
year | 年 (当前年). |
wday | 星期 (0 - 6; 星期日 = 0). |
yday | 一年的天数 (0 - 365; 1月1日 = 0). |
如果省略time,则使用当前时间。
如果format是'l'本地时间 或 'u'UTC时间,如果省略则默认为'l'(本地时间)。
getenv(varaname)
返回包含环境变量varname值的字符串
remove(path)
删除path指定的文件
rename(oldname, newname)
将oldname指定的文件或目录重命名为newname指定的名称
system(cmd)
通过os命令解释器执行字符串cmd。
time()
返回自1970年1月1日午夜00:00:00起经过的秒数。
这个函数的结果可以通过函数date()格式化
endswith(str, cmp)
如果字符串str的结尾与字符串cmp匹配则返回true,否则返回false
ecape(str)
在需要转义的字符(”,a,b,t,n,v,f,r,\,”,’,0,xnn).之前添加反斜线返回
format(formatstr, ...)
返回根据formatstr格式化的字符串以及其后的可选参数。 格式字符串遵循与标准C函数的printf系列相同的规则(不支持“*”)。
sq> print(format("%s %d 0x%02X\n","this is a test :",123,10));
this is a test : 123 0x0A
strip(str)
删首空,并返回删除后字符串。
rstrip(str)
删尾空,并返回删除后字符串。
split(str, separtators)
返回在str中出现分隔符的每个点处拆分的字符串数组。 分隔符不会作为任何数组元素的一部分返回。 参数分隔符是一个字符串,用于指定要用于拆分的字符。
local a = split("1.2-3;4/5",".-/;");
// 返回将是 [1,2,3,4,5]
startswith(str, cmp)
如果字符串str的开头与字符串cmp匹配则返回true,否则返回false
strip(str)
删首尾空,并返回删除后字符串。