fscript 腳本引擎
1. 介紹
fscript 是一個極簡的腳本引擎,借鑒了函數(shù)語言中一些思路,主要用于低端嵌入式系統(tǒng),讓用戶輕松擴展現(xiàn)有系統(tǒng),而不需要重新編譯和下載固件。
- 特色:
- 小內(nèi)存。最低開銷小于 400 字節(jié)。
- 小巧。核心代碼 600 行,擴展函數(shù) 600 行。
- 靈活。支持多條語句、函數(shù)嵌套調(diào)用和變量定義。
- 強大。超過 50 個內(nèi)置函數(shù),支持用 C 語言擴展函數(shù)。
如果不需要數(shù)學函數(shù),可以定義 AWTK_LITE 宏。
keil -O1 編譯結果:
Code (inc. data) RO Data RW Data ZI Data Debug Object Name
5108 134 1051 0 0 27871 fscript.o
- 限制:
- 不支持循環(huán)。
- 不支持函數(shù)定義。
2. 示例
print("hello fscript")
在 PC 上測試運行:
./bin/runFScript 'print("hello fscript")'
3. 語法
數(shù)據(jù)類型
- 浮點數(shù)類型 (double)。
- 整數(shù)類型 (int32)。支持十進制、二進制和十六進制。
- 字符串類型 (string)。UTF-8 字符串,用英文雙引號擴起來。
- 布爾類型 (bool)。標準取值為:true 和 false,非 0 的數(shù)值視為 true。
函數(shù)調(diào)用
print(0xff)
print(100)
print(0b1010)
print("hello fscript")
print("hello", 123)
函數(shù)之間可以用空格、換行和英文分號分隔。
定義變量
set(a, 123)
獲取變量
a
函數(shù)嵌套調(diào)用
print(join(",", 1, 2, 3))
print(join(",", +(1, 2), -(5, 2), *(2, 3), /(9, 3)))
條件執(zhí)行
if(false, print("a"), print("b"))
if(true, print("a"), print("b"))
4. 函數(shù)
4.1 基本函數(shù)
打印調(diào)試信息到控制臺。
原型
print(str)
示例
print("hello fscript")
print("hello", "fscript")
print(1)
print(true)
noop
空函數(shù)。什么也不做,主要給 if 函數(shù)用。
原型
noop()
if
條件執(zhí)行。如果第一個參數(shù)為 true,執(zhí)行第二個參數(shù),否則執(zhí)行第三個參數(shù)。
原型
if(p, s1, s2)
示例
set(a, 1)
if(<(a, 0), print(" a < 0"), print("a >= 0"))
set
設置變量的值。
原型
set(var, value)
示例
set(a, 1)
unset
清除變量。
原型
unset(var)
示例
unset(a)
int
轉換為整數(shù)類型。
原型
int(var)
示例
int("123")
float
轉換為浮點數(shù)類型。
原型
float(var)
示例
float("123")
str
轉換為字符串類型。
原型
str(var)
示例
str(int(123))
iformat
對整數(shù)進行格式化(生成的字符串長度不超過 63)
原型
iformat(format, value)
示例
iformat("hello:%d", 123)
fformat
對浮點數(shù)進行格式化(生成的字符串長度不超過 63)
原型
fformat(format, value)
示例
fformat("hello:%lf", 123)
exec
執(zhí)行 object 里的一個命令。
原型
exec(cmd, arg)
示例
exec("clear", "all")
具體功能與 object 的實現(xiàn)有關。
4.2 字符串函數(shù)
join
將多個變量用指定的分隔符拼接起來(最多 7 個字符串),形成一個字符串。
原型
join(seperator, s1, s2, s3...)
示例
join(",", 1, 2, 3, "abc")
len
取字符串的長度。
原型
len(str)
示例
len("abc")
toupper
將字符串轉換成大寫。
原型
toupper(str)
示例
tuppper("abc")
tolower
將字符串轉換成小寫。
原型
tolower(str)
示例
tolower("ABC")
trim
將字符串轉換成小寫。
原型
trim(str)
示例
trm(" abc ")
substr
取子字符串。
原型
substr(str, from, len)
示例
substr("abcd", 1, 2)
replace
替換子字符串。
原型
replace(str, old, new)
示例
replace("ab cd", "ab", "hello")
contains
檢查是否包含指定的子字符串。
原型
contains(str, substr)
示例
contains("ab cd", "ab")
4.3 運算函數(shù)
sum
對多個數(shù)值類型的參數(shù)求和。
原型
sum(n1,n2...)
+(n1,n2...)
示例
print(sum(1, 2, 3))
運行:
./bin/runFScript 'print(sum(1, 2, 3))'
輸出:
6.000000
sub
計算兩個數(shù)之差。
原型
sub(n1,n2)
或
-(n1,n2)
示例
print(sub(2, 1))
print(-(2, 1))
運行:
./bin/runFScript 'print(sub(2, 1))'
輸出:
1.000000
mul
計算兩個數(shù)之積。
原型
mul(n1,n2)
或
*(n1,n2)
示例
print(mul(2, 1))
print(*(2, 1))
運行:
./bin/runFScript 'print(mul(2, 1))'
輸出:
2.000000
div
計算兩個數(shù)之商。
原型
div(n1,n2)
或
/(n1,n2)
示例
print(div(2, 1))
print(/(2, 1))
運行:
./bin/runFScript 'print(div(2, 1))'
輸出:
2.000000
%
計算兩個數(shù)的模。
原型
%(n1,n2)
示例
print(%(23, 7))
運行:
./bin/runFScript 'print(%(23, 7))'
輸出:
2.000000
and
邏輯與運算。
原型
and(n1,n2)
&&(n1,n2)
示例
print(&&(true, false))
print(&&(true, true))
運行:
./bin/runFScript 'print(and(true, true))'
輸出:
true
or
邏輯或運算。
原型
or(n1,n2)
||(n1,n2)
示例
print(and(true, false))
print(||(true, true))
運行:
./bin/runFScript 'print(or(true, false))'
輸出:
true
not
邏輯非運算。
原型
not(n1)
!(n1)
示例
print(not(true))
print(!(false))
運行:
./bin/runFScript 'print(not(false))'
輸出:
true
&
位與運算。
原型
&(n1,n2)
示例
print(&(1, 1))
運行:
./bin/runFScript 'print(&(1, 2))'
輸出:
0
|
位或運算。
原型
|(1,2)
示例
print(|(1, 2))
運行:
./bin/runFScript 'print(|(1, 2))'
輸出:
3
~
按位取反運算。
原型
~(n1)
示例
print(~(1))
運行:
./bin/runFScript 'print(iformat("0x%x", ~(1)))'
輸出:
0xfffffffe
比較函數(shù)
<
小于。
原型
<(1,2)
less(1,2)
示例
print(<(1, 2))
print(<("a", "b"))
運行:
./bin/runFScript 'print(<(1, 2))'
輸出:
true
<=
小于等于。
原型
<=(1,2)
le(1,2)
示例
print(<=(1, 2))
print(<=("a", "b"))
運行:
./bin/runFScript 'print(<=(1, 2))'
輸出:
true
>
大于。
原型
>(1,2)
great(1,2)
示例
print(>(1, 2))
print(>("a", "b"))
運行:
./bin/runFScript 'print(>(1, 2))'
輸出:
true
>=
大于等于。
原型
>=(1,2)
ge(1,2)
示例
print(>=(1, 2))
print(>=("a", "b"))
運行:
./bin/runFScript 'print(>=(1, 2))'
輸出:
false
==
等于。
原型
==(1,2)
eq(1,2)
示例
print(==(1, 2))
print(==("a", "b"))
運行:
./bin/runFScript 'print(==(1, 2))'
輸出:
false
4.4 數(shù)學函數(shù)
random
產(chǎn)生隨機數(shù)。
原型
random()
random(min, max)
示例
print(random())
print(random(0, 100))
sin
sin 函數(shù)。
原型
sin(a)
示例
sin(0)
cos
cos 函數(shù)。
原型
cos(a)
示例
cos(0)
tan
tan 函數(shù)。
原型
tan(a)
示例
tan(1)
asin
asin 函數(shù)。
原型
asin(a)
示例
asin(1)
acos
acos 函數(shù)。
原型
acos(a)
示例
acos(1)
atan
atan 函數(shù)。
原型
atan(a)
示例
atan(1)
abs
abs 函數(shù)。
原型
abs(a)
示例
abs(1)
min
min 函數(shù)。
原型
min(a, b)
max
max 函數(shù)。
原型
max(a, b)
示例
max(1, 2)
示例
min(1, 2)
clamp
clamp 函數(shù)。
原型
clamp(a, min, max)
示例
clamp(2, 1, 3)
4.5 時間函數(shù)
time_now
獲取當前時間函數(shù) (s)。
原型
time_now()
示例
time_now()
time_now_ms
獲取當前時間函數(shù) (ms)。
原型
time_now_ms()
示例
time_now_ms()
time_now_us
獲取當前時間函數(shù) (us)。
原型
time_now_us()
示例
time_now_us()
5. 自定義函數(shù)
定義函數(shù)
static ret_t func_foo(object_t* obj, fscript_args_t* args, value_t* v) {
value_set_int(v, 123);
return RET_OK;
}
注冊和使用
value_t v;
object_t* obj = object_default_create();
object_set_prop_pointer(obj, "function.foo", (void*)func_foo);
fscript_eval(obj, "foo()", &v);
value_reset(&v);
OBJECT_UNREF(obj);