summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile4
-rw-r--r--ir.c37
-rw-r--r--ir.h2
-rw-r--r--test.lang4
-rwxr-xr-xwatch.sh14
6 files changed, 46 insertions, 18 deletions
diff --git a/.gitignore b/.gitignore
index d7756c2..5ab0e6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
-a.out
+lang
*.o
+out.pdf
diff --git a/Makefile b/Makefile
index 1130156..265c2f9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-EXE = a.out
+EXE = lang
RUNARGS = test.lang
CFLAGS = -std=c23 -Wall -Wextra -Wpedantic ${CFLAGS_${DEBUG}}
@@ -27,7 +27,7 @@ debug: ${EXE}
${GDB} -ex start --args ./${EXE} ${RUNARGS}
clean:
- rm -fv ${EXE} ${OBJ}
+ rm -fv ${EXE} ${OBJ} out.pdf
${EXE}: ${OBJ}
${CC} ${LDFLAGS} ${OBJ} -o ${EXE} ${LDLIBS}
diff --git a/ir.c b/ir.c
index 356a606..c4115b7 100644
--- a/ir.c
+++ b/ir.c
@@ -1,4 +1,5 @@
#include <stdarg.h>
+#include <stdbit.h>
#include <assert.h>
#include "ir.h"
@@ -10,20 +11,16 @@
void nodelist_fit(NodeList *l, u32 sz, Arena *a) {
if (l->cap) {
if (sz > l->cap) {
- u32 c = l->cap;
- while (sz > c) c <<= 1;
- l->data = resize(a, l->data, l->cap, c);
- l->cap = c;
- }
- } else {
- if (sz > 1) {
- u32 cap = 2;
- while (cap < sz) cap <<= 1;
- Node **data = new_arr(a, Node *, cap);
- data[0] = l->sbo;
- l->data = data;
+ u32 cap = stdc_bit_ceil(sz);
+ l->data = resize(a, l->data, l->cap, cap);
l->cap = cap;
}
+ } else if (sz > 1) {
+ u32 cap = stdc_bit_ceil(sz);
+ Node **data = new_arr(a, Node *, cap);
+ data[0] = l->sbo;
+ l->data = data;
+ l->cap = cap;
}
}
@@ -176,14 +173,26 @@ Node *node_new_empty(Graph *p, NodeType t) {
Node *node_newv(Graph *p, NodeType t, Node *ctrl, ...) {
Node *node = node_new_empty(p, t);
va_list ap;
+ /* do inputs all at once to decrease chance of arena_realloc() fragmenting */
+
va_start(ap, ctrl);
- node_add(p, ctrl, node);
+ node_add_in(p, node, ctrl);
for (;;) {
Node *n = va_arg(ap, Node *);
if (!n) break;
- node_add(p, n, node);
+ node_add_in(p, node, n);
}
va_end(ap);
+
+ va_start(ap, ctrl);
+ if (ctrl) node_add_out(p, ctrl, node);
+ for (;;) {
+ Node *n = va_arg(ap, Node *);
+ if (!n) break;
+ node_add_out(p, n, node);
+ }
+ va_end(ap);
+
return node;
}
diff --git a/ir.h b/ir.h
index eb9b6b7..ae91b6c 100644
--- a/ir.h
+++ b/ir.h
@@ -102,7 +102,7 @@ typedef enum {
const char *node_type_name(NodeType t);
typedef struct {
- unsigned len, cap;
+ u32 len, cap;
union {
struct Node *sbo;
struct Node **data;
diff --git a/test.lang b/test.lang
index e57f630..11f09d3 100644
--- a/test.lang
+++ b/test.lang
@@ -1,3 +1,7 @@
+func square(x i64) i64 {
+ return x * x
+}
+
func main(a, b i64) i64 {
if a < b {
let t = a
diff --git a/watch.sh b/watch.sh
new file mode 100755
index 0000000..896473d
--- /dev/null
+++ b/watch.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+gen() {
+ tcc ir.c lex.c impl.c peephole.c proc.c -run main.c test.lang\
+ | dot -Tpdf -o out.pdf
+}
+
+gen
+mupdf out.pdf &
+while true; do
+ inotifywait -e modify -r .
+ gen
+ killall -SIGHUP mupdf
+done