Skip to content

Commit

Permalink
Allow promoting union type to itself, or to a bigger union type.
Browse files Browse the repository at this point in the history
  • Loading branch information
cpressey committed Jun 30, 2021
1 parent 1fc49f5 commit 13606e6
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 23 deletions.
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ Each of the individual types named in the union type must be unique.
| }
? bad union type

Cannot promote a union type to itself.
One can, vacuously, promote a union type to itself.

| fun main() {
| a = 20;
Expand All @@ -1089,20 +1089,20 @@ Cannot promote a union type to itself.
| d = c as integer|string
| print("ok")
| }
? bad cast
= ok

Can promote a union type to another union type, so long as it is a superset. (TODO)
One can promote a union type to another union type, so long as it is a superset.

/| fun main() {
/| a = 20;
/| b = 30;
/| c = a + b as integer|string
/| d = c as integer|string|void
/| print("ok")
/| }
/= ok
| fun main() {
| a = 20;
| b = 30;
| c = a + b as integer|string
| d = c as integer|string|void
| print("ok")
| }
= ok

Cannot promote a union type to a union type that is not a superset.
One cannot promote a union type to a union type that is not a superset.

| fun main() {
| a = 20;
Expand Down
2 changes: 0 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ Other backends (Python? Java? CIL? Scheme?)

### Design ###

Promote union type to bigger union type (e.g. `string|int` => `string|int|void`)

Don't output final value. Command-line arguments passed to `main`. (`sysmain`?)

Convenience:
Expand Down
14 changes: 7 additions & 7 deletions src/castile/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,15 +302,15 @@ def type_of(self, ast):
elif ast.tag == 'StructDefn':
ast.type = Void()
elif ast.tag == 'TypeCast':
val_t = self.type_of(ast.children[0])
uni_t = self.type_of(ast.children[1])
if not isinstance(uni_t, Union):
raise CastileTypeError('bad cast, not a union: %s' % uni_t)
if not uni_t.contains(val_t):
value_t = self.type_of(ast.children[0])
union_t = self.type_of(ast.children[1])
if not isinstance(union_t, Union):
raise CastileTypeError('bad cast, not a union: %s' % union_t)
if not union_t.contains(value_t):
raise CastileTypeError(
'bad cast, %s does not include %s' % (uni_t, val_t)
'bad cast, %s does not include %s' % (union_t, value_t)
)
ast.type = uni_t
ast.type = union_t
else:
raise NotImplementedError(repr(ast))
return ast.type
6 changes: 4 additions & 2 deletions src/castile/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ class Union(Type):
def __init__(self, content_types):
self.content_types = content_types

def contains(self, type):
def contains(self, type_):
if isinstance(type_, Union):
return all([self.contains(t) for t in type_.content_types])
for member in self.content_types:
if type == member:
if type_ == member:
return True
return False

Expand Down

0 comments on commit 13606e6

Please sign in to comment.