diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2017-05-25 19:41:27 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2017-05-25 19:41:27 +0200 |
commit | 4358e6f324a6765b7da69ba28b891584531e710e (patch) | |
tree | 2ffcf6bef079b8bd554d69c81aba0531b011949c /ell.c | |
parent | 5ae69c1cfcc05f3dce30a60fcfe38ce6de7a799d (diff) | |
download | ell-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.c | 115 |
1 files changed, 52 insertions, 63 deletions
@@ -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; } |