summaryrefslogtreecommitdiffhomepage
path: root/compiler.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-01-18 10:42:46 +0100
committerJo-Philipp Wich <jo@mein.io>2022-01-18 11:21:20 +0100
commit3578afee0ab77650cf6adf3987a6f653f9311e9b (patch)
tree4c57d279a8b54df10e6b194b586d3f6423d8e7cd /compiler.c
parent371ba457917cf319b74de5a56e17782f6c4cd77a (diff)
build: support building without compile capabilities
Introduce a new default enable CMake option "COMPILE_SUPPORT" which allows to disable source code compilation in the ucode interpreter. Such an interpreter will only be able to load precompiled ucode files. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'compiler.c')
-rw-r--r--compiler.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/compiler.c b/compiler.c
index 119e7f7..c5b0ee5 100644
--- a/compiler.c
+++ b/compiler.c
@@ -24,6 +24,8 @@
#include "ucode/program.h"
#include "ucode/lib.h" /* uc_error_context_format() */
+#ifndef NO_COMPILE
+
static void uc_compiler_compile_unary(uc_compiler_t *compiler);
static void uc_compiler_compile_binary(uc_compiler_t *compiler);
static void uc_compiler_compile_delete(uc_compiler_t *compiler);
@@ -2865,56 +2867,85 @@ uc_compiler_compile_declaration(uc_compiler_t *compiler)
uc_compiler_parse_synchronize(compiler);
}
-uc_function_t *
-uc_compile(uc_parse_config_t *config, uc_source_t *source, char **errp)
+#endif /* NO_COMPILE */
+
+
+static uc_function_t *
+uc_compile_from_source(uc_parse_config_t *config, uc_source_t *source, char **errp)
{
+#ifdef NO_COMPILE
+ if (errp)
+ xasprintf(errp, "Source code compilation not supported\n");
+
+ return NULL;
+#else
+ uc_function_t *fn = NULL;
uc_exprstack_t expr = { .token = TK_EOF };
uc_parser_t parser = { .config = config };
uc_compiler_t compiler = { .parser = &parser, .exprstack = &expr };
- uc_function_t *fn = NULL;
uc_program_t *prog;
- switch (uc_source_type_test(source)) {
- case UC_SOURCE_TYPE_PLAIN:
- prog = uc_program_new(source);
+ prog = uc_program_new(source);
- uc_lexer_init(&parser.lex, config, source);
- uc_compiler_init(&compiler, "main", 0, prog,
- config && config->strict_declarations);
+ uc_lexer_init(&parser.lex, config, source);
+ uc_compiler_init(&compiler, "main", 0, prog,
+ config && config->strict_declarations);
- uc_compiler_parse_advance(&compiler);
+ uc_compiler_parse_advance(&compiler);
- while (!uc_compiler_parse_match(&compiler, TK_EOF))
- uc_compiler_compile_declaration(&compiler);
+ while (!uc_compiler_parse_match(&compiler, TK_EOF))
+ uc_compiler_compile_declaration(&compiler);
- fn = uc_compiler_finish(&compiler);
+ fn = uc_compiler_finish(&compiler);
- if (errp) {
- *errp = parser.error ? parser.error->buf : NULL;
- free(parser.error);
- }
- else {
- printbuf_free(parser.error);
- }
+ if (errp) {
+ *errp = parser.error ? parser.error->buf : NULL;
+ free(parser.error);
+ }
+ else {
+ printbuf_free(parser.error);
+ }
- uc_lexer_free(&parser.lex);
+ uc_lexer_free(&parser.lex);
- break;
+ return fn;
+#endif
+}
- case UC_SOURCE_TYPE_PRECOMPILED:
- prog = uc_program_from_file(source->fp, errp);
+static uc_function_t *
+uc_compile_from_bytecode(uc_parse_config_t *config, uc_source_t *source, char **errp)
+{
+ uc_function_t *fn = NULL;
+ uc_program_t *prog;
- if (prog) {
- fn = uc_program_entry(prog);
+ prog = uc_program_from_file(source->fp, errp);
- if (!fn) {
- if (errp)
- xasprintf(errp, "Program file contains no entry function\n");
+ if (prog) {
+ fn = uc_program_entry(prog);
- uc_program_free(prog);
- }
+ if (!fn) {
+ if (errp)
+ xasprintf(errp, "Program file contains no entry function\n");
+
+ uc_program_free(prog);
}
+ }
+
+ return fn;
+}
+uc_function_t *
+uc_compile(uc_parse_config_t *config, uc_source_t *source, char **errp)
+{
+ uc_function_t *fn = NULL;
+
+ switch (uc_source_type_test(source)) {
+ case UC_SOURCE_TYPE_PLAIN:
+ fn = uc_compile_from_source(config, source, errp);
+ break;
+
+ case UC_SOURCE_TYPE_PRECOMPILED:
+ fn = uc_compile_from_bytecode(config, source, errp);
break;
default: