aboutsummaryrefslogtreecommitdiff
path: root/ell.c
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2017-05-25 19:41:27 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2017-05-25 19:41:27 +0200
commit4358e6f324a6765b7da69ba28b891584531e710e (patch)
tree2ffcf6bef079b8bd554d69c81aba0531b011949c /ell.c
parent5ae69c1cfcc05f3dce30a60fcfe38ce6de7a799d (diff)
downloadell-4358e6f324a6765b7da69ba28b891584531e710e.tar.gz
ell-4358e6f324a6765b7da69ba28b891584531e710e.tar.xz
ell-4358e6f324a6765b7da69ba28b891584531e710e.zip
Simplify runtime library initialization
And remove the error printing side effect, just like that, at a cost.
Diffstat (limited to 'ell.c')
-rw-r--r--ell.c115
1 files changed, 52 insertions, 63 deletions
diff --git a/ell.c b/ell.c
index 1b66f72..99b0867 100644
--- a/ell.c
+++ b/ell.c
@@ -1244,70 +1244,59 @@ defn (fn_less) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+const char init_program[] =
+ "set unless { arg _cond _body; if (not (@_cond)) @_body }\n"
+ "set filter { arg _body _list\n"
+ " map { arg _i; if (@_body @_i) { @_i } } @_list }\n"
+ "set for { arg _list _body\n"
+ " try { map { arg _i; @_body @_i } @_list } {\n"
+ " arg _e; if (ne? @_e _break) { throw @e } } }\n"
+ "set break { throw _break }\n"
+
+ // TODO: we should be able to apply them to all arguments
+ "set ne? { arg _ne1 _ne2; not (eq? @_ne1 @_ne2) }\n"
+ "set ge? { arg _ge1 _ge2; not (lt? @_ge1 @_ge2) }\n"
+ "set le? { arg _le1 _le2; ge? @_le2 @_le1 }\n"
+ "set gt? { arg _gt1 _gt2; lt? @_gt2 @_gt1 }\n"
+ "set <> { arg _<>1 _<>2; not (= @_<>1 @_<>2) }\n"
+ "set >= { arg _>=1 _>=2; not (< @_>=1 @_>=2) }\n"
+ "set <= { arg _<=1 _<=2; >= @_<=2 @_<=1 }\n"
+ "set > { arg _>1 _>2; < @_>2 @_>1 }\n";
+
static bool
init_runtime_library (struct context *ctx) {
- struct {
- const char *name; ///< Name of the function
- const char *definition; ///< The defining script
- } functions[] = {
- { "unless", "arg _cond _body; if (not (@_cond)) @_body" },
- { "filter", "arg _body _list;"
- "map { arg _i; if (@_body @_i) { @_i } } @_list" },
- { "for", "arg _list _body;"
- "try { map {arg _i; @_body @_i } @_list"
- "} { arg _e; if (ne? @_e _break) { throw @e } }" },
- { "break", "throw _break" },
- // TODO: we should be able to apply them to all arguments
- { "ne?", "arg _ne1 _ne2; not (eq? @_ne1 @_ne2)" },
- { "ge?", "arg _ge1 _ge2; not (lt? @_ge1 @_ge2)" },
- { "le?", "arg _le1 _le2; ge? @_le2 @_le1" },
- { "gt?", "arg _gt1 _gt2; lt? @_gt2 @_gt1" },
- { "<>", "arg _<>1 _<>2; not (= @_<>1 @_<>2)" },
- { ">=", "arg _>=1 _>=2; not (< @_>=1 @_>=2)" },
- { "<=", "arg _<=1 _<=2; >= @_<=2 @_<=1" },
- { ">", "arg _>1 _>2; < @_>2 @_>1" },
- };
-
- bool ok = true;
- for (size_t i = 0; i < N_ELEMENTS (functions); i++) {
- struct parser parser;
- parser_init (&parser,
- functions[i].definition, strlen (functions[i].definition));
- const char *e = NULL;
- struct item *body = parser_run (&parser, &e);
- if (e) {
- printf ("error parsing internal function `%s': %s\n",
- functions[i].name, e);
- ok = false;
- } else if (!check (ctx, (body = new_list (body)))
- || !set (ctx, functions[i].name, body)) {
- ok = false;
- } else
- body = NULL;
- item_free_list (body);
- parser_free (&parser);
- }
+ if (!native_register (ctx, "set", fn_set)
+ || !native_register (ctx, "list", fn_list)
+ || !native_register (ctx, "if", fn_if)
+ || !native_register (ctx, "map", fn_map)
+ || !native_register (ctx, "print", fn_print)
+ || !native_register (ctx, "..", fn_concatenate)
+ || !native_register (ctx, "system", fn_system)
+ || !native_register (ctx, "parse", fn_parse)
+ || !native_register (ctx, "try", fn_try)
+ || !native_register (ctx, "throw", fn_throw)
+ || !native_register (ctx, "+", fn_plus)
+ || !native_register (ctx, "-", fn_minus)
+ || !native_register (ctx, "*", fn_multiply)
+ || !native_register (ctx, "/", fn_divide)
+ || !native_register (ctx, "not", fn_not)
+ || !native_register (ctx, "and", fn_and)
+ || !native_register (ctx, "or", fn_or)
+ || !native_register (ctx, "eq?", fn_eq)
+ || !native_register (ctx, "lt?", fn_lt)
+ || !native_register (ctx, "=", fn_equals)
+ || !native_register (ctx, "<", fn_less))
+ return false;
- return ok
- && native_register (ctx, "set", fn_set)
- && native_register (ctx, "list", fn_list)
- && native_register (ctx, "if", fn_if)
- && native_register (ctx, "map", fn_map)
- && native_register (ctx, "print", fn_print)
- && native_register (ctx, "..", fn_concatenate)
- && native_register (ctx, "system", fn_system)
- && native_register (ctx, "parse", fn_parse)
- && native_register (ctx, "try", fn_try)
- && native_register (ctx, "throw", fn_throw)
- && native_register (ctx, "+", fn_plus)
- && native_register (ctx, "-", fn_minus)
- && native_register (ctx, "*", fn_multiply)
- && native_register (ctx, "/", fn_divide)
- && native_register (ctx, "not", fn_not)
- && native_register (ctx, "and", fn_and)
- && native_register (ctx, "or", fn_or)
- && native_register (ctx, "eq?", fn_eq)
- && native_register (ctx, "lt?", fn_lt)
- && native_register (ctx, "=", fn_equals)
- && native_register (ctx, "<", fn_less);
+ struct parser parser;
+ parser_init (&parser, init_program, sizeof init_program);
+
+ const char *e = NULL;
+ struct item *result = NULL;
+ struct item *program = parser_run (&parser, &e);
+ bool ok = !e && execute (ctx, program, &result);
+ parser_free (&parser);
+ item_free_list (program);
+ item_free_list (result);
+ return ok;
}