X-Git-Url: https://code.kerkeslager.com/?a=blobdiff_plain;f=parsing.py;h=12b93f585d22a1c47e11b5ccf1ad47c68139fcb7;hb=76ffe5adf4f6497945684e700dec15c809897d77;hp=45964d761fcbb81a9939c1d439450cdbca22cf5b;hpb=3297817843cd6bd087505a70d8e108f1baa35cff;p=fur diff --git a/parsing.py b/parsing.py index 45964d7..12b93f5 100644 --- a/parsing.py +++ b/parsing.py @@ -36,6 +36,14 @@ def _zero_or_more_parser(formatter, parser): return result_parser +NodeMetadata = collections.namedtuple( + 'NodeMetadata', + [ + 'index', + 'line', + ], +) + FurIntegerLiteralExpression = collections.namedtuple( 'FurIntegerLiteralExpression', [ @@ -67,6 +75,7 @@ FurNegationExpression = collections.namedtuple( FurInfixExpression = collections.namedtuple( 'FurInfixExpression', [ + 'metadata', 'order', 'operator', 'left', @@ -90,6 +99,21 @@ FurIfExpression = collections.namedtuple( ], ) +FurSymbolExpressionPair = collections.namedtuple( + 'FurSymbolExpressionPair', + [ + 'symbol', + 'expression', + ], +) + +FurStructureLiteralExpression = collections.namedtuple( + 'FurStructureLiteralExpression', + [ + 'fields', + ], +) + def _integer_literal_expression_parser(index, tokens): failure = (False, index, None) @@ -101,6 +125,9 @@ def _integer_literal_expression_parser(index, tokens): return True, index, FurIntegerLiteralExpression(integer=value) def _string_literal_expression_parser(index, tokens): + if tokens[index].type == 'double_quoted_string_literal': + return (True, index + 1, FurStringLiteralExpression(string=tokens[index].match[1:-1])) + if tokens[index].type == 'single_quoted_string_literal': return (True, index + 1, FurStringLiteralExpression(string=tokens[index].match[1:-1])) @@ -147,6 +174,44 @@ def _parenthese_wrapped_parser(internal_parser): def _parenthesized_expression_parser(index, tokens): return _parenthese_wrapped_parser(_expression_parser)(index, tokens) +def symbol_expression_pair_parser(index, tokens): + failure = (False, index, None) + + if tokens[index].type == 'symbol': + symbol = tokens[index].match + index += 1 + else: + return failure + + if tokens[index].type == 'colon': + index += 1 + else: + return failure + + success, index, expression = _expression_parser(index, tokens) + + if not success: + raise Exception() + + return ( + True, + index, + FurSymbolExpressionPair( + symbol=symbol, + expression=expression, + ), + ) + +def _structure_literal_parser(index, tokens): + success, index, result = _parenthese_wrapped_parser(_comma_separated_list_parser(symbol_expression_pair_parser))(index, tokens) + return ( + success, + index, + FurStructureLiteralExpression( + fields=result, + ), + ) + def _list_literal_expression_parser(index, tokens): failure = (False, index, None) @@ -159,29 +224,42 @@ def _list_literal_expression_parser(index, tokens): else: return failure +def _literal_level_expression_parser(index, tokens): + return _or_parser( + _list_item_expression_parser, + _function_call_expression_parser, + _parenthesized_expression_parser, + _integer_literal_expression_parser, + _string_literal_expression_parser, + _list_literal_expression_parser, + _symbol_expression_parser, + _structure_literal_parser, + )(index, tokens) + +def _dot_expression_parser(index, tokens): + return _left_recursive_infix_operator_parser( + lambda token: token.type == 'period', + _literal_level_expression_parser, + 'dot_level', + )(index, tokens) + def _negation_expression_parser(index, tokens): failure = (False, index, None) if tokens[index].match != '-': return failure - success, index, value = _literal_level_expression_parser(index + 1, tokens) + success, index, value = _dot_expression_parser(index + 1, tokens) if not success: return failure return (True, index, FurNegationExpression(value=value)) -def _literal_level_expression_parser(index, tokens): +def _negation_level_expression_parser(index, tokens): return _or_parser( + _dot_expression_parser, _negation_expression_parser, - _list_item_expression_parser, - _function_call_expression_parser, - _parenthesized_expression_parser, - _integer_literal_expression_parser, - _string_literal_expression_parser, - _list_literal_expression_parser, - _symbol_expression_parser, )(index, tokens) def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser, order): @@ -201,6 +279,10 @@ def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser if success: result = FurInfixExpression( + metadata=NodeMetadata( + index=tokens[index].index, + line=tokens[index].line, + ), order=order, operator=tokens[index].match, left=result, @@ -215,7 +297,7 @@ def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser def _multiplication_level_expression_parser(index, tokens): return _left_recursive_infix_operator_parser( lambda token: token.type == 'multiplication_level_operator', - _literal_level_expression_parser, + _negation_level_expression_parser, 'multiplication_level', )(index, tokens) @@ -445,9 +527,6 @@ def _if_expression_parser(index, tokens): ), ) - - - _expression_parser = _or_parser( _or_level_expression_parser, _if_expression_parser, # This should always be at the top level