L脚本语言语法手册
0.14版
简 介
L脚本语言是一个轻量级的,旨在接近自然语言的编程语言,目前支持在中文、英文基础上的编程。并可扩展为任意语种。L脚本语言的语法结构简单,程序结构相对松散,易学易用。
目前L脚本语言仍处于开发初期,功能尚不完善。目前在Windows平台提供了一个简单的源码编辑器,建议使用notepad++或者Visual studio code进行源码编辑。
目录
L脚本语言定义了单一的语法格式
动作:对象类型,对象名称,参数列表
Action:ObjectType,ObjectName,ParamList
L脚本语言的每一行代码都遵从这一条语法规则,相对其他编程语言来说,这样的设计更加简单,更容易实现,更容易学习和记忆
由于有着简洁的语法,L脚本语言的解释引擎实现相比比其他编程语言简单了许多,对于比较简单的编程任务,已经足够了
源码编码格式
L脚本语言是在中文环境中开发的,Windows环境下L脚本的代码允许存储为ansi格式或unicode格式,Linux环境下L脚本的代码需要存储为utf8编码格式
有关代码编辑
我们在编写L脚本语言代码的时候会觉得输入法的切换比较麻烦,因为我们的分隔符、数学运算的运算符是英文的半角字符,而程序的关键字是中文的字符,我们定义变量的时候又喜欢使用英文,这个时候其实可以把输入法切换为中文,同时把标点符号切换为英文,这时候就方便一些了。例如使用搜狗拼音输入法,我们按”ctrl+,”切换出中文输入法,按”ctrl+.”切换为英文标点符号,当我们输入中文关键字的时候直接按空格输入,当我们输入英文的变量名时直接按回车输入,输入标点符号的时候和输入分隔符、运算符的时候也不需要切换为英文模式,直接输入就可以了
L脚本语言的注释是以#打头的行,注释和空行会被解释引擎自动忽略
L脚本语言同时也支持C++风格的注释,一行脚本中//之后到换行之间的字符都被识别为注释并被忽略
当解释引擎发现某行代码中包含错误时会尽可能地提供错误信息并简单地将这行代码忽略掉
任何对象必须先进行定义之后才能引用,对象定义的格式为
定义:对象类型,对象名称,初始值
define:objecttype,objectname,initialvalue
例如
定义:整数,number1,0
define:int,number1,0
定义:整数,number2,1
define:int,number2,1
定义:浮点数,double,1.0
define:double,double1,1.0
定义:字符串,string1,”helloworld”
define:string,string1,”helloworld”
如果想要将对象的内容展示出来,可以这样
显示:number1
show:number1
显示:string1
show:string1
:是分隔符用来分隔动作和对象
,是分隔符用来分隔参数列表
在这里,对象的名称可以是除:,以外的任何字符串,中文、英文、韩文都是可以的
如果仅知道对象名字想要知道对象的类型,可以通过以下方式查询
获取:类型,对象名字,保存对象类型的字符串名
例如
获取:类型,int1,str1
显示:str1
获取:类型,func1,str1
显示:str1
获取:类型,123456,str1
显示:str1
L脚本语言内置了对整数(32位整数)、大整数(64位整数)和浮点数(双精度)的支持,允许进行四则运算、逻辑运算以及取余数等
整数定义的格式为
定义:整数,整数的名称,整数的初始值(可选)
define:int,nameofint,initialvalue(optional)
定义:大整数, 大整数的名称,大整数的初始值(可选)
define:bigint,nameofbigint,initialvalue(optional)
浮点数定义的格式为
定义:浮点数,浮点数的名称,浮点数的初始值(可选)
define:double,nameofdouble,initialvalue(optional)
整数和浮点数定义时若没有初始值,则默认初始化为0
数值计算和逻辑运算必须遵从固定的格式
计算:表达式的内容,表达式的内容,…
compute:expression,expression,…
“计算”关键字是可以省略的
表达式的内容,表达式的内容,…
expression,expression,…
如
计算:number1+number2
compute:number1+number2
计算:number1*number2
compute:number1*number2
计算:number1>number2
compute:number1>number2
计算:number1=number2+100,number1=number*3
compute: number1=number2+100,number1=number*3
每一行代码的运行结果会保存到一个“结果”对象中,这个对象是全局的
所以如果我们想要把数值计算的结果显示出来,就可以这样写
计算:number1+number2*100
compute:number1+number2*100
显示:结果
show:result
表达式的个数可以是任意多个,L脚本语言会依次计算每一个表达式,并把最后一个表达式的运算结果存入“结果”对象
加减乘除四则运算
加法
计算:number+number2
compute:number+number2
显示:结果
show:result
减法
计算:number1-number2
compute:number1-number2
显示:结果
show:result
乘法
计算:number1*number2
compute:number1*number2
显示:结果
show:result
除法
计算:number1/number2
compute:numbe1/number2
显示:结果
show:result
取余数
计算:number1%number2
compute:number1%number2
显示:结果
show:result
赋值
计算:number1=number2+1
compute:number1=number2+1
显示:结果
show:result
计算:number1+=number2
compute:number1+=number2
计算:number1-=number2
compute:number1-=number2
计算:number1*=number2
compute:number1*=number2
计算:number1/=number2
compute:number1/=number2
计算:number1%=number2
compute:number1%=number2
括号的使用
乘法 除法 取余数 操作的优先级高于 加法和减法 同级的运算保持左结合性,因此如果希望改变运算的顺序,需要通过使用括号,如
计算:(number1+number2)*100
compute:(number1+number2)*100
L脚本语言中逻辑值"真"等价于数值1, 逻辑值"假"等价于数值0
因此逻辑运算的值仅有1和0两种状态
比较大小
计算:number1>number2
compute:number1>number2
显示:结果
show:result
计算:number1>=number2
compute:number1>=number2
计算:number1<number2
compute:number1<number2
计算:number1<=number2
compute:number1<=number2
计算:number1==number2
compute:number1==number2
逻辑与
计算:(number1>=number2)&&( number3>=number4)
compute: (number1>=number2)&&(number3>=number4)
逻辑或
计算:(number1==number2)||( number1==number3)
compute: (number1==number2)||(number1==number3)
逻辑非
计算:!(number1==number2)
compute: !(number1==number2)
按位取反(未实现)
计算:~number1
compute: ~number1
按位左移
计算:number1 << number2
compute: number1 << number2
number1按位左移number2位
按位右移
计算:number1 >> number2
compute: number1 >> number2
number1按位右移number2位
按位与
计算:number1 & number2
compute: number1 & number2
按位或
计算:number1 | number2
compute: number1 | number2
按位异或
计算:number1 ^ number2
compute: number1 ^ number2
字符串定义时可以进行初始化,若没有初始化参数,则默认为空串
字符串定义的格式为
定义:字符串,字符串的名称,字符串的初始值
define:string,nameofstring,intialvaue
例如
定义:字符串,string1,”hello”
define:string,string1,”hello”
定义:字符串,string2," world"
define:string,string2,” world”
支持字符串的连接操作
格式为
连接:字符串,第一个字符串,第二个字符串
connect:string,first string,second string
连接:字符串,string1,string2
connect:string,string1,string2
显示:string1
show:string1
支持字符串取子串的操作
格式为
取子串:子串名称,原字符串名称,取子串时的其实位置,取子串的长度
getsubstring:nameofsubstring,originalstring,startpos,lengthofsubstring
如
定义:字符串,string3
define:string,string3
取子串:string3,string1,1,3
getsubstring:string3,string1,1,3
允许将字符串的内容清空
格式为
清空:字符串,字符串的名称
clear:string,nameofstring
支持字符串查找子串的操作
格式为
查找:字符串,原字符串,子串
find:string,originalstring,substring
如果找到子串,“结果”对象置为一个整数对象,其值是1否则值是0
如
查找:字符串,string1,string2
find:string,string1,string2
支持字符串替换子串的操作
格式为
替换:字符串,原字符串,字符串中的子串,替换的子串
replace:string,originalstring,substring,replacedstring
和查找一样,如果找到子串,“结果”对象置为一个整数对象,其值是1否则值是0
如
替换:字符串,string1,string2,"xyz"
replace:string,string1,string2,”xyz”
字符串可以转换大小写,还可以反转
语法格式为
转换:字符串名称,大写
transform:nameofstring,upper
转换:字符串名称,小写
transform:nameofstring,lower
转换:字符串名称,反转
transform:nameofstring,reverse
字符串可以转换为整数或浮点数
语法格式为
转换:整数名,字符串名
转换:浮点数名,字符串名
transform:nameofdouble,nameofstring
任何对象都可以转换为字符串
语法格式为
转换:字符串名,对象名
transform:nameofstring,nameofobject
L脚本语言内置了简单的正则表达式实现,允许通过正则表达式匹配查找字符串,目前还不支持分组和替换功能
正则表达式本身是特殊格式的字符串,定义格式为
定义:正则表达式,正则表达式的名称,正则表达式的内容
define:regexp,name ofregexp,regexp string content
如
定义:正则表达式,regexp1,"\d\d\d"
define:regexp,regexp1,”\d\d\d”
如果要使用正则表达式匹配某个字符串,格式如下
定义:字符串,str2,"abc"
define:string,str2,”abc”
定义:字符串,str1,123
define:string,str1,123
匹配:正则表达式,regexp1,str1
match:regexp,regexp1,str1
匹配:正则表达式,regexp1,str2
match:regexp,regexp2,str2
L脚本语言中支持条件分支,叫做“如果”语句,格式为
如果:条件表达式或逻辑运算表达式,条件为真时执行的语句
否则:条件为假时执行的语句(可选)
test:expression,action
otherwise:action(可选)
这里要注意,”否则”语句必须是紧跟着”如果”语句的下一条
条件语句也支持语句块,格式为
如果:条件表达式或逻辑运算表达式
条件为真时执行的语句1
条件为真时执行的语句2
否则(可选)
条件为假时执行的语句1(可选)
条件为假时执行的语句1(可选)
结束
这里要注意,”否则”语句以及条件为假的分支语句块是可选的,但是”结束”语句必须有,就是说,当”如果”语句不是简单的一行,而是包含语句块时,必须有”结束”语句标识语句块的结尾
例如
如果:number1>number2,显示:"大于"
test:number1>number2,show:”bigthan!”
否则:显示:“小于”
otherwise:show:”lessthan!”
在L脚本语言中循环语句叫做“当”语句,格式为
当:条件表达式或逻辑运算表达式,条件为真时重复执行的语句
while:expression,action:
或者
当:条件表达式或逻辑运算表达式
#循环语句块
#如果:条件满足,跳出
#如果:条件满足,继续
结束
可以在循环体中通过 跳出 命令来结束循环,类似于C语言的break
可以在循环体中通过 继续 命令来忽略后面的循环体,重新考察条件表达式开始新一轮的循环,类似于C语言的continue
例如
当:1,调用:函数,function1
while:1,call:function,function1
定义:整数,int1,100
当:int1>0
如果:int1==50,跳出
显示:int1
计算:int1-=1
结束
和其它编程语言一样,函数必须先定义之后才能进行调用
函数定义的格式为
定义:函数,函数的名称,形式参数列表
#函数体
结束
define:function,name_of_function,formalparameters
#functionbody
end
函数的参数可以是0个或任意多个,函数的参数必须是对象或静态数值
函数体可以是任意合法的代码行,但是不允许函数的嵌套定义
函数体必须是由对称的“定义:函数“,“结束”包起来
函数体内部允许定义局部对象,其生存期随函数调用时产生,函数调用结束时销毁
函数调用的格式为
调用:函数,函数的名称,实际参数列表
调用:函数的名称,实际参数列表
函数的名称:实际参数列表
函数的名称(实际参数列表)
call:function,name_of_function,realparameters
call:name_of_function,realparameters
name_of_function:realparameters
name_of_function(realparameters)
L脚本语言的函数可以有返回值,也可以没有,返回值是任意对象,所以不必在函数声明中指定返回值类型,如果函数需要返回值,可以通过”返回”语句,
语法格式为:
返回:对象名
返回:表达式
return:objectname
return:expression
L脚本语言的函数参数是占位符号,并不能表示参数的对象类型,因此,在设计函数的时候需要自己确保形式参数与实际参数的类型一致,这样设计是为了实现简单,同时考虑L脚本语言并不适合处理大型任务,因此函数实现不会过于复杂,但是使用时应小心可能存在的问题
函数调用的例子代码
定义:整数,ab,22
定义:函数,乘以二,参数1
开始:函数,乘以二
计算:参数1=参数1*2
结束:函数,乘以二
乘以二:ab
显示:ab
类似于其它编程语言,L脚本语言可以有一个默认的主函数,这个主函数实际上是名字为“主函数”的一个普通函数,L脚本解释引擎会找到这个函数并自动调用这个函数,这实际上就是程序的入口点。
L脚本语言中的数组是对象数组,数组的大小在定义时确定,数组的元素可以是静态数值,静态字符串,或同一类型的对象
数组可以在定义时初始化,初始化时确定数组的类型和大小
也可以定义一个有大小无类型的空值数组,对这个数组的元素进行第一次赋值时确定数组元素的类型
数组定义的语法格式为
定义:数组,数组对象的名称,元素列表
定义:数组,数组对象的名称,[数组的大小]
可以通过下标或元素名的方式访问数组的元素
数组对象的名称[下标]
数组对象的名称[元素的名称]
例如
定义:数组,array1,1,2,3,4,5,6,7
显示:array1
定义:数组,array2,abc,def,fgh,ghi,ddd,"123"
显示:array2
定义:字符串,string1,aaa
定义:字符串,string2,bbb
定义:数组,array3,string1,string2
显示:array3
定义:数组,array4[10]
定义:整数,int1,10
定义:整数,int2,20
定义:数组,array5,int1,int2
显示:array5[1]
计算:array5[1]=15+int2
显示:array5[1]
L脚本语言中的表的概念与Lua语言中的表的概念类似,实际上就是名字与对象之间的映射关系
表中的元素可以是任意合法的L脚本对象,表的大小是动态的,允许动态添加删除元素
表定义的语法格式为
定义:表,表的名称
define:table,name oftable object
插入:表,表的名称,对象名
insert:table,name oftable object,user object name
取大小,表,整数变量名
getsize:table,name ofint object
取元素:表,元素的别名,元素在表中的索引
getelement:table,element’sreplace name,index of element
例如
定义:字符串,str1,"hello"
define:string,str1,”hello”
定义:字符串,str2,"world"
define:string,str2,”world”
定义:整数,number1,123456
define:int,number1,123456
定义:浮点数,number2,1.75
define:double,number2,1.75
定义:表,table1
define:table,table1
插入:表,table1,str1
insert:table,table1,str1
插入:表,table1,str2
insert:table,table1,str2
插入:表,table1,number1
insert:table,table1,number1
插入:表,table1,number2
insert:table,table1,number2
定义:函数,function1,参数1,参数2
define:function,function1,param1,param2
开始:函数,function1
start:function,function1
显示:参数1
show:param1
显示:参数2
show:param2
结束:函数,function1
end:function,function1
插入:表,table1,function1
insert:table,table1,function1
显示:table1
show:table1
和数组对象类似,也可以通过下标或元素名称的方式访问表的元素
数组对象名[元素下标]
数组对象名[元素名称]
例如
定义:字符串,str1,"hello"
定义:字符串,str2,"world"
定义:整数,number1,123456
定义:浮点数,number2,1.75
定义:表,table1
插入:table1,str1
插入:table1,str2
插入:table1,number1
插入:table1,number2
显示:table1[str1]
计算:table1[number1]+=1
显示:table1[number1]
如果表对象的成员还是表,也可以级联访问表的元素,例如
定义:字符串,string1,hellotable
定义:表,subtable
插入:subtable,string1
定义:表,table1
插入:table1,subtable
显示:table1[subtable[string1]]
对于表对象,L脚本语言提供了一种便捷的访问所有元素的方式,”遍历语句”
L脚本语言会对每一个元素调用遍历语句提供的回调函数,语法格式如下:
遍历:表对象的名称,回调函数名
回调函数的格式为
定义:函数,表元素的遍历函数,元素名
#显示:元素名
结束
例如:
#scp
#这个例子脚本用来播放mp3文件
打开:目录,dir1,C:\mp3\
枚举:文件,dir1,allfiles
定义:函数,play,元素名称
运行:进程,C:\mp3player.exe,元素名称
结束
遍历:allfiles,play
表对象的高级运算
L脚本语言将针对表对象的并集、交集、差集运算映射为基本运算符+ & -
我们可以对表对象进行集合代数运算
例如
#scp
定义:字符串,str1,world
定义:字符串,str2,hello
定义:整数,int1,12345
定义:表,table1
定义:表,table2
定义:表,table3
定义:表,table4
定义:表,table5
插入:table1,str1
插入:table1,int1
插入:table2,str1
显示:差集运算
计算:table3=table1-table2
显示:table3
显示:------------------------------
插入:table1,str2
显示:并集运算
计算:table4=table1+table2
显示:table4
显示:交集运算
计算:table5=table1&table2
显示:table5
等待:用户输入,str1
L脚本语言支持用户自定义类,以支持面向对象的类型封装
语法格式为
定义:类,类的名字
define:class,name of class
公开:
定义:整数,成员变量,初始值
define:int,name of member,initialvalue
私有:
定义:字符串,成员变量字符串,初始值
define:string,nameof member,initial value
定义:函数,成员函数,成员函数参数
define:function,name of member function,formal parameters
结束
结束
类对象需要实例化以后方可使用,语法格式为
定义:类的名字,类实例的名字
类对象是可继承的
L脚本语言类对象不包含纯虚函数,因此没有成员函数的重载机制,但允许继承的新类增加成员变量和成员函数,实际上继承的新类是父类的一个完整拷贝,并允许在这个基础上进行扩充
类成员的引用
类定义中的成员变量默认是私有的,不可以直接访问,如果需要访问类的成员变量或成员函数,需要指明”公开”属性,在类定义时增加”公开:”命令之后定义的成员都会具有”公开”属性 ,增加“私有:”命令之后的成员都会有“私有”属性
允许调用类的成员函数,语法格式为
调用:类实例的名字:成员函数,成员函数参数
call:classinstancname:functionname,parameters
“调用”关键字可以省略
类实例的名字:成员函数,成员函数参数
classinstancename:functionname,parameters
L脚本语言支持自定义库以及库的导入机制,以最大程度的提供灵活性,并允许将自定义的函数注册为全局动作
库文件是只包含对象定义和函数定义的脚本文件
库文件必须以#scplib 为起始行
在库中定义的对象为全局用户对象和函数为全局用户函数
使用库时需要首先导入,语法格式为
导入:库,库文件的完整路径名
import:lib,full pathof libfile
普通用户函数调用时的格式为
调用:函数,函数的名称,函数的参数列表
call:function,functionname,realparameters list
注册为全局动作的函数就可以直接通过函数名来调用,语法格式为
注册:函数,函数的名称
register:function,functionname
函数:函数的参数列表
function:real parameters list
请参考例子代码
L脚本语言中,文件和目录都是内置对象
打开文件或目录的语句会返回一个文件对象,不需要定义
格式为
打开:文件,文件对象名,文件的完整路径名
open:file,name_of_file_object,full_path_of_file
打开:目录,目录对象名,目录的完整路径
open:directory,name of directory object,full path of diretory
如:
打开:文件,file1,c:\1.txt
open:file,file1,c:\1.txt
打开:目录,dir1,c:\
open:directiory,dir1,c:\
对文件对象支持的操作有 复制、移动、删除、取大小、读取、写入
文件操作的语法格式为
复制:文件,源文件名,目标文件名
copy:file,sourcefilename,destfilename
移动:文件,源文件名,目标文件名
move:file,sourcefile,destfile
删除:文件,文件路径名
delete:file,filepathname
取大小:文件,文件对象,保存文件大小的整数对象
getsize:file,name of file object,name of int object
写入:文件,文件对象,内存对象
write:file,name of file object,name of memory object
写入:文件,文件对象,字符串对象
write:file,name of file object,name of string object
获取:属性,文件对象,保存文件属性的表对象
get:attribute,name of file object,name of table object
插入:表, 保存文件属性的表对象,属性名称
insert:table,name of table object,attribute name
设置:属性,文件对象,文件的属性
set:attribute,name of file object,name of table object
获取:文件对象,创建时间,保存创建时间的time对象名(新建)
get:fileobject,createtime,name of timeobject(create new one)
获取:文件对象,修改时间,保存修改时间的time对象名(新建)
get:fileobject,modifytime,name of timeobject
获取:文件对象,访问时间,保存访问时间的time对象名(新建)
get:fileobject,accesstime,name of timeobject
获取: 文件对象,驱动器,保存驱动器的字符串
get:fileobject,drive,name of string object
获取: 文件对象,目录,保存目录的字符串
get:fileobject,path,name of string object
获取: 文件对象,文件名,保存文件名的字符串
get:fileobject,filename,name of string object
获取: 文件对象,扩展名,保存扩展名的字符串
get:fileobject,extension,name of string object
对目录对象支持的操作有 枚举目录中的文件 、枚举目录中的子目录 、复制、 移动、 删除
打开:目录,目录对象,目录的路径
open:directory,name of directory object,full path of directory
枚举:文件,目录对象,保存文件列表的表对象
enum:file,name of directory object,name of table object
枚举:子目录,目录对象,保存目录列表的表对象
enum:subdir,name of directory object,name of table object
显示:保存文件列表的表对象
show:tableobject
显示:保存目录列表的表对象
show:tableobject
复制:目录,源目录的路径,目标目录的路径
copy:directory,source directory,dest directory
移动:目录,源目录的路径,目标目录的路径
move:directory, source directory,dest directory
删除:目录,目录的路径
delete:directory,full path of directory
查找:文件,目录对象的名称,表对象的名称,正则表达式匹配规则
查找:文件,目录的路径,表对象的名称,正则表达式匹配规则
例如,查找目录下的所有文件(含子目录)
打开:目录,dir1,E:\ScriptEngine\ScritpEngine\Release\
定义:表,tableoffiles
#查找:文件,dir1,tableoffiles,(.)*scp
查找:文件,E:\ScriptEngine\ScritpEngine\Release\,tableoffiles,(.)*scp
显示:tableoffiles
L脚本语言内置了对访问Windows注册表的支持
打开一个注册表项会返回一个注册表对象,在这个对象上支持读取、写入、删除操作
语法格式为
打开:注册表,注册表对象名,注册表路径,值的名称
open:registry,nameof registry object,path of registery,key name
读取:注册表,注册表对象名,字符串对象名
read:registry, nameof registry object,name of string object
写入:注册表,注册表对象名,字符串对象名
write:registry, nameof registry object,,name of string object
删除:注册表,注册表对象名
delete:registry, nameof registry object
如
打开:注册表,reg1,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run,HttpServer
open:registry,reg1, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run,HttpServer
读取:注册表,reg1,string1
read:registry,reg1,string1
写入:注册表,reg1,string1
write:registry,reg1,string1
删除:注册表,reg1
delete:registry,reg1
L脚本语言中,时间对象的定义方式为
定义:时间,时间对象的名称
define:time,name of time object
可以将当前时间读取到时间对象中
读取:当前时间, 时间对象的名称
read:currenttime,name oftime object
时间对象可以通过比较运算符进行比较
如果想要让脚本在运行过程中等待一段时间,可以调用睡眠语句
睡眠:需要睡眠的毫秒数
sleep:millisecond
可以将时间对象的小时,分,秒读入到整数变量中
语法格式为
获取:时间对象名,时,整数变量名
get:timeobj1,hour,inthour1
获取:时间对象名,分,整数变量名
get:timeobj1,minute,intminute1
获取:时间对象名,秒,整数变量名
get:timeobj1,second,intsecond1
例如:
定义:时间,time1
define:time,time1
读取:当前时间,time1
read:currenttime,time1
显示:time1
show:time1
睡眠:1000
sleep:1000
定义:时间,time2
define:time,time2
读取:当前时间,time2
read:currenttime,time2
显示:time2
show:time2
如果:((time1<time2)||(time1==time2)),显示:"time1早于或等于time2"
test: ((time1<time2)||(time1==time2)),show:”time1early than or equal to time2”
目前L脚本支持TCP和UDP协议的网络访问,后台使用阻塞式socket实现
对网络的访问通过网络连接对象和地址对象完成
定义地址对象的格式为
定义:地址,地址对象的名称,IP(如127.0.0.1),端口号(如27015)
define:address,name of address object,IP,port
地址对象可以动态修改,语法格式为
设置:地址对象的名称,IP,新的IP地址字符串
设置:地址对象的名称,端口,新的端口
定义网络连接对象的格式为
定义:网络连接,网络连接的名称,TCP或UDP
define:netconnection,name of netconnection object,protocol type
针对网络连接对象的动作有监听,连接,发送,接收 格式为
监听:网络连接的名称,地址对象的名称
watch:netconnection object,addresobject
连接: 网络连接的名称, 地址对象的名称
connect:netconnection object,addressobject
发送: 网络连接的名称,字符串对象名
send:netconnectionobject ,stringobject
接收: 网络连接的名称, 字符串对象名
receive:netconnection object,stringobject
对于TCP和UDP,目前做了以下限制:发送和接收的数据包大小限制为小于等于32K
详细请参考例子代码
L脚本语言内置了对HTTP协议的支持,可以实现http客户端功能
语法结构如下
定义:HTTP连接,网站连接
define:httpconnection,httpconnection object name
获取:网站连接,URL地址,保存页面内容的字符串
get:httpconnectionobject,url address,string object
提交:网站连接,URL地址,保存提交内容的字符串,保存响应信息的字符串
post:httpconnectionobject,url address,submit content string,reponsestring
例如
定义:HTTP连接,网站连接
define:httpconnection,webconn
定义:字符串,页面Url
define:string,url
定义:函数,页面抓取
define:function,getweb
开始:函数,页面抓取
start:function,getweb
显示:请输入网站URL地址
show:”pleaser input url address”
等待:用户输入,页面Url
warit:userinput,url
获取:网站连接,http://www.126.com,页面Url
get: webconn, http://www.126.com,url
显示:页面Url
show:url
打开:文件,file1,c:\1.html
open:file,file1,c:\1.html
写入:文件,file1,页面Url
write:file,file1,url
结束:函数,页面抓取
end:function,getweb
当:1,调用:函数,页面抓取
while:1,call:function,getweb
定义:HTTP连接,网站连接
define:httpconnection,webconn
定义:字符串,页面Url,http://www.baidu.com
define:string,url,http://www.baidu.com
定义:字符串,表单数据,wd=123
define:string,forms,wd=123
定义:字符串,响应信息
define:string,response
提交:网站连接,页面Url,表单数据,响应信息
submit:webconn,url,forms,response
显示:响应信息
show:response
在程序中我们经常会用到随机信息
在L脚本语言中,随机数是一类对象,实际上是特殊的整数类型
使用方法为
生成:随机数,随机数对象的名称
generate:randomnumber, name of random number
刷新:随机数, 随机数对象的名称
refresh:randomnumber,name of random number
例如
生成:随机数,random1
generate:randomnumber,random1
显示:random1
show:random1
定义:整数,count,1000
define:int,count,1000
定义:函数,genrandom
define:function,genrandom
开始:函数,genrandom
start:function,genrandom
刷新:随机数,random1
refresh:randomnumber,random1
显示:random1
show:random1
计算:count=count-1
compute:count=count-1
结束:函数,genrandom
end:function,genrandom
当:count>0,调用:函数,genrandom
while:count>0,call:function,genrandom
如果我们想要在程序中启动外部程序,可以
运行:程序,进程的名称,进程可执行文件的路径名,启动参数
run:process,process object name,full path of process file,parameter
如果想要关闭已启动的外部程序,可以
关闭:程序, 进程的名称
shutdown:process,process object name
例如:
运行:程序,proc1,notepad.exe,c:\hello.txt
run:process,proc1,notepad.exe,c:\hello.txt
关闭:程序,proc1
shutdown:process,proc1
或者,如果我们知道某个进程的Pid,想要强制关闭它,可以
关闭:程序,保存进程pid的整数变量
shutdown:process,processpid
关闭:程序,保存进程名的字符串变量
shutdown:process,processname
关闭:程序,保存进程名的静态字符串值
shutdown:process,processname
如果我们想要枚举所有的进程(仅WINDOWS),可以
枚举:进程,表对象的名字,PID(可选参数,没有的话表对象中存储进程名)
enum:process,tableobjectname
注意,这个时候表对象必须已定义,例如
定义:表,tableofprocess
定义:表,tableofprocesspid
枚举:进程,tableofprocess
枚举:进程,tableofprocesspid,PID
显示:表,tableofprocess
显示:表,tableofprocesspid
L脚本内置了进程通信的支持,目前支持命名管道方式的双向通信和基于共享内存的进程间通讯
命名管道方式的进程间通讯语法格式为
打开:管道,管道对象名称,Windows管道名
写入:管道,管道对象名称,字符串名称
读取:管道,管道对象名称,字符串名称
关闭:管道,管道对象名称
例如
打开:管道,pipe1,\\.\pipe\mypipe1
open:pipe,pipe1, \\.\pipe\mypipe1
写入:管道,pipe1,string1
write:pipe,pipe1,string1
读取:管道,pipe1,string2
read:pipe,pipe1,string2
显示:string2
show:string2
关闭:管道,pipe1
close:pipe,pipe1
基于共享内存的进程间通讯语法格式为
定义:共享内存,共享内存对象名,共享内存标识,共享内存大小的字节数
打开:共享内存,共享内存对象名
读取:共享内存对象名,字符串对象名
写入:共享内存对象名,字符串对象名
关闭:共享内存对象名
例如:
#testsharemem1.scp
定义:字符串,str1,helloworld
定义:共享内存,sharemem1,"GSHAREMEM",1024
打开:共享内存,sharemem1
写入:sharemem1,str1
关闭: sharemem1
#testsharemem2.scp
定义:字符串,str1,helloworld
定义:共享内存,sharemem1,"GSHAREMEM",1024
打开:共享内存,sharemem1
读取:sharemem1,str1
关闭: sharemem1
显示:str1
L脚本支持多线程,允许在脚本中派生新的线程,以支持并发操作
语法格式为
定义:线程,线程的名称,线程函数
define:thread,nameof thread object ,thread function
运行:线程,线程的名称,线程函数的参数
run:thread,name ofthread object,parameters
在这里,线程函数就是线程执行体所执行的操作,这里和调用函数很相似,但是这个函数是在另一个线程中执行的
详细的使用方法可以参考例子代码
二十四、 与C/C++的交互
由于操作系统提供的API都是C语言的接口,为了实现功能扩展,L脚本语言也允许直接调用操作系统的C语言API函数
目前,仅支持函数调用约定为__stdcall 的C语言函数
C语言的变量和L脚本语言的对象不是一一对应的关系,因此调用C语言函数的时候不能直接将L脚本语言的对象作为参数传入,但是可以进行适当的转换
L脚本语言中目前实现了6种基本的C语言数据类型对象
C整数,C无符号整数,句柄,C字符指针,C宽字符指针,指针
对应的C语言数据类型为int ,unsigned int ,HANDLE, char*,wchar_t * ,void *
这里的句柄是指WINDOWS操作系统中的句柄类型HANDLE,指针是指C语言的无类型指针void *
在调用C语言函数之前需要进行适当的定义,格式为
定义:C函数,函数别名, 动态库文件,C语言函数原名,返回值类型,参数类型列表
例如
定义:C函数,MyOutputDebugStringW, c:\windows\system32\Kernel32.dll,OutputDebugStringW,无,C宽字符指针
定义:C函数,myMessageBoxW, c:\windows\system32\user32.dll,MessageBoxW,C整数,句柄,C宽字符指针,C宽字符指针,C无符号整数
调用C语言函数时需要传入适当的参数和返回值 格式为
调用:C函数, 函数别名,返回值,参数列表
例如
调用:C函数,myMessageBoxW,返回值,参数1,参数2,参数3,参数4
在其它编程语言中调用L脚本语言
L脚本语言允许被其它编程语言调用,只要在宿主语言中加载,L脚本引擎的动态库,直接调用这两个函数就可以了
extern "C" int __stdcall ScriptEngineDoString(wchar_t *ScriptString);
extern "C" int __stdcall ScriptEngineDoScriptFile(wchar_t* ScriptFileName);
C语言调用L脚本引擎的例子:
#include <windows.h>
#include "../ScriptEngineDll/ScriptEngineDll.h"
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hDLL =LoadLibraryW(L"ScriptEngineDll.dll");
if(hDLL)
{
FUNC_ScriptEngineDoStringScriptEngineDoString=(FUNC_ScriptEngineDoString)GetProcAddress(hDLL,"ScriptEngineDoString");
if(ScriptEngineDoString)
{
ScriptEngineDoString(L"重启:计算机");
}
}
return 0;
}
L脚本编写的命令行程序可以接收用户输入的字符串,语法格式为
等待:用户输入,保存输入内容的字符串
例如
定义:字符串,字符串1
等待:用户输入,字符串1
显示:字符串1
二十六、 调试支持与调试器使用
如果我们需要在脚本程序运行过程中查看函数调用堆栈的运行轨迹,我们可以调用:
显示:调用堆栈
这样脚本引擎就会把当前函数的调用堆栈打印出来
L脚本语言提供了一个简单的调试器,用来进行脚本源代码的调试,在调试器中打开文件后,选中行点击右键即可对代码行设置断点,点击调试按钮即开始调试过程,当脚本执行到设置了断点的行后就会中断下来,并在消息输出窗口中显示提示信息。再次右键点击已设置断点的行即可清除断点。
调试器也支持简单的调试命令
bp 行号 ,用来设置断点
bc 行号 ,用来清除断点
g ,调试运行脚本
sd ,单步调试脚本
s ,继续运行脚本
L脚本语言内置了一些密码学算法操作
如字符串加密解密(RC4) 求字符串哈希值(MD5)
内存对象加解密(AES)
语法格式为
加密:字符串名称,密钥字符串名称
encrypt:name ofstring object,name of key string
解密:字符串名称,密钥字符串名称
decrypt: name ofstring object,name of key string
求哈希:字符串名称,保存哈希值的字符串,哈希算法名称
hash: name ofstring object,hash value string name,algorithm
加密:内存对象名称, 密钥字符串名称
encrypt:name ofmemoryobject,name of key string
解密:内存对象名称, 密钥字符串名称
decrypt:name ofmemoryobject,name of key string
例如
加密:str1,str2
encrypt:str1,str2
显示:str1
show:str1
解密:str1,str2
decrypt:str1,str2
显示:str1
show:str1
求哈希:str1,str3,MD5
hash:str1,str3,MD5
定义:字符串,str1,"我是一个字符串"
定义:字符串,str2,"密钥"
申请:内存,mem1,1024
写入:mem1,str1
显示:mem1
加密:mem1,str2
显示:mem1
解密:mem1,str2
显示:mem1
释放:内存,mem1
利用L脚本语言内置的密码学算法机制,可以实现脚本内容的加密处理,以此实现算法保护
L脚本语言内置了标准zip格式数据压缩解压支持,可以实现对文件、目录压缩为zip包,或将标准zip包解压
语法格式为:
压缩:生成zip包的路径名 ,文件或目录列表
包含两个以上参数,第一个参数可以是常量字符串,或字符串变量,或文件对象最终解析的文件必须不存在
第二个参数和以后的参数可以是常量字符串,或字符串变量,或文件对象,或目录对象,最终解析的文件或目录必须存在
打开:目录,dirobj1,c:\dir1
打开:文件,fileobj1,c:\1.txt
压缩:c:\dir1.zip dirobj1
压缩:c:\dir1.zip c:\dir1
压缩:c:\file1.zip fileobj1
压缩:c:\file1.zip c:\1.txt c:\2.txt
解压: zip包的路径名 ,解压路径
包含两个参数,第一个参数可以是常量字符串或字符串变量或文件对象最终解析的文件必须存在
第二个参数可以是常量字符串或字符串变量或目录对象最终解析的目录如果不存在则创建
解压:c:\dir1.zip dirobj1
解压:c:\dir1.zip c:\dir1
定义:字符串,string1,c:\dir1.zip
定义:字符串,string2,c:\dir1
解压:string1,string2
L脚本语言支持中文或英文关键字的编程,通过#langeng 指令可以切换到英文模式,通过#langchs 指令可以切换到中文模式,默认为中文模式
目前L脚本语言支持windows和Linux两个平台的开发,Linux平台上目前提供有限的支持
L脚本语言中可以直接调用python代码,这样我们可以实现L脚本和python混合编程
在L脚本中,python代码是一个对象,声明一个python对象,就可以直接调用python的代码
语法格式为
定义:PYTHON,python对象名,python版本(3.4或2.7)
调用:PYTHON, python对象名,python代码字符串
调用:PYTHON, python对象名, python代码文件的全路径
例如
定义:PYTHON,pythonscript1,3.4
调用:PYTHON,pythonscript1,"print('hello')"
调用:PYTHON,pythonscript1,H:\scriptengine\ScritpEngine\Release\pyemb7.py
L脚本语言内置了一些基本的图形对象,以支持图形化的编程
画布对象是一个窗体,在上面可以进行图形元素的绘制
目前支持在画布对象上绘制矩形、椭圆
语法格式为
定义:画布,画布对象的名称
define:canvas,nameof canvas object
显示: 画布对象的名称
show: name ofcanvas object
画:矩形, 画布对象的名称,左上角横坐标,左上角纵坐标,宽度,高度
draw:rect, name ofcanvas object,xpos ,y pos ,width,height
画:椭圆, 画布对象的名称,左上角横坐标,左上角纵坐标,宽度,高度
draw:elipse, nameof canvas object,xpos ,y pos ,width,height
L脚本语言内置了对sqlite数据库访问的接口,可以直接访问sqlite数据库
语法格式为
定义:数据库,数据库对象的名称,数据库对象的类型(目前仅包含sqlite)
定义:数据集,数据集对象的名称,关联的数据库对象名称
打开:数据库对象的名称,数据库文件的路径
执行:SQL,数据库对象的名称,保存错误信息的字符串,sql语句的内容
执行:SQL,数据集对象的名称, 保存错误信息的字符串, sql语句的内容
获取: 数据集对象的名称,字段值,1,保存字段值的字符串对象名称
获取: 数据集对象的名称,字段名,1, 保存字段名的字符串对象名称
移动: 数据集对象的名称,下一行
判断数据集是否已经到达结束位置的方法为
如果:recordset!=DBEOF
下面是一个数据库访问的例子脚本
#scp
定义:数据库,db,sqilte
定义:数据集,recordset,db
定义:表,table1
定义:字符串,error
定义:字符串,fieldname
定义:字符串,fieldvalue,ccc
定义:整数,id,3
定义:字符串,strsql
定义:整数,end
定义:函数,主函数
打开:db,C:\test.db
执行:SQL,db,error,"drop table user"
显示:error
执行:SQL,db,error,"create table user(idint,name char(32))"
显示:error
执行:SQL,db,error,"insert into user VALUES(1,'aaa')"
显示:error
执行:SQL,db,error,"insert into user VALUES(2,'bbb')"
显示:error
格式化:字符串,strsql,"insert into user VALUES (%s,'%s')",id,fieldvalue
显示:strsql
执行:SQL,db,error,strsql
显示:error
执行:SQL,db,error,"select * from user"
显示:error
执行:SQL,recordset,error,"select * fromuser"
显示:error
当:recordset!=DBEOF
获取:recordset,字段值,1,fieldvalue
获取:recordset,字段名,1,fieldname
显示:fieldname
显示:fieldvalue
移动:recordset,下一行
结束
关闭:db
结束
三十四、 XML文件
我们在编程中经常会用到XML文件来作为配置文件或进行数据交换
在L脚本语言中,XML也是一个内置的对象
访问 XML对象的语法格式如下
定义:XML,XML对象的名称
打开: XML对象的名称, XML对象的路径名
设置: XML对象的名称,属性,节点路径,属性名称,属性值
获取: XML对象的名称,属性,节点路径, 属性名称, 属性值
设置: XML对象的名称,值, 节点路径, 节点值
获取: XML对象的名称,值, 节点路径, 节点值
在这里,节点路径是类似文件系统的目录路径,以”\”分隔节点,如果某个节点是数组形式,那么用数组下标的方式选择访问数组中的哪一个元素,下标采用类C语言语法,从0开始
例如:
#scp
定义:XML,xml
打开:xml,c:\4.xml
设置:xml,属性,book,price,100
设置:xml,属性,book,pagecount,45
定义:整数,num1
定义:整数,num2
获取:xml,属性,book,price,num1
获取:xml,属性,book,pagecount,num2
定义:字符串,书名,C++编程语言
设置:xml,值,book,书名
定义:字符串,str1
获取:xml,值,book,str1
显示:str1
显示:num1
显示:num2
显示:xml
保存:xml
关闭:xml
打开:xml,c:\5.xml
获取:xml,属性,books\mybook[0]\yourbook[0],price,num2
显示:num2
获取:xml,属性,books\mybook[1]\yourbook[1],price,num2
显示:num2
计算:num2=777
设置:xml,属性,books\mybook[1]\yourbook[1],price,num2
显示:num2
显示:xml
保存:xml
关闭:xml
JSON和XML一样是常用的程序配置文件和数据交换格式
L脚本语言中也支持对JSON的访问
语法格式如下:
定义:JSON,json对象名
打开:json对象名,json文件的全路径
显示:json对象名
获取:json对象名,值,一个JSON键值对的键名称,字符串对象名
设置: json对象名,值,一个JSON键值对的键名称,字符串对象名
例如
#scp
定义:JSON,json
打开:json,"E:\ScriptEngine\ScritpEngine\EasyJson\good\3.json"
#显示:json
定义:字符串,string1
定义:字符串,string2,"66666"
获取:json,值,"key",string1
显示:string1
获取:json,值,"value",string1
显示:string1
设置:json,值,"value",string2
获取:json,值,"value",string1
显示:string1
等待:用户输入,string1
为方便进行系统管理,L脚本提供了一些内置的全局对象
如 计算机 是当前运行脚本的宿主机器
我们可以通过脚本来对本机进行控制
关闭:计算机
shutdown:computer
重启:计算机
reboot:computer
挂起:计算机
suspend:computer
L脚本运行环境初始化之后会创建一个名为”命令行参数”的表对象,我们通过这个表对象可以访问脚本的命令行参数,这样我们就可以编写带参数的脚本,例如
定义:整数,参数个数,0
定义:整数,index,0
取大小:命令行参数,参数个数
当:index<参数个数
显示:命令行参数[index]
index+=1
结束