summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-09-17 13:57:22 +0200
committerJo-Philipp Wich <jo@mein.io>2020-09-20 20:45:26 +0200
commit9a74b811f007986a3e6015af0c06b33147d05951 (patch)
tree43e794cb1f35582c98eab8f8a1f4d54299cf2557
parent2601b1e17f5ba2e15fb16e126ec5d22a39246649 (diff)
eval: implement -m option to preload modules
The -m option instructs the interpreter to automatically require the named module and to register the module context as global variable. The following two commands are equivalent, with the former one serving as a shortcut for the latter: utpl -m fs -s '{{ fs.open("test.txt").read("all") }}' utpl -s '{% fs = require("fs"); print(fs.open("test.txt").read("all")) %}' Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--eval.c20
-rw-r--r--eval.h2
-rw-r--r--main.c23
3 files changed, 37 insertions, 8 deletions
diff --git a/eval.c b/eval.c
index c05d80a..c8a5910 100644
--- a/eval.c
+++ b/eval.c
@@ -1557,10 +1557,11 @@ ut_register_variable(struct json_object *scope, const char *key, struct json_obj
}
enum ut_error_type
-ut_run(struct ut_state *state, struct json_object *env)
+ut_run(struct ut_state *state, struct json_object *env, struct json_object *modules)
{
struct ut_op *op = ut_get_op(state, state->main);
struct json_object *entry, *scope, *args, *rv;
+ size_t i;
if (!op || op->type != T_FUNC) {
ut_exception(state, state->main, "Runtime error: Invalid root operation in AST");
@@ -1589,6 +1590,23 @@ ut_run(struct ut_state *state, struct json_object *env)
ut_lib_init(state, scope);
args = json_object_new_array();
+
+ if (modules) {
+ for (i = 0; i < json_object_array_length(modules); i++) {
+ json_object_array_put_idx(args, 0, json_object_get(json_object_array_get_idx(modules, i)));
+
+ rv = ut_invoke(state, state->main, NULL,
+ json_object_object_get(scope, "require"),
+ args);
+
+ ut_register_variable(scope,
+ json_object_get_string(json_object_array_get_idx(modules, i)),
+ rv);
+ }
+
+ json_object_array_del_idx(args, 0, 1);
+ }
+
rv = ut_invoke(state, state->main, NULL, entry, args);
json_object_put(entry);
diff --git a/eval.h b/eval.h
index 090a4db..26f932f 100644
--- a/eval.h
+++ b/eval.h
@@ -43,6 +43,6 @@ struct json_object *
ut_invoke(struct ut_state *, uint32_t, struct json_object *, struct json_object *, struct json_object *);
enum ut_error_type
-ut_run(struct ut_state *state, struct json_object *env);
+ut_run(struct ut_state *state, struct json_object *env, struct json_object *modules);
#endif
diff --git a/main.c b/main.c
index f065bf6..0ce2a7d 100644
--- a/main.c
+++ b/main.c
@@ -47,7 +47,8 @@ print_usage(char *app)
" -r Do not trim trailing block newlines\n"
" -S Enable strict mode\n"
" -e Set global variables from given JSON object\n"
- " -E Set global variables from given JSON file\n",
+ " -E Set global variables from given JSON file\n"
+ " -m Preload given module\n",
app);
}
@@ -141,7 +142,8 @@ static void dump(struct ut_state *s, uint32_t off, int level) {
#endif /* NDEBUG */
static enum ut_error_type
-parse(struct ut_state *state, const char *source, bool dumponly, struct json_object *env)
+parse(struct ut_state *state, const char *source, bool dumponly,
+ struct json_object *env, struct json_object *modules)
{
enum ut_error_type err;
char *msg;
@@ -158,7 +160,7 @@ parse(struct ut_state *state, const char *source, bool dumponly, struct json_obj
#endif /* NDEBUG */
}
else {
- err = ut_run(state, env);
+ err = ut_run(state, env, modules);
}
}
@@ -232,7 +234,7 @@ int
main(int argc, char **argv)
{
char *srcstr = NULL, *srcfile = NULL, *envstr = NULL;
- struct json_object *env = NULL, *o;
+ struct json_object *env = NULL, *modules = NULL, *o;
struct ut_state *state;
bool dumponly = false;
int opt, rv = 0;
@@ -253,7 +255,7 @@ main(int argc, char **argv)
state->lstrip_blocks = 1;
state->trim_blocks = 1;
- while ((opt = getopt(argc, argv, "dhlrSe:E:i:s:")) != -1)
+ while ((opt = getopt(argc, argv, "dhlrSe:E:i:s:m:")) != -1)
{
switch (opt) {
case 'h':
@@ -322,6 +324,13 @@ main(int argc, char **argv)
json_object_object_add(env, key, val);
break;
+
+ case 'm':
+ modules = modules ? modules : json_object_new_array();
+
+ json_object_array_add(modules, json_object_new_string(optarg));
+
+ break;
}
}
@@ -332,9 +341,11 @@ main(int argc, char **argv)
goto out;
}
- rv = parse(state, srcstr ? srcstr : srcfile, dumponly, env);
+ rv = parse(state, srcstr ? srcstr : srcfile, dumponly, env, modules);
out:
+ json_object_put(modules);
+ json_object_put(env);
free(srcfile);
return rv;