-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from catseye/develop-0.5
Develop 0.5
- Loading branch information
Showing
24 changed files
with
944 additions
and
455 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
History of Castile | ||
================== | ||
|
||
Castile 0.5 | ||
----------- | ||
|
||
### Distribution | ||
|
||
* Added HISTORY.md file. | ||
|
||
### Language | ||
|
||
* Scoped structs can be declared with the `for (...)` clause | ||
after the struct. A value of a scope struct can only be | ||
`make`d, and the fields of such a value can only be accessed, | ||
lexically inside one of the definitions named in the `for`. | ||
* Structs cannot be tested for equality with the `==` and `!=` | ||
operators. Instead the programmer should write a function | ||
that compares structs for equality, if desired. | ||
* Values of union type can be tested for equality, but only if | ||
none of the types involved in the union are structs. | ||
|
||
### Implementation | ||
|
||
* Lexical scanner has been split off from parser code, into | ||
its own module. A performance bug (using O(n^2) space | ||
instead of O(n)) during scanning has also been fixed. | ||
* 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. | ||
* Fixed a bug where tagged values were being tagged again | ||
during a cast from a union type to another union type. | ||
* ArgumentParser is used instead of OptionParser to parse | ||
command-line arguments. `--version` added, `--test` (and | ||
remaining doctests in source modules) removed. | ||
|
||
Castile 0.4 | ||
----------- | ||
|
||
### Distribution | ||
|
||
* Re-focused project: Castile is a simple imperative language | ||
with union types. | ||
* Released under a 3-clause BSD license. | ||
|
||
### Language | ||
|
||
* `struct`s cannot be compared for order, it is a static error. | ||
* A union type is allowed to be promoted to a bigger union type, | ||
or to itself. | ||
|
||
### Implementation | ||
|
||
* Completed the C-generating backend of the compiler: it passes all tests now. | ||
* Implemented `str` builtin, equality testing of `struct`s in all backends. | ||
* Improved pretty-printing of code in C and Ruby backends. | ||
* Implemented `ne` in stackmac implementation. | ||
|
||
Castile 0.3 revision 2021.0625 | ||
------------------------------ | ||
|
||
* Updated implementation to run under both Python 2 and Python 3. | ||
* Refactored test suite, making it more idiomatic Falderal. | ||
|
||
Castile 0.3 revision 2016.0331 | ||
------------------------------ | ||
|
||
* Fixed generated Ruby code that worked in Ruby 1.8 but fails in Ruby 1.9. | ||
|
||
Castile 0.3 revision 2015.0101 | ||
------------------------------ | ||
|
||
* Stopped using deprecated Falderal variable names in test suite. | ||
|
||
Castile 0.3 | ||
----------- | ||
|
||
* Treatment of local variables became more Python-like. | ||
* Beginnings of a C backend in compiler. | ||
|
||
Castile 0.2 | ||
----------- | ||
|
||
* Heavy development of the language, with many changes. | ||
* Added JavaScript, Ruby, and stackmac (stack-machine) backends to compiler. | ||
|
||
Castile 0.1 | ||
----------- | ||
|
||
Initial release of Castile, an unremarkable language with an unremarkable | ||
compiler/interpreter in Python. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Implementation of an associative map in Castile. | ||
* | ||
* The map is implemented as an association list, | ||
* but this fact is hidden from clients, as only | ||
* the operations have access to the internals | ||
* of the struct. | ||
*/ | ||
|
||
struct assoc { | ||
key: string; | ||
value: string; | ||
next: assoc|void; | ||
} for (update, lookup, remove, render) | ||
|
||
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) | ||
} | ||
} | ||
|
||
remove : assoc|void, string -> assoc|void | ||
fun remove(a: assoc|void, k: string) { | ||
typecase a is void { | ||
return a as assoc|void | ||
} | ||
typecase a is assoc { | ||
if a.key == k { | ||
return remove(a.next, k) | ||
} | ||
return make assoc(key:a.key, value:a.value, next:remove(a.next, k)) as assoc|void | ||
} | ||
} | ||
|
||
render : assoc|void -> string | ||
fun render(a: assoc|void) { | ||
typecase a is void { | ||
return "" | ||
} | ||
typecase a is assoc { | ||
return concat(a.value, concat(",", render(a.next))) | ||
} | ||
} | ||
|
||
fun main() { | ||
a = update("3", "third", empty()); | ||
a = update("2", "second", a as assoc|void); | ||
a = update("1", "first", a as assoc|void); | ||
print(render(a as assoc|void)) | ||
b = remove((a as assoc|void), "2"); | ||
print(render(b)) | ||
r = lookup(b, "2"); | ||
typecase r is void { print("NOT FOUND"); } | ||
typecase r is string { print(r); } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
struct list { | ||
value: string; | ||
next: list|void; | ||
} | ||
|
||
fun empty() { | ||
return null as list|void | ||
} | ||
|
||
fun cons(v: string, l: list|void) { | ||
make list(value:v, next:l) as list|void | ||
} | ||
|
||
equal_list : list|void, list|void -> boolean | ||
fun equal_list(a: list|void, b: list|void) { | ||
typecase a is void { | ||
typecase b is void { | ||
return true | ||
} | ||
} | ||
typecase a is list { | ||
typecase b is list { | ||
return a.value == b.value and equal_list(a.next, b.next) | ||
} | ||
} | ||
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") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
struct person { name: string }; | ||
fun foo(a, b: integer|string) { | ||
r = a; | ||
typecase b is integer { | ||
r = r + b; | ||
}; | ||
typecase b is person { | ||
r = r + len(b); | ||
}; | ||
r | ||
} | ||
main = fun() { | ||
a = 0; | ||
a = foo(a, 333 as integer|string); | ||
a = foo(a, "hiya" as integer|string); | ||
a /* should output 337 */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
"""Abstract base class for Castile compiler backends, | ||
especially source-to-source.""" | ||
|
||
class BaseCompiler(object): | ||
def __init__(self, out): | ||
self.out = out | ||
self.indent = 0 | ||
|
||
def commas(self, asts, sep=','): | ||
if asts: | ||
for child in asts[:-1]: | ||
self.compile(child) | ||
self.out.write(sep) | ||
self.compile(asts[-1]) | ||
|
||
def write(self, x): | ||
self.out.write(x) | ||
|
||
def write_indent(self, x): | ||
self.out.write(' ' * self.indent) | ||
self.out.write(x) |
Oops, something went wrong.