表达式求值

YRE在运行的过程中会遇到需要对上下文中的变量进行运算的情况,最常见的就是Yuriri脚本逻辑中含有在编译阶段无法完成常数折叠的参数表达式,例如含有变量值的参数值表达式等,这些变量的值必须等到运行时阶段才能确定,因此YRE提供了一个公共的表达式求值接口来提供将结构化字符串作为表达式运算的服务。

表达式求值器

YRE为上下文提供了表达式求值器的统一接口:IEvaluator,它声明了运行时环境做表达式求值时的函数接口。通过实现该接口,YRE可以根据需求实现不同的求值器实体类,为不同类型的表达式提供求值服务。
注意到这里的求值服务不一定是数学意义上的解析式运算,它也可能是进行一次函调调用、一次前端渲染等等。总而言之,YRE中的表达式求值的本质就是把字符串当做可执行源代码
IEvaluator所声明的接口如下:

函数名 作用
Evaluate 关于指定的上下文,计算字符串表达式的值
EvaluateBoolean 关于指定的上下文,计算字符串表达式的真值

逆波兰式求值器

目前YRE提供了逆波兰式求值器PolishEvaluator,它用于计算Yuriri脚本中参数表达式。在编译阶段,Yuri Interpreter已经将表达式的AST构造成了逆波兰表达式字符串,逆波兰式求值器PolishEvaluator将会解析这个字符串,在给定的上下文中做求值动作。
逆波兰式求值器首先扫描串一次,依据逆波兰式的分割字符(在Yuri-IL中是采用一个空格)将串分割为多个子项,然后利用正则匹配,将这些子项分类成常数项、字符串、变量和运算符,并将字符串里这些类别的对象转化为对应的运行时环境格式,例如字符串"233"将被解析成8字节大小的System.Double类型的值类型变量,值为233。随后, 求值器会用一个栈来把这些项目做运行时常数折叠,即依照这样的逻辑来进行求值:

  • 扫描逆波兰式子项向量,压到栈中
  • 如果当前栈顶是操作符就根据操作符的目数弹栈,例如遇到操作符+,是一个二目操作符,将导致操作栈弹栈两次。如果出栈序列是B A,那么对应的求值处理逻辑就是A + B
  • 如果求值过程中出栈是操作数是一个变量,那么就到给定的上下文中使用Fetch方法取得它的值
  • 当所有的子项都处理完毕之后,返回匹配栈的栈顶(同时也是唯一的栈帧)。如果栈帧数量不是1,或者运算所引用的变量没有作为过左值,或者操作数不能做折叠(例如数字除以字符串),YRE将抛出错误并强制结束游戏。

程序集信息

Property Value
层次结构 Yuri.PlatformCore.Evaluator.IEvaluator
最低版本 1.0
并行安全 -
层次结构 Yuri.PlatformCore.Evaluator.PolishEvaluator
最低版本 1.0
并行安全