Skip to content

Commit

Permalink
feat(expr): support running multiple expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
Water-Melon committed Mar 19, 2024
1 parent bca185a commit 00586b5
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 30 deletions.
13 changes: 8 additions & 5 deletions docs/book/cn/expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ concat(abc, bcd) --这是一个函数,参数有两个,都是变量
concat(abc, "bcd") --这是一个函数,参数有两个,一个是变量,一个是常量
concat(1, "bcd") --两个参数都是常量
concat("abc", concat(bcd, "efg")) --这个例子展示了函数嵌套调用
concat("abc", concat(bcd, "efg")) aaa concat("bcd", concat(efg, "hij")) --这个例子展示运行多个表达式
```


Expand Down Expand Up @@ -175,8 +176,8 @@ static mln_expr_val_t *func_expr_handler(mln_string_t *name, int is_func, mln_ar

int main(void)
{
mln_string_t var_exp = mln_string("aaa");
mln_string_t func_exp = mln_string("concat('abc', aaa, concat(bcd, 'eee'))");
mln_string_t var_exp = mln_string("aaa bbb");
mln_string_t func_exp = mln_string("concat('abc', concat(aaa, 'bbb')) ccc concat('eee', concat(bbb, 'fff'))");

mln_expr_val_t *v;

Expand All @@ -203,9 +204,11 @@ int main(void)
执行结果:
```
0x4b1ac98 (nil) (nil)
0x4bbb720 (nil) (nil)
aaa 0 0
03/18/2024 06:18:10 UTC DEBUG: a.c:main:59: PID:2303523 4 aaa
03/18/2024 06:18:10 UTC DEBUG: a.c:main:67: PID:2303523 4 abcaaabcdeee
0x4bbb830 (nil) (nil)
bbb 0 0
03/19/2024 00:17:17 UTC DEBUG: a.c:main:59: PID:2317789 4 bbb
03/19/2024 00:17:17 UTC DEBUG: a.c:main:67: PID:2317789 4 eeebbbfff
```
13 changes: 8 additions & 5 deletions docs/book/en/expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ concat(abc, bcd) -- This is a function with two parameters, both are variables
concat(abc, "bcd") -- This is a function with two parameters, one is a variable and the other is a constant
concat(1, "bcd") -- Both parameters are constants
concat("abc", concat(bcd, "efg")) -- This example demonstrates nested function calls
concat("abc", concat(bcd, "efg")) aaa concat("bcd", concat(efg, "hij")) -- This example demonstrates running multiple expressions
```


