Add boolean operators
[fur] / parsing.py
index b30556e..5a88fdc 100644 (file)
@@ -65,89 +65,11 @@ FurParenthesizedExpression = collections.namedtuple(
     ],
 )
 
-FurAdditionExpression = collections.namedtuple(
-    'FurAdditionExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurSubtractionExpression = collections.namedtuple(
-    'FurSubtractionExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurMultiplicationExpression = collections.namedtuple(
-    'FurMultiplicationExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurIntegerDivisionExpression = collections.namedtuple(
-    'FurIntegerDivisionExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurModularDivisionExpression = collections.namedtuple(
-    'FurModularDivisionExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurEqualityExpression = collections.namedtuple(
-    'FurEqualityExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurInequalityExpression = collections.namedtuple(
-    'FurInequalityExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurLessThanOrEqualExpression = collections.namedtuple(
-    'FurLessThanOrEqualExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurGreaterThanOrEqualExpression = collections.namedtuple(
-    'FurGreaterThanOrEqualExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurLessThanExpression = collections.namedtuple(
-    'FurLessThanExpression',
-    [
-        'left',
-        'right',
-    ],
-)
-
-FurGreaterThanExpression = collections.namedtuple(
-    'FurGreaterThanExpression',
+FurInfixExpression = collections.namedtuple(
+    'FurInfixExpression',
     [
+        'order',
+        'operator',
         'left',
         'right',
     ],
@@ -220,80 +142,68 @@ def _literal_level_expression_parser(index, tokens):
         _symbol_expression_parser,
     )(index, tokens)
 
-def _multiplication_level_expression_parser(index, tokens):
-    failure = (False, index, None)
-
-    success, index, result = _literal_level_expression_parser(index, tokens)
-
-    if not success:
-        return failure
-
-    while success and index < len(tokens) and tokens[index].type == 'multiplication_level_operator':
-        success = False
+def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser, order):
+    def result_parser(index, tokens):
+        failure = (False, index, None)
 
-        if index + 1 < len(tokens):
-            success, try_index, value = _literal_level_expression_parser(index + 1, tokens)
+        success, index, result = operand_parser(index, tokens)
 
-        if success:
-            result = {
-                '*': FurMultiplicationExpression,
-                '//': FurIntegerDivisionExpression,
-                '%': FurModularDivisionExpression,
-            }[tokens[index].match](left=result, right=value)
-            index = try_index
-
-    return True, index, result
+        if not success:
+            return failure
 
-def _addition_level_expression_parser(index, tokens):
-    failure = (False, index, None)
+        while success and index < len(tokens) and operator_token_matcher(tokens[index]):
+            success = False
 
-    success, index, result = _multiplication_level_expression_parser(index, tokens)
+            if index + 1 < len(tokens):
+                success, try_index, value = operand_parser(index + 1, tokens)
 
-    if not success:
-        return failure
+            if success:
+                result = FurInfixExpression(
+                    order=order,
+                    operator=tokens[index].match,
+                    left=result,
+                    right=value,
+                )
+                index = try_index
 
-    while success and index < len(tokens) and tokens[index].type == 'addition_level_operator':
-        success = False
+        return True, index, result
 
-        if index + 1 < len(tokens):
-            success, try_index, value = _multiplication_level_expression_parser(index + 1, tokens)
+    return result_parser
 
-        if success:
-            result = {
-                '+': FurAdditionExpression,
-                '-': FurSubtractionExpression,
-            }[tokens[index].match](left=result, right=value)
-            index = try_index
+def _multiplication_level_expression_parser(index, tokens):
+    return _left_recursive_infix_operator_parser(
+        lambda token: token.type == 'multiplication_level_operator',
+        _literal_level_expression_parser,
+        'multiplication_level',
+    )(index, tokens)
 
-    return True, index, result
+def _addition_level_expression_parser(index, tokens):
+    return _left_recursive_infix_operator_parser(
+        lambda token: token.type == 'addition_level_operator',
+        _multiplication_level_expression_parser,
+        'addition_level',
+    )(index, tokens)
 
 def _equality_level_expression_parser(index, tokens):
-    failure = (False, index, None)
-
-    success, index, result = _addition_level_expression_parser(index, tokens)
-
-    if not success:
-        return failure
-
-    while success and index < len(tokens) and tokens[index].type == 'equality_level_operator':
-        success = False
-
-        if index + 1 < len(tokens):
-            success, try_index, value = _addition_level_expression_parser(index + 1, tokens)
-
-        if success:
-            result = {
-                '==': FurEqualityExpression,
-                '!=': FurInequalityExpression,
-                '>=': FurGreaterThanOrEqualExpression,
-                '<=': FurLessThanOrEqualExpression,
-                '>': FurGreaterThanExpression,
-                '<': FurLessThanExpression,
-            }[tokens[index].match](left=result, right=value)
-            index = try_index
+    return _left_recursive_infix_operator_parser(
+        lambda token: token.type == 'equality_level_operator',
+        _addition_level_expression_parser,
+        'equality_level',
+    )(index, tokens)
 
-    return True, index, result
+def _and_level_expression_parser(index, tokens):
+    return _left_recursive_infix_operator_parser(
+        lambda token: token.type == 'symbol' and token.match == 'and',
+        _equality_level_expression_parser,
+        'and_level',
+    )(index, tokens)
 
+def _or_level_expression_parser(index, tokens):
+    return _left_recursive_infix_operator_parser(
+        lambda token: token.type == 'symbol' and token.match == 'or',
+        _and_level_expression_parser,
+        'or_level',
+    )(index, tokens)
 
 def _comma_separated_list_parser(index, tokens):
     failure = (False, index, None)
@@ -370,7 +280,7 @@ def _function_call_expression_parser(index, tokens):
 
     return True, index, FurFunctionCallExpression(function=function, arguments=arguments)
 
-_expression_parser = _equality_level_expression_parser
+_expression_parser = _or_level_expression_parser
 
 def _assignment_statement_parser(index, tokens):
     # TODO Use a FurSymbolExpression for the target? Maybe this is actually not a good idea