# 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 build/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 build/js/genome.json and the vm, 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 vsix the vscode extension, server and all # make clean remove bin/ and build/ and the web build # # nothing built is kept in the tree: the genome, the javascript vm and its # layout, and the packed editor server all land in build/ (the web build keeps # its historical src/web/zc.wasm path because the page loads it by name). # # 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 CFLAGS += -pthread MICRO_THREADS := -DZY_THREADS endif BIN := bin B := build JS := $(B)/js # the hand-written core headers, then the generated genome beside them COREINC := -Isrc/core -I$(B)/core # the sources the compiler genome is built from ZC_SRC := src/runtime/rt.zc src/core/core.zc src/compiler/compiler.zc 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 src/core/memmap.h | $(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) $(B)/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) $(COREINC) -o $@ # the portable microcore $(BIN)/zym$(EXE): src/micro/micro.c src/micro/micro_port.h $(PORT) $(B)/core/genome.h src/core/memmap.h src/core/fops.h src/core/bops.h src/core/stack.h | $(BIN) $(CC) $(CFLAGS) $(MICRO_THREADS) src/micro/micro.c $(PORT) $(COREINC) -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/core/core.zc src/compiler/compiler.zc src/lsp/server.zc src/lib/std.zc src/lib/icon.zc src/tools/embed.sh 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) $@ src/compiler/compiler.zc: src/lib/std.zc src/lib/icon.zc src/tools/embed.sh bash src/tools/embed.sh all # 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 build/core/genome.h. # run this by hand after editing a .zc source; `make check` reports a stale genome. genome: $(BIN)/zc0$(EXE) $(BIN)/mkgenome$(EXE) src/compiler/compiler.zc | $(B) mkdir -p $(B)/s0 $(B)/s1 $(B)/core 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 $(ZC_SRC) | $(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 $(ZC_SRC)) | $(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 $(ZC_SRC)) | $(B)/zy1$(EXE) > $(B)/g2.bin cmp $(B)/g1.bin $(B)/g2.bin cp $(B)/s1/genome.h $(B)/core/genome.h @echo "fixpoint: $$(( $$(wc -c < $(B)/g1.bin) / 8 )) words, $(B)/core/genome.h updated" # a fresh clone has no genome, so bootstrap one on demand. it is deliberately # not rebuilt from source dependencies: the fixpoint run is expensive, and # `make genome` is the explicit way to refresh it after editing a .zc file. $(B)/core/genome.h: $(MAKE) genome js: $(JS)/genome.json $(JS)/layout.js $(JS)/tinyvm.js $(JS): mkdir -p $@ $(JS)/genome.json: $(B)/core/genome.h src/core/memmap.h src/js/extract_genome.js src/js/mapvalues.js | $(JS) node src/js/extract_genome.js $(JS)/layout.ts $(JS)/layout.js: $(JS)/genome.json @test -f $@ || node src/js/extract_genome.js $(JS)/tinyvm.js: src/js/tinyvm.ts src/js/layout.d.ts | $(JS) tsc src/js/tinyvm.ts --target es2020 --lib es2020,dom --module commonjs --outDir $(JS) # the language server image for the javascript vm, and the wasm server lspimage: $(JS)/lsp.json $(JS)/lsp.json: $(BIN)/zclsp$(EXE) src/js/extract_lsp.js src/js/mapvalues.js | $(JS) node src/js/extract_lsp.js # the vscode extension, with the server and its image inside it vsix: | $(B) bash src/tools/mkvsix.sh 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 $(B)/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) $(MICRO_THREADS) $(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 lspimage vsix web run test check clean