diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-01-15 21:22:37 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2022-01-18 11:21:20 +0100 |
commit | 371ba457917cf319b74de5a56e17782f6c4cd77a (patch) | |
tree | a5d5e14355c43849daa3236103817f0bb3025955 /source.c | |
parent | 6c2caf9fbb9d346cfb20cd5c83875fdff77e584c (diff) |
program: implement support for precompiling source files
- Introduce new command line flags `-o` and `-O` to write compiled program
code into the specified output file
- Add support for transparently executing precompiled files, the
lexical analyzing and com,pilation phase is skipped in this case
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'source.c')
-rw-r--r-- | source.c | 25 |
1 files changed, 19 insertions, 6 deletions
@@ -16,6 +16,7 @@ #include <string.h> #include <errno.h> +#include <endian.h> #include "ucode/source.h" @@ -124,7 +125,8 @@ uc_source_type_test(uc_source_t *source) union { char s[sizeof(uint32_t)]; uint32_t n; } buf; uc_source_type_t type = UC_SOURCE_TYPE_PLAIN; FILE *fp = source->fp; - int c; + size_t rlen; + int c = 0; if (fread(buf.s, 1, 2, fp) == 2 && !strncmp(buf.s, "#!", 2)) { source->off += 2; @@ -132,12 +134,8 @@ uc_source_type_test(uc_source_t *source) while ((c = fgetc(fp)) != EOF) { source->off++; - if (c == '\n') { - uc_source_line_update(source, source->off); - uc_source_line_next(source); - + if (c == '\n') break; - } } } else { @@ -145,6 +143,21 @@ uc_source_type_test(uc_source_t *source) fprintf(stderr, "Failed to rewind source buffer: %s\n", strerror(errno)); } + rlen = fread(buf.s, 1, 4, fp); + + if (rlen == 4 && buf.n == htobe32(UC_PRECOMPILED_BYTECODE_MAGIC)) { + type = UC_SOURCE_TYPE_PRECOMPILED; + } + else { + uc_source_line_update(source, source->off); + + if (c == '\n') + uc_source_line_next(source); + } + + if (fseek(fp, -(long)rlen, SEEK_CUR) == -1) + fprintf(stderr, "Failed to rewind source buffer: %s\n", strerror(errno)); + return type; } |