Expand Down Expand Up @@ -175,8 +176,8 @@ static mln_expr_val_t *func_expr_handler(mln_string_t *name, int is_func, mln_ar

int main(void)
{
mln_string_t var_exp = mln_string("aaa");
mln_string_t func_exp = mln_string("concat('abc', aaa, concat(bcd, 'eee'))");
mln_string_t var_exp = mln_string("aaa bbb");
mln_string_t func_exp = mln_string("concat('abc', concat(aaa, 'bbb')) ccc concat('eee', concat(bbb, 'fff'))");

mln_expr_val_t *v;

Expand All @@ -203,9 +204,11 @@ int main(void)
Execution result:
```
0x4b1ac98 (nil) (nil)
0x4bbb720 (nil) (nil)
aaa 0 0
03/18/2024 06:18:10 UTC DEBUG: a.c:main:59: PID:2303523 4 aaa
03/18/2024 06:18:10 UTC DEBUG: a.c:main:67: PID:2303523 4 abcaaabcdeee
0x4bbb830 (nil) (nil)
bbb 0 0
03/19/2024 00:17:17 UTC DEBUG: a.c:main:59: PID:2317789 4 bbb
03/19/2024 00:17:17 UTC DEBUG: a.c:main:67: PID:2317789 4 eeebbbfff
```
68 changes: 48 additions & 20 deletions src/mln_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ MLN_FUNC_VOID(, void, mln_expr_val_dup, (mln_expr_val_t *dest, mln_expr_val_t *s
})

MLN_FUNC(static inline, int, mln_expr_parse, \
(mln_lex_t *lex, mln_expr_cb_t cb, void *data, mln_expr_val_t *ret), \
(lex, cb, data, ret), \
(mln_lex_t *lex, mln_expr_cb_t cb, void *data, mln_expr_val_t *ret, int *eof, mln_expr_struct_t **next), \
(lex, cb, data, ret, eof, next), \
{
int rc;
enum mln_expr_enum type;
Expand All @@ -258,11 +258,20 @@ MLN_FUNC(static inline, int, mln_expr_parse, \
mln_expr_val_t *v;

again:
if ((name = mln_expr_token(lex)) == NULL || name->type == EXPR_TK_EOF) {
if ((name = *next) != NULL) {
*next = NULL;
} else {
if ((name = mln_expr_token(lex)) == NULL) {
mln_expr_free(name);
return MLN_EXPR_RET_ERR;
}
}
if ((type = name->type) == EXPR_TK_EOF) {
*eof = 1;
mln_expr_free(name);
return MLN_EXPR_RET_ERR;
return MLN_EXPR_RET_OK;
}
if ((type = name->type) == EXPR_TK_SPACE) {
if (type == EXPR_TK_SPACE) {
mln_expr_free(name);
goto again;
}
Expand All @@ -285,23 +294,22 @@ MLN_FUNC(static inline, int, mln_expr_parse, \
mln_expr_free(name);
return MLN_EXPR_RET_ERR;
}
if (tk->type == EXPR_TK_SPACE) {
if ((type = tk->type) == EXPR_TK_SPACE) {
mln_expr_free(tk);
goto again2;
}
if ((type = tk->type) == EXPR_TK_EOF || type == EXPR_TK_COMMA) {
if (type != EXPR_TK_LPAR) {
v = cb(name->text, 0, NULL, data);
mln_expr_val_dup(ret, v);
mln_expr_val_free(v);
mln_expr_free(name);
mln_expr_free(tk);
if ((type = tk->type) == EXPR_TK_EOF || type == EXPR_TK_COMMA) {
mln_expr_free(tk);
} else {
*next = tk;
}
return v == NULL? MLN_EXPR_RET_ERR: MLN_EXPR_RET_OK;
}
if (type != EXPR_TK_LPAR) {
mln_expr_free(name);
mln_expr_free(tk);
return MLN_EXPR_RET_ERR;
}
mln_expr_free(tk);

if (mln_array_init(&arr, (array_free)mln_expr_val_destroy, sizeof(mln_expr_val_t), MLN_EXPR_DEFAULT_ARGS) < 0) {
Expand All @@ -316,8 +324,8 @@ MLN_FUNC(static inline, int, mln_expr_parse, \
mln_array_destroy(&arr);
return MLN_EXPR_RET_ERR;
}
v->type = 0;
rc = mln_expr_parse(lex, cb, data, v);
v->type = mln_expr_type_null;
rc = mln_expr_parse(lex, cb, data, v, eof, next);
if (rc == MLN_EXPR_RET_ERR) {
mln_expr_free(name);
mln_array_destroy(&arr);
Expand All @@ -328,6 +336,11 @@ MLN_FUNC(static inline, int, mln_expr_parse, \
break;
} else if (rc == MLN_EXPR_RET_OK) {
v = NULL;
if (*eof) {
mln_expr_free(name);
mln_array_destroy(&arr);
return MLN_EXPR_RET_ERR;
}
}
}

Expand All @@ -344,7 +357,9 @@ MLN_FUNC(, mln_expr_val_t *, mln_expr_run, (mln_string_t *exp, mln_expr_cb_t cb,
struct mln_lex_attr lattr;
mln_lex_hooks_t hooks;
mln_alloc_t *pool;
mln_expr_val_t *ret, v;
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;
Expand All @@ -367,15 +382,28 @@ MLN_FUNC(, mln_expr_val_t *, mln_expr_run, (mln_string_t *exp, mln_expr_cb_t cb,
return NULL;
}

if (mln_expr_parse(lex, cb, data, &v) != MLN_EXPR_RET_OK) {
ret = NULL;
} else {
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);
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);
}
mln_expr_val_destroy(&v);

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

Expand Down

0 comments on commit 00586b5

Please sign in to comment.