summaryrefslogtreecommitdiffhomepage
path: root/source.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-01-15 21:22:37 +0100
committerJo-Philipp Wich <jo@mein.io>2022-01-18 11:21:20 +0100
commit371ba457917cf319b74de5a56e17782f6c4cd77a (patch)
treea5d5e14355c43849daa3236103817f0bb3025955 /source.c
parent6c2caf9fbb9d346cfb20cd5c83875fdff77e584c (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.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/source.c b/source.c
index aa73efd..3b35b70 100644
--- a/source.c
+++ b/source.c
@@ -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;
}