Skip to content

Commit

Permalink
feat(expr): support loading expressions from file
Browse files Browse the repository at this point in the history
  • Loading branch information
Water-Melon committed Mar 20, 2024
1 parent 00586b5 commit fd06d1e
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 0 deletions.
3 changes: 3 additions & 0 deletions docs/Melon Developer Guide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3249,6 +3249,9 @@ Their definitions can be found in melon/include/mln_types.h.
d) mln_expr_val_t *mln_expr_run(mln_string_t *exp, mln_expr_cb_t cb, void *data);
Run a simple expression `exp`. `cb` will be called with user-data `data` when parsing variables and functions.

e) mln_expr_val_t *mln_expr_run_file(mln_string_t *path, mln_expr_cb_t cb, void *data);
Run the expression in the file indicated by `path`. `cb` will be called with user-data `data` when parsing variables and functions.

5. Framework Usage
It is very easy to use this framework. Before we use it, we have to initialize it.
1) include header file.
Expand Down
34 changes: 34 additions & 0 deletions docs/book/cn/expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,40 @@ typedef mln_expr_val_t *(*mln_expr_cb_t)(mln_string_t *name, int is_func, mln_ar



#### mln_expr_run

```c
mln_expr_val_t *mln_expr_run(mln_string_t *exp, mln_expr_cb_t cb, void *data);

typedef mln_expr_val_t *(*mln_expr_cb_t)(mln_string_t *name, int is_func, mln_array_t *args, void *data);
```
描述:运行表达式`exp`。表达式中的变量以及函数(和函数的参数)还有用户自定义数据`data`,都会被传递到回调函数`cb`中进行解析。开发者可以根据需求,定制化这些函数和变量的值。
返回值:
- 成功:`mln_expr_val_t`指针,存放运行结果。
- 失败:`NULL`
#### mln_expr_run_filr
```c
mln_expr_val_t *mln_expr_run_file(mln_string_t *path, mln_expr_cb_t cb, void *data);
typedef mln_expr_val_t *(*mln_expr_cb_t)(mln_string_t *name, int is_func, mln_array_t *args, void *data);
```

描述:运行由`path`指定的文件中的表达式。表达式中的变量以及函数(和函数的参数)还有用户自定义数据`data`,都会被传递到回调函数`cb`中进行解析。开发者可以根据需求,定制化这些函数和变量的值。

返回值:

- 成功:`mln_expr_val_t`指针,存放运行结果。
- 失败:`NULL`



### 示例

```c
Expand Down
17 changes: 17 additions & 0 deletions docs/book/en/expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,23 @@ Return values:



#### mln_expr_run_file

```c
mln_expr_val_t *mln_expr_run_file(mln_string_t *path, mln_expr_cb_t cb, void *data);

typedef mln_expr_val_t *(*mln_expr_cb_t)(mln_string_t *name, int is_func, mln_array_t *args, void *data);
```
Description: Run the expression specified in the file identified by `path`. Variables and functions (along with their arguments) in the expression, as well as user-defined data `data`, will be passed to the callback function `cb` for evaluation. Developers can customize the values of these functions and variables as needed.
Return values:
- On success: Pointer to `mln_expr_val_t`, containing the result of the evaluation
- On failure: `NULL`
### Example
```c
Expand Down
1 change: 1 addition & 0 deletions include/mln_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ typedef mln_expr_val_t *(*mln_expr_cb_t)(mln_string_t *name, \
void *data);

extern mln_expr_val_t *mln_expr_run(mln_string_t *exp, mln_expr_cb_t cb, void *data);
extern mln_expr_val_t *mln_expr_run_file(mln_string_t *path, mln_expr_cb_t cb, void *data);
extern mln_expr_val_t *mln_expr_val_new(mln_expr_typ_t type, void *data, mln_expr_udata_free free);
extern void mln_expr_val_free(mln_expr_val_t *ev);
extern void mln_expr_val_dup(mln_expr_val_t *dest, mln_expr_val_t *src);
Expand Down
60 changes: 60 additions & 0 deletions src/mln_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,66 @@ MLN_FUNC(, mln_expr_val_t *, mln_expr_run, (mln_string_t *exp, mln_expr_cb_t cb,

if (eof) {
mln_expr_val_destroy(&v);
if (ret == NULL) ret = mln_expr_val_new(mln_expr_type_null, NULL, NULL);
break;
}

if (ret != NULL) mln_expr_val_free(ret);
if ((ret = (mln_expr_val_t *)malloc(sizeof(mln_expr_val_t))) != NULL) {
mln_expr_val_dup(ret, &v);
}
mln_expr_val_destroy(&v);
}

if (next != NULL) mln_expr_free(next);
mln_lex_destroy(lex);
mln_alloc_destroy(pool);

return ret;
})

MLN_FUNC(, mln_expr_val_t *, mln_expr_run_file, (mln_string_t *path, mln_expr_cb_t cb, void *data), (path, cb, data), {
mln_lex_t *lex = NULL;
struct mln_lex_attr lattr;
mln_lex_hooks_t hooks;
mln_alloc_t *pool;
mln_expr_val_t *ret = NULL, v;
int eof = 0;
mln_expr_struct_t *next = NULL;

memset(&hooks, 0, sizeof(hooks));
hooks.dblq_handler = (lex_hook)mln_expr_dblq_handler;
hooks.sglq_handler = (lex_hook)mln_expr_sglq_handler;

if ((pool = lattr.pool = mln_alloc_init(NULL)) == NULL) {
return NULL;
}
lattr.keywords = keywords;
lattr.hooks = &hooks;
lattr.preprocess = 1;
lattr.padding = 0;
lattr.type = M_INPUT_T_FILE;
lattr.data = path;
lattr.env = NULL;

mln_lex_init_with_hooks(mln_expr, lex, &lattr);
if (lex == NULL) {
mln_alloc_destroy(pool);
return NULL;
}

while (1) {
v.type = mln_expr_type_null;
if (mln_expr_parse(lex, cb, data, &v, &eof, &next) != MLN_EXPR_RET_OK) {
if (ret != NULL) mln_expr_val_free(ret);
ret = NULL;
mln_expr_val_destroy(&v);
break;
}

if (eof) {
mln_expr_val_destroy(&v);
if (ret == NULL) ret = mln_expr_val_new(mln_expr_type_null, NULL, NULL);
break;
}

Expand Down

0 comments on commit fd06d1e

Please sign in to comment.