diff --git a/TODO.md b/TODO.md index e70b643..15c7a96 100644 --- a/TODO.md +++ b/TODO.md @@ -28,10 +28,11 @@ or implement some kind of resource-awareness in the language itself. Other backends (Python? Java? CIL? Scheme?) -### Design ### +Test framework: collect the backend-independent tests into a single +file, and only test it once. Run all the *other* tests on every +backend. -Disallow equality checking for union types too (maybe except where -all member types are simple.) +### Design ### Don't output final value. Command-line arguments passed to `main`. (`sysmain`?) diff --git a/src/castile/checker.py b/src/castile/checker.py index eb04898..0017508 100644 --- a/src/castile/checker.py +++ b/src/castile/checker.py @@ -107,6 +107,8 @@ def type_of(self, ast): self.assert_eq(type1, type2) if isinstance(type1, Struct): raise CastileTypeError("structs cannot be compared") + if isinstance(type1, Union) and type1.contains_instance_of(Struct): + raise CastileTypeError("unions containing structs cannot be compared") ast.type = Boolean() elif ast.tag == 'Not': type1 = self.type_of(ast.children[0]) diff --git a/src/castile/types.py b/src/castile/types.py index 5be3891..2c388fe 100644 --- a/src/castile/types.py +++ b/src/castile/types.py @@ -61,6 +61,12 @@ def contains(self, type_): return True return False + def contains_instance_of(self, cls): + for member in self.content_types: + if isinstance(member, cls): + return True + return False + def __str__(self): h = "union(" h += ', '.join(sorted([str(t) for t in self.content_types])) diff --git a/tests/Castile.md b/tests/Castile.md index 92d9a9d..dc7ea37 100644 --- a/tests/Castile.md +++ b/tests/Castile.md @@ -602,7 +602,8 @@ Equality cannot be checked between two values of different types. | } ? mismatch -Equality can be checked between unions. +Equality can be checked between unions, as long as they are +unions entirely of simple (non-struct) types. | fun main() { | a = 40 as string|integer @@ -633,6 +634,19 @@ Equality cannot be tested between two disjoint unions. | } ? mismatch +Equality cannot be tested between values of a union type +that contains a struct type as one of its members. + + | struct person { name: string; age: integer } + | fun main() { + | a = 40 as person|integer + | b = 40 as person|integer + | if a == b { + | print("it is") + | } + | } + ? struct + ### Builtins ### The usual.