diff --git a/src/python/flowmetal/syntax_analyzer.py b/src/python/flowmetal/syntax_analyzer.py index ed31f33..6f38510 100644 --- a/src/python/flowmetal/syntax_analyzer.py +++ b/src/python/flowmetal/syntax_analyzer.py @@ -156,12 +156,17 @@ class Analyzer(AnalyzerBase): """ TACK0 = _t('⊢') TACK1 = _t('|-') + TACK2 = p.KeywordToken(":-", None, None) LET = _t('let') DO = _t('do') FN = _t('fn') LIST = _t('list') QUOTE = _t('quote') + @classmethod + def _tackp(cls, t): + return t in [cls.TACK0, cls.TACK1, cls.TACK2] + @classmethod def _nows(cls, tokens): return [t for t in tokens if not isinstance(t, p.WhitespaceToken)] @@ -172,7 +177,7 @@ class Analyzer(AnalyzerBase): if len(tokens) == 1: return cls.analyze(tokens[0]), [] - elif tokens[1] in [cls.TACK0, cls.TACK1]: + elif cls._tackp(tokens[1]): if len(tokens) >= 3: return ( AscribeExpr( @@ -269,7 +274,7 @@ class Analyzer(AnalyzerBase): if not binding_tokens: raise SyntaxError(f"Analyzing `let` at {let_token.pos}, got binding expression without subsequent value expression!") - if binding_tokens[0] in [cls.TACK0, cls.TACK1]: + if cls._tackp(binding_tokens[0]): if len(binding_tokens) < 2: raise SyntaxError(f"Analyzing `let` at {let_token.pos}, got `⊢` at {binding_tokens[0].pos} without type!") bind_ascription = cls.analyze(binding_tokens[1]) @@ -311,7 +316,7 @@ class Analyzer(AnalyzerBase): args.append(argexpr) ascription = None - if tokens[1] in [cls.TACK0, cls.TACK1]: + if cls._tackp(tokens[1]): ascription = cls.analyze(tokens[2]) tokens = tokens[2:] else: diff --git a/test/python/flowmetal/test_syntax_analyzer.py b/test/python/flowmetal/test_syntax_analyzer.py index 4ab830b..7afde5d 100644 --- a/test/python/flowmetal/test_syntax_analyzer.py +++ b/test/python/flowmetal/test_syntax_analyzer.py @@ -43,6 +43,7 @@ def test_analyze_constants(txt, exprtype): '(fn [] 1)', '(fn [] ⊢ integer? x)', '(fn [] x |- integer?)', + '(fn [] x :- integer?)', ]) def test_analyze(txt): """Make sure that do exprs work."""