summaryrefslogtreecommitdiffstats
path: root/bytecode/bytecode.c
diff options
context:
space:
mode:
authorRose Hogenson <rhogenson@posteo.net>2023-02-11 09:41:54 -0800
committerRose Hogenson <rhogenson@posteo.net>2023-02-11 09:41:54 -0800
commit4c3b2fec322feb8afd23703866d81f1dda51b6ae (patch)
treecae4d14c66f639c13198a4bfafc9425cb8aa70bf /bytecode/bytecode.c
parentddb69212f03a82e980144594d809a072b50e7f19 (diff)
downloadsml-4c3b2fec322feb8afd23703866d81f1dda51b6ae.tar.zst
Add a bytecode interpreter.
I wrote it in C because I actually like programming in C. Turns out setting up a Makefile is really easy too.
Diffstat (limited to 'bytecode/bytecode.c')
-rw-r--r--bytecode/bytecode.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/bytecode/bytecode.c b/bytecode/bytecode.c
new file mode 100644
index 0000000..a21231b
--- /dev/null
+++ b/bytecode/bytecode.c
@@ -0,0 +1,71 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "oper.h"
+#include "panic.h"
+#include "slice.h"
+
+static struct slice xmalloc(size_t size)
+{
+ void *p = malloc(size);
+ if (!p) {
+ panicf("Out of memory!\n");
+ }
+ return (struct slice) {
+ .buf = p,
+ .size = size,
+ };
+}
+
+static struct slice xrealloc(void *ptr, size_t size)
+{
+ void *p = realloc(ptr, size);
+ if (!p) {
+ panicf("Out of memory!\n");
+ }
+ return (struct slice) {
+ .buf = p,
+ .size = size,
+ };
+}
+
+void read_file(struct slice *out, char *filename)
+{
+ FILE *f = fopen(filename, "r");
+ if (!f) {
+ panicf("File %s does not exit!\n", filename);
+ }
+ size_t offset = 0;
+ while (true) {
+ if (offset >= out->size) {
+ size_t new_size = 2 * out->size;
+ *out = xrealloc(out->buf, new_size);
+ }
+ size_t read_size = out->size - offset;
+ size_t n = fread(out->buf + offset, 1, read_size, f);
+ if (n < read_size) {
+ if (ferror(f)) {
+ panicf("Read error!\n");
+ }
+ out->size = offset + n;
+ return;
+ }
+ offset += n;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ if (argc < 2) {
+ printf("Usage error: need a filename.\n");
+ return 1;
+ }
+
+ struct slice program = xmalloc(1);
+ read_file(&program, argv[1]);
+
+ run(program);
+
+ free(program.buf);
+}