-
开发思路
-
-
总体开发思路
代码解析,需要考虑的问题是(目前已经实现了70%左右的功能)
-
代码片段的内在结构,识别代码片段中所存在的对象元素,系统根据不同的对象元素的分类能快速执行相应的处理程序,将处理的结果进行传递
-
将处理过程进行缓存,保留代码逻辑层面必要的数据信息,考虑数据的作用范围
-
批处理规则,让系统知道如何根据相应的条件与规则执行处理相应的脚本语句对象
-
文件函数的调用,系统判断出对象为函数还是引用外部的文件等等,如何加载资源对象,同步异步锁机制,参数的规则约束校验,如何响应调用方式
-
代码规则与抽象化,动态的注册外部代码规则,提高系统的可扩展性,以及在不同规则之间切换代码表示形式
-
-
开发细节
-
代码中的脚本对象
-
值Value
无名称,值的是存储在物理内存中的一块编码信息,只能通过变量名称来访问,无法直接通过脚本构造,如果一个值没有被变量引用,则被系统当自动回收清理。
值可以是基本类型,也可以是引用类型
在C#中值的类型包括system.int32,system.boolean,system.string,system.double,system.object
其中引用类型引用的是一个对象的地址,Value值就是一个地址
<Value value={Value} type={类型}/>
-
-
-
-
变量Var
储存值的容器,有一个ID名称,规定了值的生命周期
属性:变量名称(string),变量值(object),变量的类型(自定义基本类型,扩展类型)
<Var:Value name="a" value={Value} type={类型}/>
<Array:Var name="a" value={List<Value>} type={类型} length = {数组长度} />
<Object:Var name="a" value={ref System.object} type={类型} Propertys={实例属性VarSpace}/>
VarName,返回该变量的value
ArrayName[Index],返回该变量value第Index的值(该方法在Array操作中实现)
VarName.MethodName(Param1,Param2...)
VarName.PropertyName
根据变量名VarName找到VarSpace中的变量,如果变量是一个Object,则根据其类型type查找对应的类,然后根据MethodName/PropertyName查找类中声明的方法属性成员并调用,将参数变量依次传递到对应的方法接收参数中;如果属性为实例属性,则使用对象Propertys中的属性变量,在调用实例方法时,实例方法中引用的实例变量使用实例的属性,静态变量使用类的属性(该方法在Object操作中实现)
-
-
-
-
类型
有些编程语言不需要类型的定义,类型就是类对象的名称
但是在运行时中每个对象都有各自的类型,系统根据不同的变量类型进行相应的计算
属性:类型类型(基本类型,对象类型),类型名称(类型定义所在资源的路径,通过类型名称确定变量与资源的对应关系)
<VarType name = "string" fullname = "System.String">
<VarType name = "Object" fullname = "Math.Randon...">
-
-
-
-
代码行
规定了变量之间如何进行处理,运算,调用函数,赋值
如果代码块出现throw 则表示抛异常,
代码行不存储变量,代码行的定义的变量传递給所在的代码块。
<Codeline:CodeBlock type = {normal|throw|break|return} content = {codeExpress}>
当type为normal时,有codeExpress,codeExpress可以为空,表示不做任何操作
当type为throw时,不继续执行下面的代码行,将异常参数传递并跳转到父层的tryCatch代码块的catch,按照tryCatch的规则继续执行
当type为break,不继续执行下面的代码行,跳转到父层,根据父层代码块的规则继续执行
当type为return,将参数返回到方法的输出,并结束方法
-
-
-
-
代码块
装载代码行的容器,代码块内部定义的变量,只能在内部引用,不能传递到代码块外部,但是代码块运行规则可以规定代码块的执行顺序以及变量的传递规则
当引用一个变量时,程序查找在当前作用域空间中此时的变量值
属性,变量空间:存放当前代码块定义的变量 content,代码行或者子代码块
<CodeBlocks VarSpace={变量空间,存放内部定义的变量}>
<CodeLine>
<CodeLine>
<CodeLine>
<CodeBlocks>
<CodeBlocks>
<CodeBlocks/>
-
-
-
-
代码块运行规则定义,都继承代码块
规定了代码行的运行规则,默认从上到下,如果遇到了不同的规则定义则按照指定的规则执行代码块
-
-
-
-
-
顺序执行
<CodeBlocks >
<CodeBlocks.body>
<Codeline/>
<Codeline/>
<Codeline/>
<CodeBlocks/>
</CodeBlocks.body>
<CodeBlocks>
顺序代码块,依次执行代码行
-
-
-
-
-
条件执行
<ifElse:CodeBlocks condition={Codeline|CodeBlocks , 需要返回一个bool类型的参数的代码行或代码块} >
<if:CodeBlocks condition body>
<elseif:CodeBlocks condition body>
<elseif:CodeBlocks condition body>
<else:CodeBlocks body>
</ifelse>
条件代码块,先执行ifElse.condition,如果返回true,则执行IF.body,如果返回false且if后面无其他代码块,则直接退出;如果依次执行后面有elseif/else,else条件,如果elseif的condition=true,则执行对应的Body,执行完后退出ifelse,否者继续执行下一个CodeBlocks,
如果是elseif且condition为false继续往下执行,否者执行对应的Body,执行完后退出ifelse,依次类推,最后一个else无condition,直接执行Body,然后退出
<Switchcase condition = {[switchcase条件执行,返回一个枚举或变量值] default={CodeBlocks}>
<case:CodeBlocks comparseValue={值}/>
<case:CodeBlocks comparseValue={值}/>
<case:CodeBlocks comparseValue={值}/>
<default:CodeBlocks/>
</Switchcase>
-
-
-
-
-
循环执行
<CodeBlocks type={[循环]} startCode={Codeline|CodeBlocks} condition={Codeline|CodeBlocks , 需要返回一个bool类型的参数的代码行或代码块} interval={代码块对初始条件的一个处理,无返回参数} >
<Codeline/>
<Codeline/>
<Codeline/>
<CodeBlocks/>
<CodeBlocks>
循环代码块,先执行startCode,在执行condition,如果返回true,则执行body ,执行完body后,执行interval ,再执行condition,一直运行,直至condition返回false退出循环
特别的,对于for循环,按照以上规则,
对于do{}while(condition)循环,没有startCode和interval,直接执行body,再执行condition,如果返回true,则继续执行body ,否者退出
对于while(condition)(condition) 先执行condition 如果返回true,则继续执行body ,否者退出
捕获异常
<TryCath try={Codeline|CodeBlocks} catch={Codeline|CodeBlocks}>
先执行try,如果出现异常,则将异常信息传递给catch代码块并执行
-
-
-
-
方法Method
指的是对不同地方声明的代码块进行引用,一个方法归属于一个类,相当于对一个代码块的注册,外部系统通过类名和方法名就能访问已定义的代码块
<Method:CodeBlocks name = "方法名称" 作用域={私有,公有} belong={类/实例} Input= {传入的有序参数},Output={传出的有序参数} body={CodeBlocks}/>
<Method:CodeBlocks>
属性相当于一种特殊的方法
-
-
-
-
属性Property
属性属于被注册的变量,归属于类或其实例。一般变量在代码块定义之后,退出代码块,该变量就被清空,但是如果变量被注册到一个类中,则不会被清空,只有当类对象声明所在代码块运行结束后则跟着类对象一起被清空,如果属性是静态变量,属性属于类,而不属于实例,这样,即使实例被清空,静态属性也不会被清空,不能直接调用类的实例成员,由于实例方法中包含实例的属性,因此不能通过类调用实例方法,也不能在静态方法中调用实例成员。
<Property:Val name="属性名" value={Val} type={类型} scope={作用域} belong={类/实例}/>
作用域:全局变量局部变量,作用域确定了哪些类成员可以暴露给外部使用
变量归属:确定变量是实例变量还是类变量,
实例属性只是在类中进行声明,其值不会保存到类中,而是保持到类的实例Propertys中
静态属性保存在类中
-
-
-
-
类
类是对方法和属性的分组,便于分类管理和使用
<Class name = "类名" Inherit={基类} 作用域={私有,公有} belong={命名空间}>
<Methods>
</Methods>
<Propertys>
</Propertys>
<Class>
-
-
-
-
命名空间
命名空间是对类的分组,一个命名空间一般规定了系统的一套功能,通过命名空间,大致就知道程序集实现了什么
-
-
-
-
变量空间
指一个代码块在运行过程中通过赋值语句声明的变量集合,在同一个代码块的body中,处于后面的代码块可以访问修改前面定义的变量,代码块可以规定哪些子代码块可以被后续运行的代码块引用;跳出子代码块后,子代码块中声明的变量被删除,通过return访问的变量值则被父层代码块的变量接收
-
-
-
-
运算规则
运算规则确定对不同类型的输入变量如何进行处理,以及对处理结果的传递,操作对象为变量
所有操作都继承至Operation
-
-
-
-
-
变量定义VarDefine
创建一个变量
<VarDefine varName="{变量名}" type="变量类型" var={变量表达式}>
当未对变量赋值时var为null,否则执行Assign,将var计算的值存储到变量空间
-
-
-
-
-
赋值Assign
对变量进行赋值
关键字=,有两个输入变量,将右侧变量表达式计算的值传递给左侧变量
<Assign target = {有序VarSpace} source= {变量表达式}></Assign>
数组赋值,将变量表达式返回List,依次传递给数组变量
多目标赋值
[变量A,变量B] = sort(rand(1,2))
方法返回多个参数,将参数依次传递给变量A,B
C= sort(rand(1,2))
方法返回多个参数,但只有一个接收变量
接收变量必须是长度为2的数组,如果数组未定义,则构造一个长度为2的数组,将方法返回值覆盖数组值
定义一个变量,然后给变量赋值
a = sin(30);
<Assign target = {变量名a} source = {变量表达式 sin(30)}></Assign>
判断变量名是否存在,如果不存在,根据right计算出的变量构造一个变量,储存在当前代码块的变量空间中
-
-
-
-
-
Operation操作符+ - * / %,类型转换
对变量进行运算,包括基本类型运算,操作符的重载
<Operation type = 'add|minus|times|divide|heavyload|remain|method' Input={子操作List} result={变量}>
将Input的操作结果使用type规则进行处理,处理后传递给result
属性,type操作类型,source=待操作的变量List ,result 操作后的变量List
<Operation type="opposite"/>
为取相反数,将右侧的操作结果值取反,然后传递给左侧相加
<Operation type ='add' value={}>
将value的值
多重操作,为操作的容器,操作容器定义了操作的运行顺序
<Operations return>
<Operation/>
<Operation/>
<Operation/>
</Operations>
特别的,如果变量没有进行任何操作
<Var value={object}>也代表一种操作,直接将变量值返回
-
-
-
-
-
占位操作Present
占位操作是在解析表达式时表达式未完全解析当前的操作,此时操作用占位操作取代
仅当操作
-
-
-
-
解析案例(说明,以下是简化的XML,用于表示对象实体的结构)
b=3+4+5+pow(30,a+1)+a^2-1*(-1+3)
<Assign target = {变量b}>
<Add>
<Var:Operation value=3>
<Var:Operation value=4>
<Var:Operation value=5>
<Method:Operation Input = {传入变量List} methodname ={方法对象}>
<Var value=30>
<Add>
<Var:Operation value=a>
<Var:Operation value=3>
</Add>
</Method>
<Power:Operation>
<Var value={a}>
<Var value=-1>
</Power>
<Opposite:Operation/>
<Times:Operation>
<Var:Operation value=1>
<Add:Operation>
<Var value=-1>
<Var value=3>
</Add>
<Times>
<Add>
</Assign>
连续赋值
a=b=[12,3,4,c=5]
<Assign target={变量a}>
<Assign target={变量b}>
<Array length = 4>
<Value 12>
<Value 3>
<Value 4>
<Assign target={变量c}>
<Value 5>
</Assign>
</Array>
</Assign>
</Assign>
重置优先级
(3+4-v)*b+3>4?1:2
<IF>
<GT>
<Add>
<Times>
<Add>
<Value 3/>
<Value 4/>
<Minus val={变量v}/>
</Add>
<Val b/>
</Times>
<Value 3/>
</Add>
<Value 4/>
</GT>
<Var 1/>
<Var 2/>
</IF>
代码块
操作的集合
a = 3;
a++;
b=[1,2,3];
v = a+b;
print(v);
<Squence:CodeBlocks>
<Assign targrt={变量a}><Value 3></Assign>
<SelfAdd target={变量a}/>
<Assign target={变量b}><Array [1,2,3]></Assign>
<Assign target={变量v}>
<Add>
<Val a>
<Val b>
</Add>
</Assign>
<Method name ="print" >
<Val v>
</Method>
</Squence>
循环语句
s=[]
for(i = 0;i<3;i++)
{
for(j=0;j<3;j++)
{
s.push(i+j);
}
}
<Assign target={变量s}><Array/></Assign>
<For:CodeBlocks>
<For.startCode:Squence>
<Assign target={变量i}>0</Assign>
</For.startCode>
<For.Conditione:Squence>
<LT>
<Var i>
<Value 3>
</LT>
</For.Condition>
<For.Interval:Squence>
<SelfAdd target={变量i}/>
</For.Interval>
<For.body:Squence>
<For:CodeBlocks>
<For.startCode:Squence>
<Assign target={变量j}>0</Assign>
</For.startCode>
<For.Conditione:Squence>
<LT>
<Var j>
<Value 3>
</LT>
</For.Condition>
<For.Interval:Squence>
<SelfAdd target={变量j}/>
</For.Interval>
<For.body:Squence>
<Method type="实例方法" instance = {变量a} Method = "{方法对象}">
<Add>
<Val i>
<Val j>
</Add>
</Method>
</For.body>
</For>
</For.body>
</For>
-
-
-
生成解析结构
生成解析结构的目的是为了让程序快速运算,而不用每次重新解析代码文本
-
-
-
-
类型声明
相当于声明一个类,需要声明类的结构
属性声明
<Property name value{get set}>
方法
<Method name body={代码片段}>
<TypeDefine definetype="class" name = "类名" fullname={全名称}>
<Property>
{变量列表}
</Property>
<Method>
</Method>
</TypeDefine>
-
-
-
-
解析状态
Init
发现一个单词
发现=
发现一个单词
发现句子结束
b=3+4+5+pow(30,a+1)+a^2-1*(-1+3)
b |
Squence |
Squence.content |
<Val b> |
Val |
出现变量 |
b= |
Val |
<Val b> |
<Assign target=b> </Assign> |
Assign |
出现赋值标识符 |
b=3 |
Assign |
Assign.Content |
<Value 3> |
Value |
出现变量或数字 |
b=3+ |
Value |
<Value 3> |
<Add> <Value 3> </Add> |
Add |
出现加号 |
b=3+4 |
Add |
Add.NextChild |
<Value 4> |
Value |
出现变量或数字 |
b=3+4+ |
Value |
Value.parent==Add? |
Add |
Add |
出现加号 |
b=3+4+5 |
Add |
Add.NextChild |
<Value 5> |
Value |
出现变量或数字 |
b=3+4+5+ |
Value |
Value.parent==Add? |
Add |
Add |
出现加号 |
b=3+4+5+pow |
Add |
Add.NextChild |
<Value pow> |
Value |
出现变量 |
b=3+4+5+pow( |
Value |
<Value pow> |
<Method pow> |
Method |
出现( |
b=3+4+5+pow(30 |
Method |
<Method pow> |
<Method pow> <Value 30> <Method> |
Value |
出现变量或数字 |
b=3+4+5+pow(30, |
Value |
Value.parent==Method? |
Method |
Method |
出现, |
b=3+4+5+pow(30,a |
Method |
Method.NextChild |
<Value a> |
Value |
出现变量或数字 |
b=3+4+5+pow(30,a+ |
Value |
<Value a> |
<Add> <Value a> </Add> |
Add |
出现加号 |
b=3+4+5+pow(30,a+1 |
Add |
Add.NextChild |
<Value 1> |
Value |
出现变量或数字 |
b=3+4+5+pow(30,a+1) |
Value |
Value.parent==Method? |
Method |
Method |
出现) |
b=3+4+5+pow(30,a+1)+ |
Method |
Value.parent==Add? |
Add |
Add |
出现加号 |
b=3+4+5+pow(30,a+1)+a |
Add |
Add.NextChild |
<Value a> |
Value |
出现变量或数字 |
b=3+4+5+pow(30,a+1)+a^ |
Value |
<Value a> |
<Power> <Value a> </Power> |
POW |
出现^ |
b=3+4+5+pow(30,a+1)+a^2 |
POW |
POW.NextChild |
<Value 2> |
Value |
出现变量或数字 |
b=3+4+5+pow(30,a+1)+a^2- |
Value |
Value.parent==Add? Add.NextChild |
<oppsite> |
Add |
出现- |
b=3+4+5+pow(30,a+1)+a^2-1 |
Add |
Add.NextChild |
<Value 1> |
Value |
出现变量或数字 |
b=3+4+5+pow(30,a+1)+a^2-1* |
Value |
<Value 1> |
<Times> <Value 1> </Times> |
Times |
出现* |
b=3+4+5+pow(30,a+1)+a^2-1*( |
Times |
Times.NextChild |
<Fisrt> |
Fisrt |
出现( |
b=3+4+5+pow(30,a+1)+a^2-1*(- |
Fisrt |
<Fisrt> |
<Fisrt> <oppsite> <Fisrt> |
Fisrt |
出现- |
b=3+4+5+pow(30,a+1)+a^2-1*(-1 |
Fisrt |
Fisrt.NextChild |
<Value 1> |
Value |
出现变量或数字 |
b=3+4+5+pow(30,a+1)+a^2-1*(-1+ |
Value.parent ==Add |
<Value 1> |
<Add> <Value 1> <Add> |
Add |
出现加号 |
b=3+4+5+pow(30,a+1)+a^2-1*(-1+3 |
Add |
Add.NextChild |
<Value 3> |
Value |
出现变量或数字 |
b=3+4+5+pow(30,a+1)+a^2-1*(-1+3) |
Value |
Value.parent==First? |
- |
First |
出现) |
代码部分:
略
效果展示
<Squence>
<Assign targetName='a'>
<Value value = '1' type='number'/>
</Assign>
<Assign targetName='b'>
<Add>
<Value value = '1' type='number'/>
<Val name ='a'/>
</Add>
</Assign>
</Squence>
<Squence>
<Assign targetName='a'>
<Add>
<Value value = '3.2' type='number'/>
<Value value = '4' type='number'/>
<Method name='sin'>
<Value value = '40' type='number'/>
<Add>
<Val name ='a'/>
<Value value = '1' type='number'/>
</Add>
</Method>
<Opposite/>
<Power>
<Val name ='a'/>
<Value value = '2' type='number'/>
</Power>
<Opposite/>
<Times>
<Value value = '1' type='number'/>
<Priority>
<Opposite/>
<Add>
<Value value = '1' type='number'/>
<Value value = '3' type='number'/>
</Add>
</Priority>
</Times>
</Add>
</Assign>
<Assign targetName='b'>
<Value value = '45' type='number'/>
</Assign>
<Assign targetName='b'>
<Add>
<Value value = '3' type='number'/>
<Value value = '4' type='number'/>
<Value value = '5' type='number'/>
<Method name='pow'>
<Value value = '30' type='number'/>
<Add>
<Val name ='a'/>
<Value value = '1' type='number'/>
</Add>
</Method>
<Power>
<Val name ='a'/>
<Value value = '2' type='number'/>
</Power>
<Opposite/>
<Times>
<Value value = '1' type='number'/>
<Priority>
<Opposite/>
<Add>
<Value value = '1' type='number'/>
<Value value = '3' type='number'/>
</Add>
</Priority>
</Times>
</Add>
</Assign>
</Squence>