summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--compiler.c93
-rw-r--r--lexer.c112
3 files changed, 126 insertions, 85 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1430a61..0621d51 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,12 @@ ADD_DEFINITIONS(-Wmissing-declarations -Wno-error=unused-variable -Wno-unused-pa
INCLUDE_DIRECTORIES(include)
+OPTION(COMPILE_SUPPORT "Support compilation from source" ON)
+
+IF(NOT COMPILE_SUPPORT)
+ ADD_DEFINITIONS(-DNO_COMPILE)
+ENDIF()
+
OPTION(FS_SUPPORT "Filesystem plugin support" ON)
OPTION(MATH_SUPPORT "Math plugin support" ON)
OPTION(UBUS_SUPPORT "Ubus plugin support" ON)
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:
diff --git a/lexer.c b/lexer.c
index d554c0d..6c665c8 100644
--- a/lexer.c
+++ b/lexer.c
@@ -54,6 +54,8 @@ struct token {
(((x) >= 'a') ? (10 + (x) - 'a') : \
(((x) >= 'A') ? (10 + (x) - 'A') : dec(x)))
+#ifndef NO_COMPILE
+
static uc_token_t *parse_comment(uc_lexer_t *);
static uc_token_t *parse_string(uc_lexer_t *);
static uc_token_t *parse_regexp(uc_lexer_t *);
@@ -165,60 +167,6 @@ static const struct keyword reserved_words[] = {
};
-/*
- * Stores the given codepoint as a utf8 multibyte sequence into the given
- * output buffer and substracts the required amount of bytes from the given
- * length pointer.
- *
- * Returns false if the multibyte sequence would not fit into the buffer,
- * otherwise true.
- */
-
-bool
-utf8enc(char **out, int *rem, int code)
-{
- if (code >= 0 && code <= 0x7F) {
- if (*rem < 1)
- return false;
-
- *(*out)++ = code; (*rem)--;
-
- return true;
- }
- else if (code > 0 && code <= 0x7FF) {
- if (*rem < 2)
- return false;
-
- *(*out)++ = ((code >> 6) & 0x1F) | 0xC0; (*rem)--;
- *(*out)++ = ( code & 0x3F) | 0x80; (*rem)--;
-
- return true;
- }
- else if (code > 0 && code <= 0xFFFF) {
- if (*rem < 3)
- return false;
-
- *(*out)++ = ((code >> 12) & 0x0F) | 0xE0; (*rem)--;
- *(*out)++ = ((code >> 6) & 0x3F) | 0x80; (*rem)--;
- *(*out)++ = ( code & 0x3F) | 0x80; (*rem)--;
-
- return true;
- }
- else if (code > 0 && code <= 0x10FFFF) {
- if (*rem < 4)
- return false;
-
- *(*out)++ = ((code >> 18) & 0x07) | 0xF0; (*rem)--;
- *(*out)++ = ((code >> 12) & 0x3F) | 0x80; (*rem)--;
- *(*out)++ = ((code >> 6) & 0x3F) | 0x80; (*rem)--;
- *(*out)++ = ( code & 0x3F) | 0x80; (*rem)--;
-
- return true;
- }
-
- return true;
-}
-
/* length of the longest token in our lookup table */
#define UC_LEX_MAX_TOKEN_LEN 3
@@ -1187,3 +1135,59 @@ uc_lexer_is_keyword(uc_value_t *label)
return false;
}
+
+#endif /* NO_COMPILE */
+
+/*
+ * Stores the given codepoint as a utf8 multibyte sequence into the given
+ * output buffer and substracts the required amount of bytes from the given
+ * length pointer.
+ *
+ * Returns false if the multibyte sequence would not fit into the buffer,
+ * otherwise true.
+ */
+
+bool
+utf8enc(char **out, int *rem, int code)
+{
+ if (code >= 0 && code <= 0x7F) {
+ if (*rem < 1)
+ return false;
+
+ *(*out)++ = code; (*rem)--;
+
+ return true;
+ }
+ else if (code > 0 && code <= 0x7FF) {
+ if (*rem < 2)
+ return false;
+
+ *(*out)++ = ((code >> 6) & 0x1F) | 0xC0; (*rem)--;
+ *(*out)++ = ( code & 0x3F) | 0x80; (*rem)--;
+
+ return true;
+ }
+ else if (code > 0 && code <= 0xFFFF) {
+ if (*rem < 3)
+ return false;
+
+ *(*out)++ = ((code >> 12) & 0x0F) | 0xE0; (*rem)--;
+ *(*out)++ = ((code >> 6) & 0x3F) | 0x80; (*rem)--;
+ *(*out)++ = ( code & 0x3F) | 0x80; (*rem)--;
+
+ return true;
+ }
+ else if (code > 0 && code <= 0x10FFFF) {
+ if (*rem < 4)
+ return false;
+
+ *(*out)++ = ((code >> 18) & 0x07) | 0xF0; (*rem)--;
+ *(*out)++ = ((code >> 12) & 0x3F) | 0x80; (*rem)--;
+ *(*out)++ = ((code >> 6) & 0x3F) | 0x80; (*rem)--;
+ *(*out)++ = ( code & 0x3F) | 0x80; (*rem)--;
+
+ return true;
+ }
+
+ return true;
+}