Skip to content

Commit

Permalink
Merge pull request #44 from billhails/poke-the-bear
Browse files Browse the repository at this point in the history
Poke the bear
  • Loading branch information
billhails authored Jan 24, 2024
2 parents 5282001 + 7dcbc42 commit 0e3b70d
Show file tree
Hide file tree
Showing 44 changed files with 210 additions and 14,126 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ out_scm/
tmp_scm/
cekf
tags
.generated
.*.swp
.$*.drawio.*
callgrind.out.*
Expand Down
47 changes: 41 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,23 @@ CCMODE = $(DEBUGGING)
CC=cc -Wall -Wextra -Werror $(CCMODE)
LAXCC=cc -Werror $(CCMODE)

EXTRA_YAML=$(wildcard src/*.yaml)
EXTRA_C_TARGETS=$(patsubst src/%.yaml,tmp/%.c,$(EXTRA_YAML))
EXTRA_H_TARGETS=$(patsubst src/%.yaml,tmp/%.h,$(EXTRA_YAML))
EXTRA_OBJTYPES_H_TARGETS=$(patsubst src/%.yaml,tmp/%_objtypes.h,$(EXTRA_YAML))
EXTRA_DEBUG_H_TARGETS=$(patsubst src/%.yaml,tmp/%_debug.h,$(EXTRA_YAML))
EXTRA_DEBUG_C_TARGETS=$(patsubst src/%.yaml,tmp/%_debug.c,$(EXTRA_YAML))

EXTRA_TARGETS= \
$(EXTRA_C_TARGETS) \
$(EXTRA_H_TARGETS) \
$(EXTRA_OBJTYPES_H_TARGETS) \
$(EXTRA_DEBUG_H_TARGETS) \
$(EXTRA_DEBUG_C_TARGETS)

MAIN=src/main.c
CFILES=$(filter-out $(MAIN), $(wildcard src/*.c))
EXTRA_CFILES=tmp/lexer.c tmp/parser.c
EXTRA_CFILES=tmp/lexer.c tmp/parser.c $(EXTRA_C_TARGETS) $(EXTRA_DEBUG_C_TARGETS)
TEST_CFILES=$(wildcard tests/src/*.c)

TEST_TARGETS=$(patsubst tests/src/%.c,tests/%,$(TEST_CFILES))
Expand Down Expand Up @@ -48,8 +62,29 @@ $(TARGET): $(MAIN_OBJ) $(ALL_OBJ)
$(CC) -o $@ $(MAIN_OBJ) $(ALL_OBJ) -lm

include $(ALL_DEP)
-include Makefile.extra


$(EXTRA_C_TARGETS): tmp/%.c: src/%.yaml tools/makeAST.py | tmp
python3 tools/makeAST.py $< c > $@ || (rm -f $@ ; exit 1)

$(EXTRA_H_TARGETS): tmp/%.h: src/%.yaml tools/makeAST.py | tmp
python3 tools/makeAST.py $< h > $@ || (rm -f $@ ; exit 1)

$(EXTRA_OBJTYPES_H_TARGETS): tmp/%_objtypes.h: src/%.yaml tools/makeAST.py | tmp
python3 tools/makeAST.py $< objtypes_h > $@ || (rm -f $@ ; exit 1)

$(EXTRA_DEBUG_H_TARGETS): tmp/%_debug.h: src/%.yaml tools/makeAST.py | tmp
python3 tools/makeAST.py $< debug_h > $@ || (rm -f $@ ; exit 1)

$(EXTRA_DEBUG_C_TARGETS): tmp/%_debug.c: src/%.yaml tools/makeAST.py | tmp
python3 tools/makeAST.py $< debug_c > $@ || (rm -f $@ ; exit 1)


.generated: $(EXTRA_TARGETS) $(TMP_H)
touch $@

tags: src/*
ctags src/*
$(MAIN_OBJ) $(OBJ): obj/%.o: src/%.c | obj
$(CC) -I tmp/ -I src/ -c $< -o $@

Expand All @@ -59,14 +94,14 @@ $(EXTRA_OBJ): obj/%.o: tmp/%.c | obj
$(TEST_OBJ): obj/%.o: tests/src/%.c | obj
$(LAXCC) -I src/ -I tmp/ -c $< -o $@

$(MAIN_DEP) $(DEP): dep/%.d: src/%.c | dep $(TMP_H)
$(MAIN_DEP) $(DEP): dep/%.d: src/%.c .generated | dep
$(CC) -I tmp/ -I src/ -MM -MT $(patsubst dep/%,obj/%,$(patsubst %.d,%.o,$@)) -o $@ $<

$(EXTRA_DEP): dep/%.d: tmp/%.c | dep $(TMP_H)
$(EXTRA_DEP): dep/%.d: tmp/%.c .generated | dep
$(LAXCC) -I src/ -I tmp/ -MM -MT $(patsubst dep/%,obj/%,$(patsubst %.d,%.o,$@)) -o $@ $<

$(TEST_DEP): dep/%.d: tests/src/%.c | dep $(TMP_H)
$(CC) -I src/ -I /tmp -MM -MT $(patsubst dep/%,obj/%,$(patsubst %.d,%.o,$@)) -o $@ $<
$(TEST_DEP): dep/%.d: tests/src/%.c .generated | dep
$(CC) -I src/ -I tmp/ -MM -MT $(patsubst dep/%,obj/%,$(patsubst %.d,%.o,$@)) -o $@ $<

tmp/lexer.c tmp/lexer.h: src/lexer.l | tmp
flex --header-file=tmp/lexer.h -o tmp/lexer.c $<
Expand Down
49 changes: 0 additions & 49 deletions Makefile.extra.sample

This file was deleted.

7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ but using a bytecode interpreter rather than a tree-walking interpreter,
and utilising a hybrid stack/closure/continuation implementation where
variables local to a function are directly accessible on the stack, and
closures and continuations are snapshots of stack frames. It additionally
makes use of fast lexical addressing (an implementation of
makes use of fast lexical addressing (technically
[De Bruijn Indexing](https://en.wikipedia.org/wiki/De_Bruijn_index)) for
added efficiency gains and an implementation of Hindley-Milner
Algorithm W for strict implicit type checking.
Expand Down Expand Up @@ -52,7 +52,10 @@ in two specific cases:
`amb`, "backtracking" to the decision point and allowing the alternative
to be produced.

For all the details see [SICP pp.
To see `amb` in action, look at the sample [fn/barrels.fn](fn/barrels.fn).
Note that in this language `amb` is an infix operator called `then`.

For a good description of `amb` see [SICP pp.
412-437](https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/full-text/book/book-Z-H-28.html#%_sec_4.3).

What makes a CEK machine such an easy way to implement `amb` is that
Expand Down
2 changes: 2 additions & 0 deletions docs/TODO.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# TODO

* over-application i.e. `fn (a) { fn (b) { a + b } }(2, 3)`
* completely hide `vec` from type checker (`(tag thing)` == `(vec 0 thing)`)
* allow user overrides of print functions
* tuples - can use vec type to implement.
* BUT - fn args are not tuples, that might interfere with currying.
* tc has support for pairs and we might leverage those as a start, but flat vecs will be more efficient.
Expand Down
4 changes: 4 additions & 0 deletions fn/badLet.fn
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let
a = 10;
a = a + 2;
in print(a)
9 changes: 9 additions & 0 deletions fn/badPrint.fn
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let
fn bad() {
let
typedef doh { re | mi }
in
re
}
in
print(bad())
30 changes: 30 additions & 0 deletions fn/badSort.fn
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// naive un-optimised quicksort implementation to
// demonstrate the principle, see qqsort.fn for
// an optimised version.
let
fn f1(a) { a + 1 }
fn f2(a) { a - 1 }

fn qsort {
([]) { [] }
(pivot @ rest) {
let
lesser = filter(fn (a, b) { a >= b }(pivot), rest);
greater = filter(fn (a, b) { a < b }(pivot), rest);
in
qsort(lesser) @@ [pivot] @@ qsort(greater)
}
}

fn filter {
(f, []) { [] }
(f, h @ t) {
if (f(h)) {
h @ filter(f, t)
} else {
filter(f, t)
}
}
}
in
print(qsort([f1, f2]))
32 changes: 32 additions & 0 deletions fn/pythagoreanTriples.fn
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
let
fn require(condition) {
condition or back
}

fn square(x) { x * x }

fn integers_from(n) {
n then integers_from(n + 1)
}

fn integers_between(lower, upper) {
require(lower <= upper);
lower then integers_between(lower + 1, upper)
}

fn pythagorean_triples() {
let
z = integers_from(1);
x = integers_between(1, z);
y = integers_between(x, z);
in
require(square(x) + square(y) == square(z));
[x, y, z]
}
in {
let triple = pythagorean_triples();
in
print(triple);
puts("\n");
require(<triple > 20) // until
}
Loading

0 comments on commit 0e3b70d

Please sign in to comment.