diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2018-09-14 23:00:39 +0000 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2019-02-28 00:38:24 +0100 |
commit | ec3a86b8a0ccf8e499c15eed8e873d2a62959a13 (patch) | |
tree | ad2f17e2a2eec2bc9410e1e967de1ff1fe85aaec /filter | |
parent | 7c36eb3e8bd7d06f65dc7319d42b6abe782c5b89 (diff) |
WIP native functionnative/native-function
Diffstat (limited to 'filter')
-rw-r--r-- | filter/config.Y | 26 | ||||
-rw-r--r-- | filter/filter.c | 17 | ||||
-rw-r--r-- | filter/filter.h | 1 |
3 files changed, 36 insertions, 8 deletions
diff --git a/filter/config.Y b/filter/config.Y index c1e74531..cc19cac0 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -819,10 +819,17 @@ function_call: SYM '(' var_list ')' { struct symbol *sym; struct f_inst *inst = $3; - if ($1->class != SYM_FUNCTION) - cf_error("You can't call something which is not a function. Really."); + enum f_instruction_code code; + switch ($1->class) { + case SYM_FUNCTION: + code = FI_CALL; break; + case SYM_FUNCTION_NATIVE: + code = FI_CALL_NATIVE; break; + default: + cf_error("You can't call something which is not a function. Really."); + } DBG("You are calling function %s\n", $1->name); - $$ = f_new_inst(FI_CALL); + $$ = f_new_inst(code); $$->a1.p = inst; $$->a2.p = $1->def; sym = $1->aux2; @@ -939,10 +946,17 @@ term: | SYM '(' var_list ')' { struct symbol *sym; struct f_inst *inst = $3; - if ($1->class != SYM_FUNCTION) - cf_error("You can't call something which is not a function. Really."); + enum f_instruction_code code; + switch ($1->class) { + case SYM_FUNCTION: + code = FI_CALL; break; + case SYM_FUNCTION_NATIVE: + code = FI_CALL_NATIVE; break; + default: + cf_error("You can't call something which is not a function. Really."); + } DBG("You are calling function %s\n", $1->name); - $$ = f_new_inst(FI_CALL); + $$ = f_new_inst(code); $$->a1.p = inst; $$->a2.p = $1->def; sym = $1->aux2; diff --git a/filter/filter.c b/filter/filter.c index 37cf16a3..88da05b4 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -610,7 +610,8 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS; #define INTERPRET(val, what_) \ val = interpret(what_); \ - if (val.type & T_RETURN) \ + debug("INTERPRET %d\n", val.type); \ + if (val.type & T_RETURN) \ return val; #define ACCESS_RTE \ @@ -886,8 +887,10 @@ interpret(struct f_inst *what) res.val.t = what->a2.p; else if (res.type == T_STRING) res.val.s = what->a2.p; - else + else { res.val.i = what->a2.i; + debug("FI_CONSTANT %d\n", res.val.i); + } break; case FI_VARIABLE: case FI_CONSTANT_INDIRECT: @@ -1309,6 +1312,15 @@ interpret(struct f_inst *what) return res; res.type &= ~T_RETURN; break; + case FI_CALL_NATIVE: /* CALL: this is special: if T_RETURN and returning some value, mask it out */ + ARG_ANY(1); + debug("**********************foobar1**************************%d %x\n", v1.type, v1.val.s); + struct f_val (*f)(void) = what->a2.p; + res = f(); + if (res.type == T_RETURN) + return res; + res.type &= ~T_RETURN; + break; case FI_CLEAR_LOCAL_VARS: /* Clear local variables */ for (sym = what->a1.p; sym != NULL; sym = sym->aux2) ((struct f_val *) sym->def)->type = T_VOID; @@ -1578,6 +1590,7 @@ interpret(struct f_inst *what) default: bug( "Unknown instruction %d (%c)", what->fi_code, what->fi_code & 0xff); }} + debug("return %d\n", res.type); return res; } diff --git a/filter/filter.h b/filter/filter.h index a8c33287..1dbc16c2 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -63,6 +63,7 @@ F(FI_AS_PATH_LAST_NAG, 'a', 'L') \ F(FI_RETURN, 0, 'r') \ F(FI_CALL, 'c', 'a') \ + F(FI_CALL_NATIVE, 'c', 'n') \ F(FI_CLEAR_LOCAL_VARS, 'c', 'V') \ F(FI_SWITCH, 'S', 'W') \ F(FI_IP_MASK, 'i', 'M') \ |