summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--eval.c8
-rw-r--r--lib.c44
-rw-r--r--lib.h18
3 files changed, 47 insertions, 23 deletions
diff --git a/eval.c b/eval.c
index c7012d8..e47b395 100644
--- a/eval.c
+++ b/eval.c
@@ -806,8 +806,8 @@ ut_invoke(struct ut_state *state, struct ut_opcode *op, struct json_object *scop
{
struct ut_opcode *decl = json_object_get_userdata(func);
struct ut_opcode *arg = decl ? decl->operand[1] : NULL;
+ struct ut_tagvalue *tag = (struct ut_tagvalue *)decl;
struct json_object *s, *rv = NULL;
- struct ut_opcode *tag;
size_t arridx;
ut_c_fn *cfn;
@@ -815,8 +815,8 @@ ut_invoke(struct ut_state *state, struct ut_opcode *op, struct json_object *scop
return NULL;
/* is native function */
- if (decl->type == T_CFUNC) {
- cfn = (ut_c_fn *)decl->operand[0];
+ if (tag->type == T_CFUNC) {
+ cfn = (ut_c_fn *)tag->data;
return cfn ? cfn(state, op, argvals) : NULL;
}
@@ -838,7 +838,7 @@ ut_invoke(struct ut_state *state, struct ut_opcode *op, struct json_object *scop
case T_BREAK:
case T_CONTINUE:
ut_putval(rv);
- rv = ut_exception(state, tag, "Syntax error: %s statement must be inside loop",
+ rv = ut_exception(state, (struct ut_opcode *)tag, "Syntax error: %s statement must be inside loop",
tokennames[tag->type]);
break;
diff --git a/lib.c b/lib.c
index 96e5e87..1005e5c 100644
--- a/lib.c
+++ b/lib.c
@@ -257,6 +257,48 @@ ut_cast_int64(struct json_object *v)
return n;
}
+static int
+ut_c_fn_to_string(struct json_object *v, struct printbuf *pb, int level, int flags)
+{
+ return sprintbuf(pb, "%sfunction(...) { [native code] }%s",
+ level ? "\"" : "", level ? "\"" : "");
+}
+
+static void
+ut_c_fn_free(struct json_object *v, void *ud)
+{
+ struct ut_tagvalue *tag = json_object_get_userdata(v);
+
+ json_object_put(tag->proto);
+ free(ud);
+}
+
+static bool
+ut_register_function(struct ut_state *state, struct json_object *scope, const char *name, ut_c_fn *fn)
+{
+ struct json_object *val = json_object_new_object();
+ struct ut_tagvalue *tag;
+
+ if (!val)
+ return NULL;
+
+ tag = calloc(1, sizeof(*tag));
+
+ if (!tag) {
+ json_object_put(val);
+
+ return NULL;
+ }
+
+ tag->val = val;
+ tag->type = T_CFUNC;
+ tag->data = fn;
+
+ json_object_set_serializer(val, ut_c_fn_to_string, tag, ut_c_fn_free);
+
+ return json_object_object_add(scope, name, tag->val);
+}
+
static struct json_object *
ut_print(struct ut_state *s, struct ut_opcode *op, struct json_object *args)
{
@@ -1605,5 +1647,5 @@ ut_lib_init(struct ut_state *state, struct json_object *scope)
int i;
for (i = 0; i < sizeof(functions) / sizeof(functions[0]); i++)
- ut_add_function(state, scope, functions[i].name, functions[i].func);
+ ut_register_function(state, scope, functions[i].name, functions[i].func);
}
diff --git a/lib.h b/lib.h
index b6d693a..512a558 100644
--- a/lib.h
+++ b/lib.h
@@ -22,24 +22,6 @@
typedef struct json_object *(ut_c_fn)(struct ut_state *, struct ut_opcode *, struct json_object *);
-static inline int
-ut_c_fn_to_string(struct json_object *v, struct printbuf *pb, int level, int flags)
-{
- return sprintbuf(pb, "%sfunction(...) { [native code] }%s",
- level ? "\"" : "", level ? "\"" : "");
-}
-
-static inline bool
-ut_add_function(struct ut_state *state, struct json_object *scope, const char *name, ut_c_fn *fn)
-{
- struct ut_opcode *op = ut_new_op(state, T_CFUNC,
- json_object_new_boolean(0), (struct ut_opcode *)fn, (void *)1);
-
- json_object_set_serializer(op->val, ut_c_fn_to_string, op, NULL);
-
- return json_object_object_add(scope, name, json_object_get(op->val));
-}
-
void ut_lib_init(struct ut_state *state, struct json_object *scope);
char *ut_format_error(struct ut_state *state, const char *expr);