From bea6ad2e5e7f102d42cf9cdea1a41e5e804fb763 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Thu, 24 Feb 2022 20:50:40 +0000 Subject: [PATCH] Use new line number on error reporting to find a few type errors. --- HISTORY.md | 2 + TODO.md | 2 - eg/assoc2.castile | 37 +++++++++++++++++++ eg/length.castile | 23 ------------ ...kedlist.castile => linkedlist-ops.castile} | 8 ++++ 5 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 eg/assoc2.castile delete mode 100644 eg/length.castile rename eg/{equal-linkedlist.castile => linkedlist-ops.castile} (80%) diff --git a/HISTORY.md b/HISTORY.md index c2fe48b..3cd5465 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -22,6 +22,8 @@ Castile 0.5 ### Implementation +* Line numbers are recorded in the AST when parsing, and + reported on type errors when type errors occur. * Requesting the AST be dumped, will also dump the AST with type assignments, if an error occurs during type checking. * Established an abstract base class for compiler backends. diff --git a/TODO.md b/TODO.md index 145365c..4a2ad53 100644 --- a/TODO.md +++ b/TODO.md @@ -19,8 +19,6 @@ stackmac: store tagged values as two values on the stack. and void types in unions of (void, X) should only be one value. (structs are still boxed though) -AST nodes should have source line numbers, it would be really nice. - Implement garbage collection of some sort in the C backend. Either that or implement some kind of resource-awareness in the language itself. diff --git a/eg/assoc2.castile b/eg/assoc2.castile new file mode 100644 index 0000000..c9952a8 --- /dev/null +++ b/eg/assoc2.castile @@ -0,0 +1,37 @@ +struct assoc { + key: string; + value: string; + next: assoc|void; +} for (update, lookup, remove) + +fun empty() { + return null as assoc|void +} + +fun update(k: string, v: string, a: assoc|void) { + make assoc(key:k, value:v, next:a as assoc|void) +} + +lookup : assoc|void, string -> string|void +fun lookup(a: assoc|void, k: string) { + typecase a is void { + return null as string|void + } + typecase a is assoc { + if a.key == k { + return a.value as string|void + } + return lookup(a.next, k) + } +} + +fun main() { + a = update("3", "third", empty()); + a = update("2", "second", a as assoc|void); + a = update("1", "first", a as assoc|void); + r = lookup((a as assoc|void), "2"); + print("um"); + typecase r is void { print("NOT FOUND"); } + typecase r is string { print(r); } + print("ya"); +} diff --git a/eg/length.castile b/eg/length.castile deleted file mode 100644 index 6864ef0..0000000 --- a/eg/length.castile +++ /dev/null @@ -1,23 +0,0 @@ -struct list { - value: string; - next: list|void; -} for (cons, singleton, length) - -fun cons(v: string, l: list) { - make list(value:v, next:l as list|void) -} - -fun singleton(v: string) { - make list(value:v, next:null as list|void) -} - -length : list|void -> integer -fun length(l: list|void) { - typecase l is void { return 0 } - typecase l is list { return 1 + length(l.next) } -} - -fun main() { - l = cons("first", cons("second", singleton("third"))); - print(str(length(l as list|void))); -} diff --git a/eg/equal-linkedlist.castile b/eg/linkedlist-ops.castile similarity index 80% rename from eg/equal-linkedlist.castile rename to eg/linkedlist-ops.castile index 5475462..2b5a022 100644 --- a/eg/equal-linkedlist.castile +++ b/eg/linkedlist-ops.castile @@ -26,11 +26,19 @@ fun equal_list(a: list|void, b: list|void) { return false } +length : list|void -> integer +fun length(l: list|void) { + typecase l is void { return 0 } + typecase l is list { return 1 + length(l.next) } +} + main = fun() { l1 = cons("first", cons("second", cons("third", empty()))); l2 = cons("first", cons("second", cons("third", empty()))); l3 = cons("first", cons("second", empty())); + print(str(length(l1 as list|void))); + if (equal_list(l1, l2) and not equal_list(l2, l3)) { print("Yep, story checks out") }