aboutsummaryrefslogtreecommitdiff
path: root/lib/forlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/forlan.c')
-rw-r--r--lib/forlan.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/lib/forlan.c b/lib/forlan.c
index f12e00b..74b03a3 100644
--- a/lib/forlan.c
+++ b/lib/forlan.c
@@ -28,6 +28,7 @@ struct forlan_eval_env {
struct grecs_node *top_node;
struct forlan_value retval;
union forlan_node *instr;
+ int exit_code;
jmp_buf stop_buf;
jmp_buf loop_buf;
};
@@ -800,7 +801,7 @@ node_ident_cmp(struct grecs_node const *a, struct grecs_node const *b)
}
/* FIXME */
-void
+static void
func_sort(forlan_eval_env_t env, struct grecs_list *list)
{
struct forlan_value *val = list->head->data;
@@ -808,7 +809,7 @@ func_sort(forlan_eval_env_t env, struct grecs_list *list)
grecs_tree_sort(val->v.node, node_ident_cmp);
}
-void
+static void
func_decode(forlan_eval_env_t env, struct grecs_list *list)
{
struct forlan_value *val = list->head->data;
@@ -835,6 +836,23 @@ func_decode(forlan_eval_env_t env, struct grecs_list *list)
grecs_txtacc_free(acc);
}
+static void
+func_exit(forlan_eval_env_t env, struct grecs_list *list)
+{
+ struct forlan_value *val = list->head->data;
+ unsigned long code;
+ char *p;
+
+ code = strtoul(val->v.string, &p, 10);
+ if (*p || code > 255) {
+ err("invalid exit code \"%s\", assuming 255",
+ val->v.string);
+ code = 255;
+ }
+ env->exit_code = code;
+ longjmp(env->stop_buf, 1);
+}
+
static struct forlan_function functab[] = {
{ "dump", forlan_value_void, "n", 1, 1, func_dump },
{ "print", forlan_value_void, "", 1, -1, func_print },
@@ -842,6 +860,7 @@ static struct forlan_function functab[] = {
{ "parent", forlan_value_node, "n", 1, 1, func_parent },
{ "sort", forlan_value_void, "n", 1, 1, func_sort },
{ "decode", forlan_value_literal, "s", 1, 1, func_decode },
+ { "exit", forlan_value_void, "s", 1, 1, func_exit },
{ NULL }
};
@@ -864,7 +883,7 @@ forlan_eval(struct forlan_eval_env *env, union forlan_node *p)
f_tab[p->type].f_eval(env, p);
}
-void
+int
forlan_run(forlan_eval_env_t env, struct grecs_node *tree)
{
env->last = NULL;
@@ -875,6 +894,7 @@ forlan_run(forlan_eval_env_t env, struct grecs_node *tree)
if (setjmp(env->stop_buf) == 0)
forlan_eval(env, env->parse_tree);
free_value(&env->retval);
+ return env->exit_code;
}
forlan_eval_env_t

Return to:

Send suggestions and report system problems to the System administrator.