函数与重要宏定义
在本章中,您将会学习到:
- 定义一个 SonolusApi 函数
- 使用 IF/FOR/WHILE 语句块
函数定义
Sonolus 的引擎数据本身是由 json 来进行编写的,可读性非常差,这就需要 Sonolus.h 或 Sonolus.js 来辅助您将 C/C++ 或 JavaScript/TypeScript 的代码转为机器可读的 json 代码。
为了使您所编写出来的代码更具现代高级语言的风格,我们采用了侵入式写法,这导致了 Sonolus.h 中函数的定义方法不同于正常 C/C++ 函数的定义方法。
下面是基本的 C/C++ 函数的定义方法与 Sonolus.h 函数的定义方法。
int add(int a, int b) {
return a + b;
}
void add2(int a, int b) {
cout << a + b << endl;
return;
}
SonolusApi add(let a, let b) {
FUNCBEGIN
Return(a + b);
return VAR;
}
SonolusApi add2(let a, let b) {
FUNCBEGIN
Debuglog(a + b);
return VOID;
}
首先,只要是 Sonolus.h 的函数定义,返回值类型都必须是 SonolusApi
;并且函数的第一行一定是 FUNCBEGIN
来表明这是一个 Sonolus.h 的函数定义。
接下来看具体实现上的差别。首先,关于有返回值的函数,在 C/C++ 中直接使用 return
返回就行了。而在 Sonolus.h 的函数定义中,您需要先使用 Return(num)
函数返回这个函数的返回值,最后在函数的最后一行使用 return VAR;
来表明这是一个有返回值的函数。
其次,关于无返回值的函数,在 C/C++ 中直接 return;
结束就行了,而在 Sonolus.h 的函数定义中,在最后一行使用一个简单的 return VOID;
表明没有返回值就行了。
请注意,在 Sonolus.h 函数定义中, return VAR;
和 return VOID;
都只能放在函数的最末尾,放在中间会导致这句话后面的所有语句都不会执行。
当然,您还可以使用正常 C/C++ 函数来快速编写一个 简单的有返回值的 Sonolus.h 函数,下面是简单示例:
SonolusApi add(let a, let b) {
return a + b;
}
在这种写法中,直接使用 return
函数返回值即可,不需要也不能使用 FUNCBEGIN
来指定为 Sonolus.h 函数,否则会出现未知问题。
请注意,在这种写法中,所有变量 var
都不能被正常存储在内存中,只能以表达式 let
形式进行运算,因此这种写法只适合一些简单的运算。
语句块
C/C++ 中的 if
/for
/while
/continue
/break
函数是自带函数,我们无法对其重定义,因此我们额外设置了 IF/FI
/FOR/DONE
/WHILE/DONE
/CONTINUE
/BREAK
宏定义来在 Sonolus 中实现上述功能。
使用方法与 C/C++ 原来的函数几乎一模一样,下面是基本使用示例:
SonolusApi TestFunc(let a) {
IF (a == 114514 || a == 1919810) {
Debuglog(a);
} FI
FOR (i, 0, a, 1) {
IF (i == 114514 || i == 1919810) {
CONTINUE;
} ELSE {
Debuglog(114514);
} FI
Debuglog(i);
BREAK;
} DONE
var it = a;
WHILE (it >= 0) {
Debuglog(it);
it = it - 1; // 注意:如果这里使用 a 变量来迭代会无法赋值导致死循环
} DONE
}
下面是一些您需要注意的点:
FOR (i, st, en, step)
定义中,i
可以是您自定义的任意符合 C/C++ 命名标准的变量名,i
的范围包括st
不包括en
。- 这些语句块的实现基础都是匿名 Sonolus.h 函数,因此你不需要在语句块中使用
return VAR;
或return VOID;
语句。 - 由于语句块是由宏定义实现的,你还可以写成以下类似 Python 语句的形式:
SonolusApi TestFunc(let a) {
IF (a == 114514 || a == 1919810)
Debuglog(a);
FI
FOR (i, 0, a, 1)
IF (i == 114514 || i == 1919810)
CONTINUE;
ELSE
Debuglog(114514);
FI
Debuglog(i);
BREAK;
DONE
var it = a;
WHILE (it >= 0)
Debuglog(it);
it = it - 1; // 注意:如果这里使用 a 变量来迭代会无法赋值导致死循环
DONE
}