aboutsummaryrefslogtreecommitdiff
path: root/Makefile
blob: 6c42e620672086b367e14c25cf63ba5b2a0e4d2a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# tinyvm and zc. `make` builds the tools, the interpreter, the microcore and the
# language server into bin/. nothing built is kept in the tree.
#
#   make                 everything below that is a program
#   make test            the whole suite (tests/test.sh)
#   make check           the minimal suite, for iterating (tests/test.sh -q)
#   make test JOBS=4     the same, four sections at a time
#   make genome          rebuild src/core/genome.h from src/ and check the fixpoint
#   make lsp             bin/zclsp, the language server
#   make web             src/web/zc.wasm (needs clang with the wasm32 target)
#   make js              src/js/genome.json, for the javascript vm
#   make run PROG=examples/hello.zc
#                        compile one program into a run-only image on a memory
#                        map sized to it (src/tools/automap.sh) -> build/run/zymr
#   make clean           remove bin/ and build/ and the web build
#
# CC picks the compiler (cc by default; clang works too).

CC     ?= cc
CFLAGS ?= -O2 -w -fwrapv
ifeq ($(OS),Windows_NT)
  EXE := .exe
  IO  := src/core/io_win.c
  PORT := src/micro/port_win.c
else
  EXE :=
  IO  := src/core/io_linux.c
  PORT := src/micro/port_linux.c
endif

BIN := bin
B   := build

TOOLS := $(BIN)/zc0$(EXE) $(BIN)/mkgenome$(EXE) $(BIN)/genmap$(EXE)
PROGS := $(BIN)/zy$(EXE) $(BIN)/zym$(EXE) $(BIN)/zclsp$(EXE)

all: $(TOOLS) $(PROGS)

$(BIN) $(B):
	mkdir -p $@

$(BIN)/zc0$(EXE): src/tools/zc0.c src/core/memmap.h src/core/fops.h src/core/bops.h | $(BIN)
	$(CC) -O1 -w -fwrapv src/tools/zc0.c -Isrc/core -o $@
$(BIN)/mkgenome$(EXE): src/tools/mkgenome.c | $(BIN)
	$(CC) -O1 -w -fwrapv src/tools/mkgenome.c -Isrc/core -o $@
$(BIN)/genmap$(EXE): src/tools/genmap.c | $(BIN)
	$(CC) $(CFLAGS) src/tools/genmap.c -Isrc/core -o $@

# the interpreter: the vm core with the compiler genome inside
$(BIN)/zy$(EXE): src/core/core.c $(IO) src/core/genome.h src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h | $(BIN)
	$(CC) $(CFLAGS) -DJTYPE=int src/core/core.c $(IO) -Isrc/core -o $@
# the portable microcore
$(BIN)/zym$(EXE): src/micro/micro.c src/micro/micro_port.h $(PORT) src/core/genome.h src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h | $(BIN)
	$(CC) $(CFLAGS) src/micro/micro.c $(PORT) -Isrc/core -Isrc/micro -o $@

# the language server is the compiler in check mode plus src/lsp/server.zc, on a map
# sized to it
lsp: $(BIN)/zclsp$(EXE)
$(BIN)/zclsp$(EXE): src/core/core.c src/core/io_linux.c src/core/fops.h src/core/bops.h src/core/stack.h src/core/memmap.h src/runtime/rt.zc src/compiler/compiler.zc src/lsp/server.zc src/tools/zc0.c src/tools/genmap.c src/tools/automap.sh src/tools/mklsp.sh | $(BIN)
	CC="$(CC)" bash src/tools/mklsp.sh $(B)/lsp
	cp $(B)/lsp/zclsp$(EXE) $@

# bootstrap: zc0 compiles the compiler to g0, g0 compiles it to g1, g1 to g2.
# g1 and g2 must be identical (the fixpoint), and g1 becomes src/core/genome.h.
genome: $(BIN)/zc0$(EXE) $(BIN)/mkgenome$(EXE) | $(B)
	mkdir -p $(B)/s0 $(B)/s1
	cp src/core/core.c $(IO) src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h $(B)/s0/
	cp src/core/core.c $(IO) src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h $(B)/s1/
	cat src/runtime/rt.zc src/compiler/compiler.zc | $(BIN)/zc0$(EXE) > $(B)/s0/genome.h
	$(CC) $(CFLAGS) -DJTYPE=int $(B)/s0/core.c $(B)/s0/$(notdir $(IO)) -o $(B)/zy0$(EXE)
	(cat src/tools/build.zc; printf '`'; cat src/runtime/rt.zc src/compiler/compiler.zc) | $(B)/zy0$(EXE) > $(B)/g1.bin
	$(BIN)/mkgenome$(EXE) < $(B)/g1.bin > $(B)/s1/genome.h
	$(CC) $(CFLAGS) -DJTYPE=int $(B)/s1/core.c $(B)/s1/$(notdir $(IO)) -o $(B)/zy1$(EXE)
	(cat src/tools/build.zc; printf '`'; cat src/runtime/rt.zc src/compiler/compiler.zc) | $(B)/zy1$(EXE) > $(B)/g2.bin
	cmp $(B)/g1.bin $(B)/g2.bin
	cp $(B)/s1/genome.h src/core/genome.h
	@echo "fixpoint: $$(( $$(wc -c < $(B)/g1.bin) / 8 )) words, src/core/genome.h updated"

js: src/js/genome.json src/js/layout.ts src/js/layout.js src/js/tinyvm.js
src/js/genome.json: src/core/genome.h src/core/memmap.h src/js/extract_genome.js src/js/mapvalues.js
	node src/js/extract_genome.js
src/js/layout.ts: src/js/genome.json
	@test -f $@ || node src/js/extract_genome.js
src/js/layout.js: src/js/layout.ts
	@test -f $@ || node src/js/extract_genome.js
src/js/tinyvm.js: src/js/tinyvm.ts src/js/layout.ts
	tsc src/js/tinyvm.ts --target es2020 --lib es2020,dom --module commonjs --outDir src/js

web: src/web/zc.wasm
src/web/zc.wasm: src/micro/micro.c src/micro/micro_port.h src/web/port_wasm.c src/web/build.sh src/core/genome.h src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h
	bash src/web/build.sh $@

# one program as a run-only image: the runtime, the program, and a map exactly
# big enough for them
run: | $(B)
	@test -n "$(PROG)" || { echo "make run PROG=examples/hello.zc"; exit 2; }
	bash src/tools/automap.sh run $(B)/run src/runtime/run.zc $(PROG)
	cp src/micro/micro.c src/micro/micro_port.h $(PORT) src/core/fops.h src/core/bops.h src/core/stack.h $(B)/run/
	$(CC) $(CFLAGS) $(B)/run/micro.c $(B)/run/$(notdir $(PORT)) -I$(B)/run -o $(B)/run/zymr$(EXE)
	@echo "built $(B)/run/zymr$(EXE)"

# JOBS sets how many sections run at once: make test JOBS=4
test:
	bash tests/test.sh -j $(or $(JOBS),1)

# the minimal suite: bootstrap, fixpoint, interpreter and lsp checks
check:
	bash tests/test.sh -q -j $(or $(JOBS),2)

clean:
	rm -rf $(BIN) $(B) src/web/zc.wasm

.PHONY: all lsp genome js web run test check clean