mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-12-02 03:58:33 +08:00
rework fscripts
This commit is contained in:
parent
5c7d74eebf
commit
e298f62872
@ -116,6 +116,7 @@ EXPORTS
|
||||
value_double
|
||||
value_set_str
|
||||
value_dup_str
|
||||
value_dup_str_with_len
|
||||
value_set_wstr
|
||||
value_str
|
||||
value_str_ex
|
||||
@ -1108,6 +1109,9 @@ EXPORTS
|
||||
file_read
|
||||
file_read_part
|
||||
file_write
|
||||
fscript_create
|
||||
fscript_exec
|
||||
fscript_destroy
|
||||
fscript_eval
|
||||
func_call_parser_init
|
||||
func_call_parser_parse
|
||||
|
@ -101,6 +101,7 @@ EXPORTS
|
||||
value_double
|
||||
value_set_str
|
||||
value_dup_str
|
||||
value_dup_str_with_len
|
||||
value_set_wstr
|
||||
value_str
|
||||
value_str_ex
|
||||
@ -302,6 +303,9 @@ EXPORTS
|
||||
file_read
|
||||
file_read_part
|
||||
file_write
|
||||
fscript_create
|
||||
fscript_exec
|
||||
fscript_destroy
|
||||
fscript_eval
|
||||
func_call_parser_init
|
||||
func_call_parser_parse
|
||||
|
@ -5,13 +5,14 @@
|
||||
fscript 是一个极简的脚本引擎,借鉴了函数语言中一些思路,主要用于低端嵌入式系统,让用户轻松扩展现有系统,而不需要重新编译和下载固件。
|
||||
|
||||
* 特色:
|
||||
* 小巧。核心代码 400 行,扩展函数 600 行。
|
||||
* 小巧。核心代码 600 行,扩展函数 600 行。
|
||||
* 灵活。支持多条语句、函数嵌套调用和变量定义。
|
||||
* 强大。超过 50 个内置函数,支持用 C 语言扩展函数。
|
||||
* 小内存。边解析边执行,释放不用的内存,最低开销小于 500 字节。
|
||||
* 小内存。最低开销小于 500 字节。
|
||||
|
||||
* 限制:
|
||||
* 不支持循环。
|
||||
* 不支持函数定义。
|
||||
|
||||
## 2. 示例
|
||||
|
||||
|
@ -19,34 +19,73 @@
|
||||
#include "tkc/time_now.h"
|
||||
#include "tkc/fscript.h"
|
||||
|
||||
struct _fscript_func_call_t;
|
||||
typedef struct _fscript_func_call_t fscript_func_call_t;
|
||||
|
||||
struct _fscript_func_call_t {
|
||||
fscript_func_t func;
|
||||
fscript_args_t args;
|
||||
fscript_func_call_t* next;
|
||||
};
|
||||
|
||||
#define VALUE_TYPE_JSCRIPT_ID 128
|
||||
#define VALUE_TYPE_JSCRIPT_FUNC VALUE_TYPE_JSCRIPT_ID + 1
|
||||
|
||||
static ret_t func_if(object_t* obj, fscript_args_t* args, value_t* result);
|
||||
static ret_t func_set(object_t* obj, fscript_args_t* args, value_t* result);
|
||||
|
||||
static ret_t func_args_push_str(fscript_args_t* args, const char* str, uint32_t size) {
|
||||
char* new_str = NULL;
|
||||
return_value_if_fail(str != NULL && args->size < FSCRIPT_MAX_ARGS, RET_BAD_PARAMS);
|
||||
static value_t* value_set_func(value_t* v, fscript_func_call_t* func) {
|
||||
value_set_pointer(v, func);
|
||||
v->type = VALUE_TYPE_JSCRIPT_FUNC;
|
||||
return v;
|
||||
}
|
||||
|
||||
new_str = tk_strndup(str, size);
|
||||
return_value_if_fail(new_str != NULL, RET_OOM);
|
||||
static ret_t func_args_extend(fscript_args_t* args) {
|
||||
if (args->size < args->capacity) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
value_set_str(args->args + args->size, new_str);
|
||||
args->args[args->size].free_handle = TRUE;
|
||||
args->size++;
|
||||
if (args->capacity < FSCRIPT_MAX_ARGS) {
|
||||
value_t* new_args = NULL;
|
||||
uint16_t capacity = args->capacity + 2;
|
||||
capacity = tk_min(capacity, FSCRIPT_MAX_ARGS);
|
||||
new_args = TKMEM_REALLOC(args->args, capacity * sizeof(value_t));
|
||||
return_value_if_fail(new_args != NULL, RET_OOM);
|
||||
args->args = new_args;
|
||||
args->capacity = capacity;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
static ret_t func_args_push_str(fscript_args_t* args, const char* str, uint32_t size,
|
||||
bool_t is_id) {
|
||||
value_t* v = NULL;
|
||||
return_value_if_fail(str != NULL && func_args_extend(args) == RET_OK, RET_BAD_PARAMS);
|
||||
v = args->args + args->size++;
|
||||
value_dup_str_with_len(v, str, size);
|
||||
v->type = is_id ? VALUE_TYPE_JSCRIPT_ID : v->type;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t func_args_push(fscript_args_t* args, value_t* v) {
|
||||
return_value_if_fail(v != NULL && args->size < FSCRIPT_MAX_ARGS, RET_BAD_PARAMS);
|
||||
|
||||
value_deep_copy(args->args + args->size, v);
|
||||
args->size++;
|
||||
return_value_if_fail(v != NULL && func_args_extend(args) == RET_OK, RET_BAD_PARAMS);
|
||||
value_deep_copy(args->args + args->size++, v);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t func_args_init(fscript_args_t* args, str_t* str) {
|
||||
static ret_t func_args_init(fscript_args_t* args, uint16_t init_args_capacity) {
|
||||
memset(args, 0x00, sizeof(fscript_args_t));
|
||||
args->str = str;
|
||||
|
||||
if (init_args_capacity > 0) {
|
||||
args->args = TKMEM_ZALLOCN(value_t, init_args_capacity);
|
||||
return_value_if_fail(args->args != NULL, RET_OOM);
|
||||
args->capacity = init_args_capacity;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
@ -54,9 +93,26 @@ static ret_t func_args_deinit(fscript_args_t* args) {
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; i < args->size; i++) {
|
||||
value_t* v = args->args + i;
|
||||
v->type = v->type == VALUE_TYPE_JSCRIPT_ID ? VALUE_TYPE_STRING : v->type;
|
||||
value_reset(args->args + i);
|
||||
}
|
||||
args->size = 0;
|
||||
TKMEM_FREE(args->args);
|
||||
memset(args, 0x00, sizeof(fscript_args_t));
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_func_call_destroy(fscript_func_call_t* call) {
|
||||
fscript_func_call_t* iter = call;
|
||||
fscript_func_call_t* next = NULL;
|
||||
|
||||
while (iter != NULL) {
|
||||
next = iter->next;
|
||||
func_args_deinit(&(call->args));
|
||||
TKMEM_FREE(iter);
|
||||
iter = next;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
@ -78,7 +134,7 @@ typedef struct _token_t {
|
||||
bool_t valid;
|
||||
} token_t;
|
||||
|
||||
typedef struct _fscript_t {
|
||||
typedef struct _fscript_parser_t {
|
||||
const char* str;
|
||||
const char* cursor;
|
||||
object_t* obj;
|
||||
@ -91,80 +147,170 @@ typedef struct _fscript_t {
|
||||
char c;
|
||||
str_t temp;
|
||||
bool_t ignore;
|
||||
|
||||
fscript_func_call_t* first;
|
||||
} fscript_parser_t;
|
||||
|
||||
typedef struct _fscript_t {
|
||||
str_t str;
|
||||
object_t* obj;
|
||||
fscript_func_call_t* first;
|
||||
} fscript_t;
|
||||
|
||||
static fscript_func_t fscript_lookup(fscript_t* fscript, const char* name, uint32_t size);
|
||||
static fscript_func_call_t* fscript_func_call_create(fscript_parser_t* parser, const char* name,
|
||||
uint32_t size);
|
||||
|
||||
static ret_t fscript_init(fscript_t* fscript, object_t* obj, const char* str) {
|
||||
fscript_t* fscript_create_impl(fscript_parser_t* parser) {
|
||||
fscript_t* fscript = TKMEM_ZALLOC(fscript_t);
|
||||
return_value_if_fail(fscript != NULL, NULL);
|
||||
fscript->str = parser->temp;
|
||||
fscript->obj = OBJECT_REF(parser->obj);
|
||||
fscript->first = parser->first;
|
||||
|
||||
parser->obj = NULL;
|
||||
parser->first = NULL;
|
||||
parser->temp.str = NULL;
|
||||
|
||||
return fscript;
|
||||
}
|
||||
|
||||
static ret_t fscript_exec_func(fscript_t* fscript, fscript_func_call_t* iter, value_t* result) {
|
||||
uint32_t i = 0;
|
||||
ret_t ret = RET_OK;
|
||||
fscript_args_t args;
|
||||
|
||||
func_args_init(&args, iter->args.size);
|
||||
args.str = &(fscript->str);
|
||||
args.size = iter->args.size;
|
||||
return_value_if_fail((args.args != NULL || args.size == 0), RET_OOM);
|
||||
for (i = 0; i < iter->args.size; i++) {
|
||||
value_t* s = iter->args.args + i;
|
||||
value_t* d = args.args + i;
|
||||
int32_t save_type = s->type;
|
||||
if (s->type == VALUE_TYPE_JSCRIPT_ID) {
|
||||
s->type = VALUE_TYPE_STRING;
|
||||
if (iter->func == func_set && i == 0) {
|
||||
value_copy(d, s); /*func_set accept id/str as first param*/
|
||||
} else if (object_get_prop(fscript->obj, value_str(s), d) != RET_OK) {
|
||||
value_copy(d, s);
|
||||
}
|
||||
} else if (s->type == VALUE_TYPE_JSCRIPT_FUNC) {
|
||||
s->type = VALUE_TYPE_POINTER;
|
||||
fscript_func_call_t* func = (fscript_func_call_t*)value_pointer(s);
|
||||
if (i > 0 && iter->func == func_if) {
|
||||
if (value_bool(args.args) && i == 1) {
|
||||
fscript_exec_func(fscript, func, d);
|
||||
}
|
||||
if (!value_bool(args.args) && i == 2) {
|
||||
fscript_exec_func(fscript, func, d);
|
||||
}
|
||||
} else {
|
||||
fscript_exec_func(fscript, func, d);
|
||||
}
|
||||
} else {
|
||||
value_copy(d, s);
|
||||
}
|
||||
s->type = save_type;
|
||||
}
|
||||
|
||||
ret = iter->func(fscript->obj, &args, result);
|
||||
func_args_deinit(&args);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t fscript_exec(fscript_t* fscript, value_t* result) {
|
||||
fscript_func_call_t* iter = NULL;
|
||||
return_value_if_fail(fscript != NULL, RET_FAIL);
|
||||
|
||||
iter = fscript->first;
|
||||
while (iter != NULL) {
|
||||
return_value_if_fail(iter->func != NULL, RET_FAIL);
|
||||
value_reset(result);
|
||||
return_value_if_fail(fscript_exec_func(fscript, iter, result) == RET_OK, RET_FAIL);
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t fscript_destroy(fscript_t* fscript) {
|
||||
return_value_if_fail(fscript != NULL, RET_FAIL);
|
||||
|
||||
OBJECT_UNREF(fscript->obj);
|
||||
str_reset(&(fscript->str));
|
||||
fscript_func_call_destroy(fscript->first);
|
||||
memset(fscript, 0x00, sizeof(fscript_t));
|
||||
|
||||
fscript->obj = obj;
|
||||
fscript->str = str;
|
||||
fscript->cursor = str;
|
||||
str_init(&(fscript->temp), 64);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_parser_init(fscript_parser_t* parser, object_t* obj, const char* str) {
|
||||
memset(parser, 0x00, sizeof(fscript_parser_t));
|
||||
|
||||
parser->obj = obj;
|
||||
parser->str = str;
|
||||
parser->cursor = str;
|
||||
str_init(&(parser->temp), 64);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_deinit(fscript_t* fscript) {
|
||||
str_reset(&(fscript->temp));
|
||||
TKMEM_FREE(fscript->error);
|
||||
static ret_t fscript_parser_deinit(fscript_parser_t* parser) {
|
||||
str_reset(&(parser->temp));
|
||||
TKMEM_FREE(parser->error);
|
||||
fscript_func_call_destroy(parser->first);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static char fscript_get_char(fscript_t* fscript) {
|
||||
static char fscript_parser_get_char(fscript_parser_t* parser) {
|
||||
char c = '\0';
|
||||
return_value_if_fail(fscript != NULL, c);
|
||||
if (fscript->c) {
|
||||
c = fscript->c;
|
||||
fscript->c = '\0';
|
||||
return_value_if_fail(parser != NULL, c);
|
||||
if (parser->c) {
|
||||
c = parser->c;
|
||||
parser->c = '\0';
|
||||
return c;
|
||||
}
|
||||
|
||||
c = fscript->cursor[0];
|
||||
c = parser->cursor[0];
|
||||
if (c) {
|
||||
if (c == '\n') {
|
||||
fscript->row++;
|
||||
fscript->col = 0;
|
||||
parser->row++;
|
||||
parser->col = 0;
|
||||
} else {
|
||||
fscript->col++;
|
||||
parser->col++;
|
||||
}
|
||||
|
||||
fscript->cursor++;
|
||||
parser->cursor++;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static ret_t fscript_unget_char(fscript_t* fscript, char c) {
|
||||
return_value_if_fail(fscript->cursor > fscript->str, RET_BAD_PARAMS);
|
||||
static ret_t fscript_parser_unget_char(fscript_parser_t* parser, char c) {
|
||||
return_value_if_fail(parser->cursor > parser->str, RET_BAD_PARAMS);
|
||||
|
||||
fscript->c = c;
|
||||
parser->c = c;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
typedef struct _func_entry_t {
|
||||
const char* name;
|
||||
fscript_func_t func;
|
||||
} func_entry_t;
|
||||
static ret_t fscript_parser_set_error(fscript_parser_t* parser, const char* str) {
|
||||
return_value_if_fail(parser != NULL && str != NULL, RET_BAD_PARAMS);
|
||||
|
||||
static ret_t fscript_set_error(fscript_t* fscript, const char* str) {
|
||||
return_value_if_fail(fscript != NULL && str != NULL, RET_BAD_PARAMS);
|
||||
|
||||
fscript->error = tk_str_copy(fscript->error, str);
|
||||
log_warn("at line(%u) col (%u): %s\n", fscript->row, fscript->col, str);
|
||||
parser->error = tk_str_copy(parser->error, str);
|
||||
log_warn("at line(%u) col (%u): %s\n", parser->row, parser->col, str);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_skip_seperators(fscript_t* fscript) {
|
||||
static ret_t fscript_parser_skip_seperators(fscript_parser_t* parser) {
|
||||
char c = '\0';
|
||||
|
||||
do {
|
||||
c = fscript_get_char(fscript);
|
||||
c = fscript_parser_get_char(parser);
|
||||
} while (isspace(c) || c == ';');
|
||||
fscript_unget_char(fscript, c);
|
||||
fscript_parser_unget_char(parser, c);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
@ -174,15 +320,15 @@ static ret_t fscript_skip_seperators(fscript_t* fscript) {
|
||||
t->token = str->str; \
|
||||
t->size = str->size;
|
||||
|
||||
static ret_t fscript_parse_str(fscript_t* fscript) {
|
||||
static ret_t fscript_parser_parse_str(fscript_parser_t* parser) {
|
||||
char c = '\0';
|
||||
bool_t escape = FALSE;
|
||||
str_t* str = &(fscript->temp);
|
||||
token_t* t = &(fscript->token);
|
||||
str_t* str = &(parser->temp);
|
||||
token_t* t = &(parser->token);
|
||||
|
||||
str_set(str, "");
|
||||
do {
|
||||
c = fscript_get_char(fscript);
|
||||
c = fscript_parser_get_char(parser);
|
||||
if ((!escape && c == '\"') || c == '\0') {
|
||||
break;
|
||||
}
|
||||
@ -198,20 +344,20 @@ static ret_t fscript_parse_str(fscript_t* fscript) {
|
||||
|
||||
TOKEN_INIT(t, TOKEN_STR, str);
|
||||
if (c != '\0' && c != '\"') {
|
||||
fscript_unget_char(fscript, c);
|
||||
fscript_parser_unget_char(parser, c);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_parse_id_or_number(fscript_t* fscript, token_type_t def_type) {
|
||||
static ret_t fscript_parser_parse_id_or_number(fscript_parser_t* parser, token_type_t def_type) {
|
||||
char c = '\0';
|
||||
str_t* str = &(fscript->temp);
|
||||
token_t* t = &(fscript->token);
|
||||
str_t* str = &(parser->temp);
|
||||
token_t* t = &(parser->token);
|
||||
|
||||
str_set(str, "");
|
||||
do {
|
||||
c = fscript_get_char(fscript);
|
||||
c = fscript_parser_get_char(parser);
|
||||
if (c != '(' && c != ')' && c != ',' && c != '\"' && c != '\0') {
|
||||
str_append_char(str, c);
|
||||
} else {
|
||||
@ -222,26 +368,26 @@ static ret_t fscript_parse_id_or_number(fscript_t* fscript, token_type_t def_typ
|
||||
str_trim(str, " \t\r\n");
|
||||
TOKEN_INIT(t, (c == '(' ? TOKEN_FUNC : def_type), str);
|
||||
if (c != '\0') {
|
||||
fscript_unget_char(fscript, c);
|
||||
fscript_parser_unget_char(parser, c);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static token_t* fscript_get_token(fscript_t* fscript) {
|
||||
static token_t* fscript_parser_get_token(fscript_parser_t* parser) {
|
||||
char c = 0;
|
||||
token_t* t = &(fscript->token);
|
||||
token_t* t = &(parser->token);
|
||||
|
||||
if (t->valid) {
|
||||
t->valid = FALSE;
|
||||
return t;
|
||||
}
|
||||
|
||||
fscript_skip_seperators(fscript);
|
||||
c = fscript_get_char(fscript);
|
||||
fscript_parser_skip_seperators(parser);
|
||||
c = fscript_parser_get_char(parser);
|
||||
|
||||
t->size = 1;
|
||||
t->token = fscript->cursor - 1;
|
||||
t->token = parser->cursor - 1;
|
||||
switch (c) {
|
||||
case '\0': {
|
||||
return NULL;
|
||||
@ -269,103 +415,81 @@ static token_t* fscript_get_token(fscript_t* fscript) {
|
||||
case '^':
|
||||
case '~':
|
||||
case '&': {
|
||||
fscript_skip_seperators(fscript);
|
||||
c = fscript_get_char(fscript);
|
||||
fscript_parser_skip_seperators(parser);
|
||||
c = fscript_parser_get_char(parser);
|
||||
if (c == '(') {
|
||||
fscript_unget_char(fscript, c);
|
||||
t->size = fscript->cursor - t->token - 1;
|
||||
fscript_parser_unget_char(parser, c);
|
||||
t->size = parser->cursor - t->token - 1;
|
||||
} else {
|
||||
t->size = fscript->cursor - t->token;
|
||||
t->size = parser->cursor - t->token;
|
||||
}
|
||||
|
||||
t->type = TOKEN_FUNC;
|
||||
return t;
|
||||
}
|
||||
case '\"': {
|
||||
fscript_parse_str(fscript);
|
||||
fscript_parser_parse_str(parser);
|
||||
return t;
|
||||
}
|
||||
default: {
|
||||
fscript_unget_char(fscript, c);
|
||||
fscript_parser_unget_char(parser, c);
|
||||
if (c == '+' || c == '-' || isdigit(c)) {
|
||||
fscript_parse_id_or_number(fscript, TOKEN_NUMBER);
|
||||
fscript_parser_parse_id_or_number(parser, TOKEN_NUMBER);
|
||||
} else {
|
||||
fscript_parse_id_or_number(fscript, TOKEN_ID);
|
||||
fscript_parser_parse_id_or_number(parser, TOKEN_ID);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t fscript_expect_token(fscript_t* fscript, token_type_t type, const char* msg) {
|
||||
token_t* t = fscript_get_token(fscript);
|
||||
static ret_t fscript_parser_expect_token(fscript_parser_t* parser, token_type_t type,
|
||||
const char* msg) {
|
||||
token_t* t = fscript_parser_get_token(parser);
|
||||
if (t == NULL || t->type != type) {
|
||||
fscript_set_error(fscript, msg);
|
||||
fscript_parser_set_error(parser, msg);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_unget_token(fscript_t* fscript) {
|
||||
fscript->token.valid = TRUE;
|
||||
static ret_t fscript_parser_unget_token(fscript_parser_t* parser) {
|
||||
parser->token.valid = TRUE;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_exec_func(fscript_t* fscript, value_t* result) {
|
||||
static ret_t fscript_parse_func(fscript_parser_t* parser, fscript_func_call_t* call) {
|
||||
value_t v;
|
||||
bool_t done = FALSE;
|
||||
fscript_args_t args;
|
||||
str_t* str = &(fscript->temp);
|
||||
token_t* t = fscript_get_token(fscript);
|
||||
fscript_func_t func = fscript_lookup(fscript, t->token, t->size);
|
||||
bool_t is_if = t && t->size == 2 && strncmp(t->token, "if", 2) == 0;
|
||||
return_value_if_fail(func != NULL, RET_NOT_FOUND);
|
||||
fscript_args_t* args = &(call->args);
|
||||
token_t* t = fscript_parser_get_token(parser);
|
||||
|
||||
value_set_int(result, 0);
|
||||
func_args_init(&args, &(fscript->temp));
|
||||
fscript_expect_token(fscript, TOKEN_LPAREN, "expect \"(\"");
|
||||
|
||||
while (fscript->error == NULL && t != NULL && t->type != TOKEN_RPAREN) {
|
||||
t = fscript_get_token(fscript);
|
||||
fscript_parser_expect_token(parser, TOKEN_LPAREN, "expect \"(\"");
|
||||
while (parser->error == NULL && t != NULL && t->type != TOKEN_RPAREN) {
|
||||
t = fscript_parser_get_token(parser);
|
||||
if (t == NULL) {
|
||||
fscript_expect_token(fscript, TOKEN_LPAREN, "expect \")\"");
|
||||
fscript_parser_expect_token(parser, TOKEN_LPAREN, "expect \")\"");
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
switch (t->type) {
|
||||
case TOKEN_ID: {
|
||||
if (t->token[0] == 't' && strncmp(t->token, "true", 4) == 0) {
|
||||
func_args_push(&args, value_set_bool(&v, TRUE));
|
||||
func_args_push(args, value_set_bool(&v, TRUE));
|
||||
} else if (t->token[0] == 'f' && strncmp(t->token, "false", 5) == 0) {
|
||||
func_args_push(&args, value_set_bool(&v, FALSE));
|
||||
func_args_push(args, value_set_bool(&v, FALSE));
|
||||
} else {
|
||||
if(args.size > 0 || (func != func_set && args.size == 0)) {
|
||||
if(object_get_prop(fscript->obj, str->str, &v) == RET_OK) {
|
||||
func_args_push(&args, &v);
|
||||
} else {
|
||||
func_args_push_str(&args, t->token, t->size);
|
||||
}
|
||||
} else {
|
||||
func_args_push_str(&args, t->token, t->size);
|
||||
}
|
||||
func_args_push_str(args, t->token, t->size, TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TOKEN_FUNC: {
|
||||
bool_t ignore = fscript->ignore;
|
||||
fscript_unget_token(fscript);
|
||||
|
||||
if (is_if && args.size > 0) {
|
||||
if (value_bool(args.args)) {
|
||||
fscript->ignore = args.size != 1;
|
||||
} else {
|
||||
fscript->ignore = args.size == 1;
|
||||
}
|
||||
}
|
||||
fscript_exec_func(fscript, &v);
|
||||
fscript->ignore = ignore;
|
||||
func_args_push(&args, &v);
|
||||
value_reset(&v);
|
||||
fscript_parser_unget_token(parser);
|
||||
fscript_func_call_t* acall = fscript_func_call_create(parser, t->token, t->size);
|
||||
return_value_if_fail(acall != NULL, RET_BAD_PARAMS);
|
||||
fscript_parse_func(parser, acall);
|
||||
value_set_func(&v, acall);
|
||||
func_args_push(args, &v);
|
||||
break;
|
||||
}
|
||||
case TOKEN_NUMBER: {
|
||||
@ -376,11 +500,11 @@ static ret_t fscript_exec_func(fscript_t* fscript, value_t* result) {
|
||||
} else {
|
||||
value_set_int(&v, tk_atoi(number));
|
||||
}
|
||||
func_args_push(&args, &v);
|
||||
func_args_push(args, &v);
|
||||
break;
|
||||
}
|
||||
case TOKEN_STR: {
|
||||
func_args_push_str(&args, t->token, t->size);
|
||||
func_args_push_str(args, t->token, t->size, FALSE);
|
||||
break;
|
||||
}
|
||||
case TOKEN_RPAREN: {
|
||||
@ -388,7 +512,7 @@ static ret_t fscript_exec_func(fscript_t* fscript, value_t* result) {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
fscript_set_error(fscript, "unexpected token:");
|
||||
fscript_parser_set_error(parser, "unexpected token:");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -397,33 +521,41 @@ static ret_t fscript_exec_func(fscript_t* fscript, value_t* result) {
|
||||
break;
|
||||
}
|
||||
|
||||
t = fscript_get_token(fscript);
|
||||
t = fscript_parser_get_token(parser);
|
||||
if (t == NULL) {
|
||||
fscript_expect_token(fscript, TOKEN_LPAREN, "expect \")\"");
|
||||
fscript_parser_expect_token(parser, TOKEN_LPAREN, "expect \")\"");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fscript->ignore) {
|
||||
func(fscript->obj, &args, result);
|
||||
}
|
||||
|
||||
func_args_deinit(&args);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fscript_exec(fscript_t* fscript, value_t* result) {
|
||||
static ret_t fscript_parse(fscript_parser_t* parser) {
|
||||
char c = '\0';
|
||||
ret_t ret = RET_OK;
|
||||
while (fscript->cursor[0]) {
|
||||
ret = fscript_exec_func(fscript, result);
|
||||
fscript_func_call_t* acall = NULL;
|
||||
fscript_func_call_t* last = NULL;
|
||||
|
||||
fscript_skip_seperators(fscript);
|
||||
c = fscript_get_char(fscript);
|
||||
while (parser->cursor[0]) {
|
||||
token_t* t = fscript_parser_get_token(parser);
|
||||
if (t != NULL && t->type == TOKEN_FUNC) {
|
||||
acall = fscript_func_call_create(parser, t->token, t->size);
|
||||
return_value_if_fail(acall != NULL, RET_BAD_PARAMS);
|
||||
|
||||
fscript_parser_unget_token(parser);
|
||||
fscript_parse_func(parser, acall);
|
||||
if (last == NULL) {
|
||||
parser->first = acall;
|
||||
} else {
|
||||
last->next = acall;
|
||||
}
|
||||
last = acall;
|
||||
}
|
||||
fscript_parser_skip_seperators(parser);
|
||||
c = fscript_parser_get_char(parser);
|
||||
if (c) {
|
||||
value_reset(result);
|
||||
fscript_unget_char(fscript, c);
|
||||
fscript_parser_unget_char(parser, c);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -432,22 +564,37 @@ static ret_t fscript_exec(fscript_t* fscript, value_t* result) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t fscript_eval(object_t* obj, const char* script, value_t* result) {
|
||||
value_t v;
|
||||
fscript_t fscript;
|
||||
fscript_t* fscript_create(object_t* obj, const char* script) {
|
||||
ret_t ret = RET_OK;
|
||||
return_value_if_fail(obj != NULL && script != NULL, RET_BAD_PARAMS);
|
||||
fscript_t* fscript = NULL;
|
||||
fscript_parser_t parser;
|
||||
return_value_if_fail(obj != NULL && script != NULL, NULL);
|
||||
|
||||
value_set_int(&v, 0);
|
||||
fscript_init(&fscript, obj, script);
|
||||
ret = fscript_exec(&fscript, &v);
|
||||
|
||||
if (result != NULL) {
|
||||
value_deep_copy(result, &v);
|
||||
fscript_parser_init(&parser, obj, script);
|
||||
ret = fscript_parse(&parser);
|
||||
if (ret == RET_OK) {
|
||||
fscript = fscript_create_impl(&parser);
|
||||
fscript_parser_deinit(&parser);
|
||||
} else {
|
||||
log_warn("parser error:%s\n", script);
|
||||
fscript_parser_deinit(&parser);
|
||||
}
|
||||
|
||||
return fscript;
|
||||
}
|
||||
|
||||
ret_t fscript_eval(object_t* obj, const char* script, value_t* result) {
|
||||
value_t v;
|
||||
ret_t ret = RET_OK;
|
||||
fscript_t* fscript = fscript_create(obj, script);
|
||||
return_value_if_fail(fscript != NULL, RET_BAD_PARAMS);
|
||||
|
||||
value_set_int(&v, 0);
|
||||
if (fscript_exec(fscript, &v) == RET_OK && result != NULL) {
|
||||
value_deep_copy(result, &v);
|
||||
}
|
||||
value_reset(&v);
|
||||
fscript_deinit(&fscript);
|
||||
fscript_destroy(fscript);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -958,85 +1105,110 @@ static ret_t func_unset(object_t* obj, fscript_args_t* args, value_t* result) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
typedef struct _func_entry_t {
|
||||
const char* name;
|
||||
fscript_func_t func;
|
||||
uint32_t max_args_nr;
|
||||
} func_entry_t;
|
||||
|
||||
static const func_entry_t s_builtin_funcs[] = {
|
||||
{"set", func_set},
|
||||
{"max", func_max},
|
||||
{"min", func_min},
|
||||
{"==", func_eq},
|
||||
{">=", func_ge},
|
||||
{">", func_great},
|
||||
{"<=", func_le},
|
||||
{"<", func_less},
|
||||
{"!", func_not},
|
||||
{"||", func_or},
|
||||
{"exec", func_exec},
|
||||
{"join", func_join},
|
||||
{"if", func_if},
|
||||
{"int", func_int},
|
||||
{"float", func_float},
|
||||
{"iformat", func_iformat},
|
||||
{"print", func_print},
|
||||
{"fformat", func_fformat},
|
||||
{"time_now", func_time_now},
|
||||
{"unset", func_unset},
|
||||
{"str", func_str},
|
||||
{"sub", func_sub},
|
||||
{"substr", func_substr},
|
||||
{"sum", func_sum},
|
||||
{"tolower", func_tolower},
|
||||
{"toupper", func_toupper},
|
||||
{"trim", func_trim},
|
||||
{"&&", func_and},
|
||||
{"abs", func_abs},
|
||||
{"acos", func_acos},
|
||||
{"and", func_and},
|
||||
{"asin", func_asin},
|
||||
{"atan", func_atan},
|
||||
{"clamp", func_clamp},
|
||||
{"contains", func_contains},
|
||||
{"cos", func_cos},
|
||||
{"div", func_div},
|
||||
{"eq", func_eq},
|
||||
{"ge", func_ge},
|
||||
{"great", func_great},
|
||||
{"le", func_le},
|
||||
{"len", func_len},
|
||||
{"less", func_less},
|
||||
{"mul", func_mul},
|
||||
{"noop", func_noop},
|
||||
{"not", func_not},
|
||||
{"or", func_or},
|
||||
{"pow", func_pow},
|
||||
{"random", func_random},
|
||||
{"replace", func_replace},
|
||||
{"sin", func_sin},
|
||||
{"sqrt", func_sqrt},
|
||||
{"tan", func_tan},
|
||||
{"time_now_ms", func_time_now_ms},
|
||||
{"time_now_us", func_time_now_us},
|
||||
{"&", func_bit_and},
|
||||
{"^", func_bit_nor},
|
||||
{"~", func_bit_not},
|
||||
{"|", func_bit_or},
|
||||
{"/", func_div},
|
||||
{"%", func_mod},
|
||||
{"*", func_mul},
|
||||
{"-", func_sub},
|
||||
{"+", func_sum},
|
||||
{"print", func_print, 4},
|
||||
{"set", func_set, 2},
|
||||
{"max", func_max, 2},
|
||||
{"min", func_min, 2},
|
||||
{"==", func_eq, 2},
|
||||
{">=", func_ge, 2},
|
||||
{">", func_great, 2},
|
||||
{"<=", func_le, 2},
|
||||
{"<", func_less, 2},
|
||||
{"!", func_not, 1},
|
||||
{"||", func_or, 2},
|
||||
{"exec", func_exec, 2},
|
||||
{"join", func_join, 8},
|
||||
{"if", func_if, 3},
|
||||
{"int", func_int, 1},
|
||||
{"float", func_float, 1},
|
||||
{"iformat", func_iformat, 2},
|
||||
{"fformat", func_fformat, 2},
|
||||
{"time_now", func_time_now, 0},
|
||||
{"unset", func_unset, 1},
|
||||
{"str", func_str, 1},
|
||||
{"sub", func_sub, 2},
|
||||
{"substr", func_substr, 3},
|
||||
{"sum", func_sum, 8},
|
||||
{"tolower", func_tolower, 1},
|
||||
{"toupper", func_toupper, 1},
|
||||
{"trim", func_trim, 1},
|
||||
{"&&", func_and, 2},
|
||||
{"abs", func_abs, 1},
|
||||
{"acos", func_acos, 1},
|
||||
{"and", func_and, 2},
|
||||
{"asin", func_asin, 1},
|
||||
{"atan", func_atan, 1},
|
||||
{"clamp", func_clamp, 3},
|
||||
{"contains", func_contains, 2},
|
||||
{"cos", func_cos, 1},
|
||||
{"div", func_div, 2},
|
||||
{"eq", func_eq, 2},
|
||||
{"ge", func_ge, 2},
|
||||
{"great", func_great, 2},
|
||||
{"le", func_le, 2},
|
||||
{"len", func_len, 1},
|
||||
{"less", func_less, 2},
|
||||
{"mul", func_mul, 2},
|
||||
{"noop", func_noop, 0},
|
||||
{"not", func_not, 1},
|
||||
{"or", func_or, 2},
|
||||
{"pow", func_pow, 2},
|
||||
{"random", func_random, 2},
|
||||
{"replace", func_replace, 3},
|
||||
{"sin", func_sin, 1},
|
||||
{"sqrt", func_sqrt, 1},
|
||||
{"tan", func_tan, 1},
|
||||
{"time_now_ms", func_time_now_ms, 0},
|
||||
{"time_now_us", func_time_now_us, 0},
|
||||
{"&", func_bit_and, 2},
|
||||
{"^", func_bit_nor, 1},
|
||||
{"~", func_bit_not, 1},
|
||||
{"|", func_bit_or, 2},
|
||||
{"/", func_div, 2},
|
||||
{"%", func_mod, 2},
|
||||
{"*", func_mul, 2},
|
||||
{"-", func_sub, 2},
|
||||
{"+", func_sum, 8},
|
||||
};
|
||||
|
||||
static fscript_func_t fscript_lookup(fscript_t* fscript, const char* name, uint32_t size) {
|
||||
static fscript_func_call_t* fscript_func_call_create(fscript_parser_t* parser, const char* name,
|
||||
uint32_t size) {
|
||||
uint32_t i = 0;
|
||||
fscript_func_t func = NULL;
|
||||
char func_name[TK_NAME_LEN + 1];
|
||||
char full_func_name[2 * TK_NAME_LEN + 1];
|
||||
fscript_func_call_t* call = TKMEM_ZALLOC(fscript_func_call_t);
|
||||
return_value_if_fail(call != NULL, NULL);
|
||||
|
||||
tk_strncpy(func_name, name, tk_min(size, TK_NAME_LEN));
|
||||
for (i = 0; i < ARRAY_SIZE(s_builtin_funcs); i++) {
|
||||
if (tk_str_eq(s_builtin_funcs[i].name, func_name)) {
|
||||
return s_builtin_funcs[i].func;
|
||||
const func_entry_t* iter = s_builtin_funcs + i;
|
||||
if (tk_str_eq(iter->name, func_name)) {
|
||||
call->func = iter->func;
|
||||
func_args_init(&(call->args), iter->max_args_nr);
|
||||
return call;
|
||||
}
|
||||
}
|
||||
|
||||
tk_snprintf(full_func_name, sizeof(full_func_name)-1, "%s%s", STR_FSCRIPT_FUNCTION_PREFIX, func_name);
|
||||
return (fscript_func_t)object_get_prop_pointer(fscript->obj, full_func_name);
|
||||
tk_snprintf(full_func_name, sizeof(full_func_name) - 1, "%s%s", STR_FSCRIPT_FUNCTION_PREFIX,
|
||||
func_name);
|
||||
func = (fscript_func_t)object_get_prop_pointer(parser->obj, full_func_name);
|
||||
|
||||
if (func != NULL) {
|
||||
call->func = func;
|
||||
func_args_init(&(call->args), 2);
|
||||
|
||||
return call;
|
||||
} else {
|
||||
TKMEM_FREE(call);
|
||||
log_warn("not found func:%s\n", func_name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -32,18 +32,24 @@ BEGIN_C_DECLS
|
||||
*/
|
||||
typedef struct _fscript_args_t {
|
||||
/**
|
||||
* @property {uint32_t} size
|
||||
* @property {uint16_t} size
|
||||
* @annotation ["readable"]
|
||||
* 参数个数。
|
||||
*/
|
||||
uint32_t size;
|
||||
uint16_t size;
|
||||
/**
|
||||
* @property {uint16_t} capacity
|
||||
* @annotation ["readable"]
|
||||
* 目前最大容量。
|
||||
*/
|
||||
uint16_t capacity;
|
||||
|
||||
/**
|
||||
* @property {value_t*} args
|
||||
* @annotation ["readable"]
|
||||
* 参数列表。
|
||||
*/
|
||||
value_t args[FSCRIPT_MAX_ARGS];
|
||||
value_t* args;
|
||||
|
||||
/**
|
||||
* @property {str_t*} str
|
||||
@ -59,10 +65,40 @@ typedef ret_t (*fscript_func_t)(object_t* obj, fscript_args_t* args, value_t* v)
|
||||
* @class fscript_t
|
||||
* @annotation ["fake"]
|
||||
*
|
||||
* 一个简易的函数式脚本。
|
||||
* 一个简易的函数式脚本引擎。
|
||||
* 用法请参考:https://github.com/zlgopen/awtk/blob/master/docs/fscript.md
|
||||
*
|
||||
*/
|
||||
struct _fscript_t;
|
||||
typedef struct _fscript_t fscript_t;
|
||||
|
||||
/**
|
||||
* @method fscript_create
|
||||
* 创建引擎对象。
|
||||
* @param {object_t*} obj 脚本执行上下文。
|
||||
* @param {const char*} script 脚本代码。
|
||||
*
|
||||
* @return {fscript_t*} 返回fscript对象。
|
||||
*/
|
||||
fscript_t* fscript_create(object_t* obj, const char* script);
|
||||
|
||||
/**
|
||||
* @method fscript_exec
|
||||
* @param {fscript_t*} fscript 脚本引擎对象。
|
||||
* @param {value_t*} result 执行结果(调用者需要用value_reset函数清除result)。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t fscript_exec(fscript_t* fscript, value_t* result);
|
||||
|
||||
/**
|
||||
* @method fscript_destroy
|
||||
* 销毁引擎对象。
|
||||
* @param {fscript_t*} fscript 脚本引擎对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t fscript_destroy(fscript_t* fscript);
|
||||
|
||||
/**
|
||||
* @method fscript_eval
|
||||
|
@ -334,10 +334,13 @@ enum { TK_NAME_LEN = 31 };
|
||||
|
||||
#ifdef WITH_CPPCHECK
|
||||
#define tk_str_eq strcmp
|
||||
#define tk_str_eq strcasecmp
|
||||
#define tk_str_ieq strcasecmp
|
||||
#define tk_str_eq_with_len strncmp
|
||||
#else
|
||||
#define tk_str_eq(s1, s2) \
|
||||
(((s1) != NULL) && ((s2) != NULL) && *(s1) == *(s2) && strcmp((s1), (s2)) == 0)
|
||||
#define tk_str_eq_with_len(s1, s2, len) \
|
||||
(((s1) != NULL) && ((s2) != NULL) && *(s1) == *(s2) && strncmp((s1), (s2), len) == 0)
|
||||
#define tk_str_ieq(s1, s2) (((s1) != NULL) && ((s2) != NULL) && strcasecmp((s1), (s2)) == 0)
|
||||
|
||||
#define tk_wstr_eq(s1, s2) \
|
||||
|
@ -384,6 +384,16 @@ value_t* value_dup_str(value_t* v, const char* value) {
|
||||
return v;
|
||||
}
|
||||
|
||||
value_t* value_dup_str_with_len(value_t* v, const char* value, uint32_t len) {
|
||||
return_value_if_fail(v != NULL, NULL);
|
||||
|
||||
value_init(v, VALUE_TYPE_STRING);
|
||||
v->value.str = tk_strndup(value, len);
|
||||
v->free_handle = TRUE;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
value_t* value_set_wstr(value_t* v, const wchar_t* value) {
|
||||
return_value_if_fail(v != NULL, NULL);
|
||||
|
||||
@ -747,7 +757,7 @@ const char* value_str_ex(const value_t* v, char* buff, uint32_t size) {
|
||||
v->type == VALUE_TYPE_FLOAT) {
|
||||
tk_snprintf(buff, size, "%lf", value_double(v));
|
||||
} else if (v->type == VALUE_TYPE_WSTRING) {
|
||||
tk_utf8_from_utf16(value_wstr, buff, size);
|
||||
tk_utf8_from_utf16(value_wstr(v), buff, size);
|
||||
} else if (v->type == VALUE_TYPE_BOOL) {
|
||||
tk_snprintf(buff, size, "%s", value_bool(v) ? "true" : "false");
|
||||
} else {
|
||||
|
@ -476,7 +476,6 @@ value_t* value_set_str(value_t* v, const char* value);
|
||||
* @method value_dup_str
|
||||
* 设置类型为字符串的值(并拷贝字符串)。
|
||||
*
|
||||
* > 供脚本语言使用。
|
||||
* @alias value_set_str
|
||||
* @annotation ["scriptable"]
|
||||
* @param {value_t*} v value对象。
|
||||
@ -486,6 +485,18 @@ value_t* value_set_str(value_t* v, const char* value);
|
||||
*/
|
||||
value_t* value_dup_str(value_t* v, const char* value);
|
||||
|
||||
/**
|
||||
* @method value_dup_str_with_len
|
||||
* 设置类型为字符串的值(并拷贝字符串)。
|
||||
*
|
||||
* @param {value_t*} v value对象。
|
||||
* @param {const char*} value 待设置的值。
|
||||
* @param {uint32_t} len 长度。
|
||||
*
|
||||
* @return {value_t*} value对象本身。
|
||||
*/
|
||||
value_t* value_dup_str_with_len(value_t* v, const char* value, uint32_t len);
|
||||
|
||||
/**
|
||||
* @method value_set_wstr
|
||||
* 设置类型为宽字符串的值。
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/platform.h"
|
||||
#include "tkc/time_now.h"
|
||||
#include "tkc/fscript.h"
|
||||
@ -6,15 +7,28 @@
|
||||
int main(int argc, char* argv[]) {
|
||||
platform_prepare();
|
||||
|
||||
if (argc != 2) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s script\n", argv[0]);
|
||||
return 0;
|
||||
} else {
|
||||
value_t v;
|
||||
uint64_t start = time_now_us();
|
||||
const char* code = argv[1];
|
||||
object_t* obj = object_default_create();
|
||||
fscript_eval(obj, argv[1], &v);
|
||||
value_reset(&v);
|
||||
if(argc == 3) {
|
||||
/*stress test*/
|
||||
uint32_t i = 0;
|
||||
uint32_t times = tk_atoi(argv[2]);
|
||||
fscript_t* fscript = fscript_create(obj, code);
|
||||
for(i = 0; i < times; i++) {
|
||||
fscript_exec(fscript, &v);
|
||||
value_reset(&v);
|
||||
}
|
||||
fscript_destroy(fscript);
|
||||
} else {
|
||||
fscript_eval(obj, code, &v);
|
||||
value_reset(&v);
|
||||
}
|
||||
OBJECT_UNREF(obj);
|
||||
log_debug("cost: %d us\n", (int)(time_now_us() - start));
|
||||
}
|
||||
|
@ -2984,7 +2984,7 @@
|
||||
"annotation": {
|
||||
"scriptable": true
|
||||
},
|
||||
"desc": "设置类型为字符串的值(并拷贝字符串)。\n\n> 供脚本语言使用。",
|
||||
"desc": "设置类型为字符串的值(并拷贝字符串)。",
|
||||
"name": "value_dup_str",
|
||||
"alias": "value_set_str",
|
||||
"return": {
|
||||
@ -2992,6 +2992,32 @@
|
||||
"desc": "value对象本身。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "value_t*",
|
||||
"name": "v",
|
||||
"desc": "value对象。"
|
||||
},
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "value",
|
||||
"desc": "待设置的值。"
|
||||
},
|
||||
{
|
||||
"type": "uint32_t",
|
||||
"name": "len",
|
||||
"desc": "长度。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "设置类型为字符串的值(并拷贝字符串)。",
|
||||
"name": "value_dup_str_with_len",
|
||||
"return": {
|
||||
"type": "value_t*",
|
||||
"desc": "value对象本身。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
@ -31374,7 +31400,15 @@
|
||||
{
|
||||
"name": "size",
|
||||
"desc": "参数个数。",
|
||||
"type": "uint32_t",
|
||||
"type": "uint16_t",
|
||||
"annotation": {
|
||||
"readable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "capacity",
|
||||
"desc": "目前最大容量。",
|
||||
"type": "uint16_t",
|
||||
"annotation": {
|
||||
"readable": true
|
||||
}
|
||||
@ -31415,11 +31449,69 @@
|
||||
"type": "const char*",
|
||||
"name": "script",
|
||||
"desc": "脚本代码。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "创建引擎对象。",
|
||||
"name": "fscript_create",
|
||||
"return": {
|
||||
"type": "fscript_t*",
|
||||
"desc": "返回fscript对象。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "fscript_t*",
|
||||
"name": "fscript",
|
||||
"desc": "脚本引擎对象。"
|
||||
},
|
||||
{
|
||||
"type": "value_t*",
|
||||
"name": "result",
|
||||
"desc": "执行结果。"
|
||||
"desc": "执行结果(调用者需要用value_reset函数清除result)。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "",
|
||||
"name": "fscript_exec",
|
||||
"return": {
|
||||
"type": "ret_t",
|
||||
"desc": "返回RET_OK表示成功,否则表示失败。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "fscript_t*",
|
||||
"name": "fscript",
|
||||
"desc": "脚本引擎对象。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "销毁引擎对象。",
|
||||
"name": "fscript_destroy",
|
||||
"return": {
|
||||
"type": "ret_t",
|
||||
"desc": "返回RET_OK表示成功,否则表示失败。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "object_t*",
|
||||
"name": "obj",
|
||||
"desc": "脚本执行上下文。"
|
||||
},
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "script",
|
||||
"desc": "脚本代码。"
|
||||
},
|
||||
{
|
||||
"type": "value_t*",
|
||||
"name": "result",
|
||||
"desc": "执行结果(调用者需要用value_reset函数清除result)。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
@ -31434,7 +31526,7 @@
|
||||
"events": [],
|
||||
"properties": [],
|
||||
"header": "tkc/fscript.h",
|
||||
"desc": "一个简易的函数式脚本。",
|
||||
"desc": "一个简易的函数式脚本引擎。\n用法请参考:https://github.com/zlgopen/awtk/blob/master/docs/fscript.md",
|
||||
"name": "fscript_t",
|
||||
"annotation": {
|
||||
"fake": true
|
||||
|
@ -2558,7 +2558,7 @@
|
||||
"annotation": {
|
||||
"scriptable": true
|
||||
},
|
||||
"desc": "设置类型为字符串的值(并拷贝字符串)。\n\n> 供脚本语言使用。",
|
||||
"desc": "设置类型为字符串的值(并拷贝字符串)。",
|
||||
"name": "value_dup_str",
|
||||
"alias": "value_set_str",
|
||||
"return": {
|
||||
@ -2566,6 +2566,32 @@
|
||||
"desc": "value对象本身。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "value_t*",
|
||||
"name": "v",
|
||||
"desc": "value对象。"
|
||||
},
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "value",
|
||||
"desc": "待设置的值。"
|
||||
},
|
||||
{
|
||||
"type": "uint32_t",
|
||||
"name": "len",
|
||||
"desc": "长度。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "设置类型为字符串的值(并拷贝字符串)。",
|
||||
"name": "value_dup_str_with_len",
|
||||
"return": {
|
||||
"type": "value_t*",
|
||||
"desc": "value对象本身。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
@ -7727,7 +7753,15 @@
|
||||
{
|
||||
"name": "size",
|
||||
"desc": "参数个数。",
|
||||
"type": "uint32_t",
|
||||
"type": "uint16_t",
|
||||
"annotation": {
|
||||
"readable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "capacity",
|
||||
"desc": "目前最大容量。",
|
||||
"type": "uint16_t",
|
||||
"annotation": {
|
||||
"readable": true
|
||||
}
|
||||
@ -7768,11 +7802,69 @@
|
||||
"type": "const char*",
|
||||
"name": "script",
|
||||
"desc": "脚本代码。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "创建引擎对象。",
|
||||
"name": "fscript_create",
|
||||
"return": {
|
||||
"type": "fscript_t*",
|
||||
"desc": "返回fscript对象。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "fscript_t*",
|
||||
"name": "fscript",
|
||||
"desc": "脚本引擎对象。"
|
||||
},
|
||||
{
|
||||
"type": "value_t*",
|
||||
"name": "result",
|
||||
"desc": "执行结果。"
|
||||
"desc": "执行结果(调用者需要用value_reset函数清除result)。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "",
|
||||
"name": "fscript_exec",
|
||||
"return": {
|
||||
"type": "ret_t",
|
||||
"desc": "返回RET_OK表示成功,否则表示失败。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "fscript_t*",
|
||||
"name": "fscript",
|
||||
"desc": "脚本引擎对象。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
"desc": "销毁引擎对象。",
|
||||
"name": "fscript_destroy",
|
||||
"return": {
|
||||
"type": "ret_t",
|
||||
"desc": "返回RET_OK表示成功,否则表示失败。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"params": [
|
||||
{
|
||||
"type": "object_t*",
|
||||
"name": "obj",
|
||||
"desc": "脚本执行上下文。"
|
||||
},
|
||||
{
|
||||
"type": "const char*",
|
||||
"name": "script",
|
||||
"desc": "脚本代码。"
|
||||
},
|
||||
{
|
||||
"type": "value_t*",
|
||||
"name": "result",
|
||||
"desc": "执行结果(调用者需要用value_reset函数清除result)。"
|
||||
}
|
||||
],
|
||||
"annotation": {},
|
||||
@ -7787,7 +7879,7 @@
|
||||
"events": [],
|
||||
"properties": [],
|
||||
"header": "tkc/fscript.h",
|
||||
"desc": "一个简易的函数式脚本。",
|
||||
"desc": "一个简易的函数式脚本引擎。\n用法请参考:https://github.com/zlgopen/awtk/blob/master/docs/fscript.md",
|
||||
"name": "fscript_t",
|
||||
"annotation": {
|
||||
"fake": true
|
||||
|
Loading…
Reference in New Issue
Block a user