Tree @master (Download .tar.gz)
Castile
Version 0.5 | Entry @ catseye.tc | See also: Eightebed ∘ Dieter
This is the reference distribution for Castile, a simple imperative language with union types.
The design of Castile was influenced (in varying degrees) by C, Rust, Eightebed, Python, Ruby, and Erlang. More information on its roots can be found in doc/Design.md.
The reference implementation can both interpret Castile programs and compile them to a variety of targets — JavaScript, Ruby, C, and a generic stack-based VM (included in this distribution).
A rich test suite in Falderal format, which describes the language with many examples, can be found in tests/Castile.md.
Quick Start
Clone this repository, cd into the repo directory and run
bin/castile eg/hello.castile
Alternately, put the bin subdirectory on your executable search path, so
that you can run castile from any directory on your system. castile
has no dependencies besides Python (either Python 2 or Python 3.)
Motivating Example
Here are some functions for creating linked lists, written in Castile:
struct list {
value: integer;
next: list|void;
}
fun empty() {
return null as list|void
}
fun cons(v: integer, l: list|void) {
make list(value:v, next:l) as list|void
}
In this, list|void is a union type. In this case it is expressing
the fact that the value can be either a list or void — the moral
equivalent of "nullable". In order to access any of the concrete types
of a union type, one must use typecase:
fun max(l: list|void) {
u = l;
v = u;
n = 0;
while true {
typecase u is void {
break;
}
typecase u is list {
if u.value > n {
n = u.value
}
v = u.next;
}
u = v;
}
return n
}
This retains type-safety; the code will never unexpectedly be presented with a null value.
Union types can also encourage the programmer follow a Parse, don't validate
approach (which, despite the impression you might get from reading that article,
is not restricted to Haskell or even to functional programming). In the above
code, cons will never return a void, and max is not defined on empty lists.
So ideally, we'd like to tighten their types to exclude those. And we can:
...
fun cons(v: integer, l: list) {
make list(value:v, next:l as list|void)
}
fun singleton(v: integer) {
make list(value:v, next:null as list|void)
}
fun max(l: list) {
u = l as list|void;
v = u;
...
}
Many more examples of Castile programs can be found in tests/Castile.md.
Commit History
@master
git clone https://git.catseye.tc/Castile/
- Update links in "see-also bar". Chris Pressey 2 years ago
- Merge pull request #4 from catseye/develop-0.5-2022.09xx Chris Pressey (commit: GitHub) 3 years ago
- By default, launch driver scripts using Python 3. Chris Pressey 3 years ago
- Merge pull request #3 from catseye/develop-0.5 Chris Pressey (commit: GitHub) 4 years ago
- Change how command-line arguments are parsed. Add --version switch. Chris Pressey 4 years ago
- Mention scanner improvements in HISTORY file. Chris Pressey 4 years ago
- Update TODO. Chris Pressey 4 years ago
- Develop the associative map example. Chris Pressey 4 years ago
- Use new line number on error reporting to find a few type errors. Chris Pressey 4 years ago
- Report line numbers on type errors. Chris Pressey 4 years ago
- Record line numbers in AST nodes. Chris Pressey 4 years ago
- Add missing line in example program. Chris Pressey 4 years ago
- Remove the deep struct equality implementation from backends. Chris Pressey 4 years ago
- No equality between unions that contain structs. Chris Pressey 4 years ago
- Structs cannot be tested for equality with `==` or `!=`. Chris Pressey 4 years ago
- When casting, don't promote already-tagged values, to tagged values. Chris Pressey 4 years ago
- Add failing test. Chris Pressey 4 years ago
- Generate more sufficient equal_foo functions in JavaScript backend. Chris Pressey 4 years ago
- Equality function in C backend. Prettier output in Ruby backend. Chris Pressey 4 years ago
- Bug is avoided by not upcasting to same type. Bug still exists. Chris Pressey 4 years ago
- Note to self. Chris Pressey 4 years ago
- Add failing test that fails under, really, all the backends. Chris Pressey 4 years ago
- Be more strict, but allow tests to pass. Suspect still a problem. Chris Pressey 4 years ago
- Association list example, which is not working for some reason. Chris Pressey 4 years ago
- Establish an abstract base class for compiler backends. Chris Pressey 4 years ago
- Add HISTORY file. Chris Pressey 4 years ago
- Make field access limited by struct scope too. All tests pass. Chris Pressey 4 years ago
- Prevent `make` where struct is inaccessible. Chris Pressey 4 years ago
- Ah yes. You have to remember to upcast a lot in this language. Chris Pressey 4 years ago
- Checkpoint. Chris Pressey 4 years ago