From 3458fb6ce7491bf608ea5c35fda6df0c1f9bd2e8 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Tue, 15 Feb 2022 21:34:47 +0000 Subject: [PATCH] Make field access limited by struct scope too. All tests pass. --- src/castile/checker.py | 25 +++++++++++++++++-------- test.sh | 2 +- tests/Castile.md | 8 ++++---- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/castile/checker.py b/src/castile/checker.py index 0c5bd0c..5e3ca0f 100644 --- a/src/castile/checker.py +++ b/src/castile/checker.py @@ -67,7 +67,9 @@ def collect_struct(self, ast): type_exprs = [] i = 0 field_defns = ast.children[0].children - scope_idents = ast.children[1].children if len(ast.children) > 1 else None + scope_idents = None + if len(ast.children) > 1: + scope_idents = [a.value for a in ast.children[1].children] for child in field_defns: assert child.tag == 'FieldDefn', child.tag field_name = child.value @@ -243,13 +245,14 @@ def type_of(self, ast): raise CastileTypeError("undefined struct %s" % t.name) struct_defn = self.structs[t.name] if struct_defn.scope_idents is not None: - scope_idents = [ast.value for ast in struct_defn.scope_idents] - if self.current_defn not in scope_idents: - raise CastileTypeError("inaccessible struct %s for make: %s not in %s" % - (t.name, self.current_defn, scope_idents) + if self.current_defn not in struct_defn.scope_idents: + raise CastileTypeError("inaccessible struct %s for make: %s not in %s" % + (t.name, self.current_defn, struct_defn.scope_idents) ) if len(struct_defn.content_types) != len(ast.children) - 1: - raise CastileTypeError("argument mismatch") + raise CastileTypeError("argument mismatch; expected {}, got {} in {}".format( + len(struct_defn.content_types), len(ast.children) - 1, ast + )) i = 0 for defn in ast.children[1:]: name = defn.value @@ -263,15 +266,21 @@ def type_of(self, ast): ast.type = self.type_of(ast.children[0]) elif ast.tag == 'Index': t = self.type_of(ast.children[0]) + struct_defn = self.structs[t.name] + if struct_defn.scope_idents is not None: + if self.current_defn not in struct_defn.scope_idents: + raise CastileTypeError("inaccessible struct %s for access: %s not in %s" % + (t.name, self.current_defn, struct_defn.scope_idents) + ) field_name = ast.value - struct_fields = self.structs[t.name].field_names + struct_fields = struct_defn.field_names if field_name not in struct_fields: raise CastileTypeError("undefined field") index = struct_fields[field_name] # we make this value available to compiler backends ast.aux = index # we look up the type from the StructDefinition - ast.type = self.structs[t.name].content_types[index] + ast.type = struct_defn.content_types[index] elif ast.tag == 'TypeCase': t1 = self.type_of(ast.children[0]) t2 = self.type_of(ast.children[1]) diff --git a/test.sh b/test.sh index a5a9be6..52d8003 100755 --- a/test.sh +++ b/test.sh @@ -24,7 +24,7 @@ if [ ! x`command -v gcc` = x ]; then APPLIANCES="$APPLIANCES tests/appliances/castile-c-c.md" fi -APPLIANCES="tests/appliances/castile-c-c.md" +#APPLIANCES="tests/appliances/castile-c-c.md" #APPLIANCES="tests/appliances/castile-c-javascript.md" falderal $APPLIANCES tests/Castile.md diff --git a/tests/Castile.md b/tests/Castile.md index 63c2f8a..d06e842 100644 --- a/tests/Castile.md +++ b/tests/Castile.md @@ -1262,7 +1262,7 @@ is accomplished. | struct list { | value: string; | next: list|void; - | } for (cons, singleton, len) + | } for (cons, singleton, length) | | fun cons(v: string, l: list) { | make list(value:v, next:l as list|void) @@ -1287,7 +1287,7 @@ is accomplished. | struct list { | value: string; | next: list|void; - | } for (cons, singleton, len) + | } for (cons, singleton, length) | | fun cons(v: string, l: list) { | make list(value:v, next:l as list|void) @@ -1312,7 +1312,7 @@ is accomplished. | struct list { | value: string; | next: list|void; - | } for (cons, singleton, len) + | } for (cons, singleton, length) | | fun cons(v: string, l: list) { | make list(value:v, next:l as list|void) @@ -1326,4 +1326,4 @@ is accomplished. | l = cons("first", cons("second", singleton("third"))); | print(l.value); | } - ? value + ? struct