diff --git a/src/python/flowmetal/syntax_analyzer.py b/src/python/flowmetal/syntax_analyzer.py index 802f223..ed31f33 100644 --- a/src/python/flowmetal/syntax_analyzer.py +++ b/src/python/flowmetal/syntax_analyzer.py @@ -49,17 +49,20 @@ class ConstraintExpr(TypeLevelExpr, NamedTuple): class ValueLevelExpr(object): """A base class for value-level expressions.""" + +class TriviallyTypedExpr(ValueLevelExpr): + """And some of those expressions have trivial types.""" @property def type(self) -> TypeExpr: """The type of an expression.""" -class AscribeExpr(TypeLevelExpr): +class AscribeExpr(TriviallyTypedExpr, NamedTuple): value: ValueLevelExpr type: TypeLevelExpr -class ConstExpr(ValueLevelExpr, NamedTuple): +class ConstExpr(TriviallyTypedExpr, NamedTuple): """Constant expressions. Keywords, strings, numbers, that sort of thing.""" token: p.ConstTokenBase @@ -114,42 +117,22 @@ class StringExpr(ConstExpr): class ListExpr(ValueLevelExpr, NamedTuple): elements: List[ValueLevelExpr] - # FIXME (arrdem 2020-07-18): - # Probably typed? Not sure. - - @property - def type(self) -> TypeExpr: - if self.elements: - return self.elements[-1].type - ## 'real' AST nodes class DoExpr(ValueLevelExpr, NamedTuple): effect_exprs: List[ValueLevelExpr] ret_expr: ValueLevelExpr - @property - def type(self) -> TypeExpr: - return self.ret_expr.type - class LetExpr(ValueLevelExpr, NamedTuple): binding_exprs: List[Tuple] ret_expr: DoExpr - @property - def type(self) -> TypeExpr: - return self.ret_expr.type - class FnExpr(ValueLevelExpr, NamedTuple): arguments: List - ret_expr: DoExpr ret_type: TypeExpr - - @property - def type(self) -> TypeExpr: - return self.ret_type + ret_expr: DoExpr ## Reader implementation @@ -310,7 +293,10 @@ class Analyzer(AnalyzerBase): def analyze_do(cls, do_token): tokens = cls._nows(do_token.data[1:]) exprs = cls._terms(tokens) - return DoExpr(exprs[:-1], exprs[-1]) + if exprs[:-1]: + return DoExpr(exprs[:-1], exprs[-1]) + else: + return exprs[-1] @classmethod def analyze_fn(cls, fn_token): @@ -334,7 +320,7 @@ class Analyzer(AnalyzerBase): # FIXME (arrdem 2020-07-18): # This needs to happen with bindings body = cls.analyze(cls._do(fn_token, tokens)) - return FnExpr(args, body, ascription or body.type) + return FnExpr(args, ascription, body) ## Analysis interface