VirtualMath是基于C语言实现的动态强类型解释形编程语言,使用VirtualMathCore解释器解释执行。
项目分为两部分:
VirtualMathCore是VirtualMath核心,包括parser文本解析器和vm运行器。VMHello是使用VirtualMathCore的可视化编程工具,使用基于命令行模式。
使用cmake生成项目Makefile文件后使用make和make install工具进行编译和安装。
cmake支持参数包括:
GC,默认为ON状态表示编译GC模块,否则不编译GC模块SET_DEBUG,默认为ON状态,表示以Debug的形式编译代码。PG,默认为OFF状态,ON表示编译时为编译器和连接器添加-pg参数,并且将代码编译为静态库。
VirtualMath支持如下命令行参数:
-n --not-run-cl 不进入command line模式
--stdout xxx 指定标准输出的位置
--stderr xxx 指定标准错误的位置
--stdin xxx 指定标准输入的位置
-l --locale 设置本地化选项
注意以上设定的标准输入\输出\错误的位置只适用于解释器所运行的VM代码。
命令行参数末尾的单独参数被解释为vm文件名,将交由VirtualMathCore逐一解释执行。
若未使用-n选项,则运行完文件代码后会自动进入command line模式。
支持字面量数字和字面量字符串
10
20.3
"Hello"
'World'
注意,字符串暂不支持转义字符串。
注意,解析器允许使用小数但VirtualMathCore仅支持整数。
VirtualMath支持使用字面量后缀。
如,123i等价于i(123)。关于函数调用将会在后面详细说明。
VritaulMath变量分为普通变量和超级变量。
普通变量名(标识符)由下划线或字母开头,仅包含下划线、字母和数字的字符组成,且为非关键词。
_
_a
a_
_23
a23
a_23
以上均为合法变量名
23a
23_
if
以上为非法的变量名
超级变量由$开头后跟表达式,如:
$10
$(20 + 30)
因此,VirtualMath允许使用数字等其他类型的数据作为变量名。但其访问时必须使用$符号。
关于$的优先级:
$20+30 等价于 ($20) + 30
通过$(xxx)获取超级变量的值的时候,分为二种情况。
-
$(xxx)的值存在,则直接返回该变量值。如:$(10) = 20 print($(10)) # 20 -
$(xxx)的值不存在,则直接返回xxx。如:print($(10)) # 10
可以通过设定解释器参数的方式来改变这种行为,具体将在后面介绍。
VirtualMath支持如下运算:
索引,切片,函数回调,成员运算(.和->)
加法、减法
乘法,除法,整除,幂
大于,大于或等于,小于,小于或等于,等于,不等于
位与,位或,按位异或,按位取反,左移,右移
布尔和,布尔或,布尔非
10 + 20
20 + 30
"Hello" + " World"
100 - 200
500 - 100
10 * 30
5 / 4
"Hello" * 3
a = 10
b = 20
20 = 30
$(20) = 30
其中20 = 30是等价于$(20) = 30的,也许会引起一些争议,但别紧张你会习惯的。
同时,还有特殊类型的赋值语句:
a[2] = 10
a[2:3] = z
注意,该赋值并非$(a[2]) = 10,这种赋值方式需要对象尊需一定协议才可使用,具体在后面将会介绍。
同时,也支持如下赋值语句:
f(x, y) = x * y
注意,以上语句并不等价于$(f(x, y)) = x * y,他其实是一种简单地函数定义,等价于:
def f(x, y){
return x * y
}
关于函数定义将在后面介绍。
do {
} if (xxx) {
} elif (xxx) as f{
} do{
} elif (xxx) {
} else {
} finally{
}
语句自上而下执行,遇到do语句会直接执行do语句内的代码并且继续执行。遇到if或者elif分支则会判断条件,然后赋值结果,再执行内部代码块,然后调准到finally分支。finally分支是条件分支离开前必然会执行的,即便条件分支内发生错误(VirtualMathCore或HelloVM的错误除外)。
do{
# 循环前执行一次
} while (xxx) as f{
} do {
# 每次循环后执行一次(break除外)
} else {
} finally{
}
else分支只有当while中的条件为false的时候才会执行。当循环体内使用了break语句跳出循环的时候else不会执行。
do {
} for i in a{
} do {
} else {
} finally {
}
for循环的do分支和while循环类似。else分支只有当迭代结束的时候才会执行。当循环体内使用了break语句跳出循环的时候else不会执行。
do while (xxx) as f{
} do {
} else {
} finally {
}
该循环并没有将条件判断后置,而是对首次条件判断的结果忽略并且设定为True。
try {
} except {
} except as e{
} except xxx {
} except xxx as e {
} else {
} finally {
}
with xxx {
} else {
} finally {
}
with xxx as f{
} else {
} finally {
}
VirtualMath还有很多特性,可自行探索。