diff options
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | compiler.c | 93 | ||||
-rw-r--r-- | lexer.c | 112 |
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) @@ -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: @@ -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; +} |