+ return True, index, FurIntegerLiteralExpression(value=value)
+
+def _string_literal_expression_parser(index, tokens):
+ if tokens[index].type == 'single_quoted_string_literal':
+ return (True, index + 1, FurStringLiteralExpression(value=tokens[index].match[1:-1]))
+
+ return (False, index, None)
+
+def _symbol_expression_parser(index, tokens):
+ if tokens[index].type == 'symbol':
+ return (True, index + 1, FurSymbolExpression(value=tokens[index].match))
+
+ return (False, index, None)
+
+def _parenthesized_expression_parser(index, tokens):
+ failure = (False, index, None)
+
+ if tokens[index].type == 'open_parenthese':
+ index += 1
+ else:
+ return failure
+
+ success, index, internal = _expression_parser(index, tokens)
+ if not success:
+ return failure
+
+ if tokens[index].type == 'close_parenthese':
+ index += 1
+ else:
+ raise Exception('Expected ")" on line {}, found "{}"'.format(
+ tokens[index].line,
+ tokens[index].match,
+ ))
+
+ return True, index, FurParenthesizedExpression(internal=internal)
+
+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)
+
+ if not success:
+ return failure
+
+ return (True, index, FurNegationExpression(value=value))
+
+def _literal_level_expression_parser(index, tokens):
+ return _or_parser(
+ _negation_expression_parser,
+ _function_call_expression_parser,
+ _parenthesized_expression_parser,
+ _integer_literal_expression_parser,
+ _string_literal_expression_parser,
+ _symbol_expression_parser,
+ )(index, tokens)
+
+def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser, order):
+ def result_parser(index, tokens):
+ failure = (False, index, None)
+
+ success, index, result = operand_parser(index, tokens)
+
+ if not success:
+ return failure
+
+ while success and index < len(tokens) and operator_token_matcher(tokens[index]):
+ success = False
+
+ if index + 1 < len(tokens):
+ success, try_index, value = operand_parser(index + 1, tokens)
+
+ if success:
+ result = FurInfixExpression(
+ order=order,
+ operator=tokens[index].match,
+ left=result,
+ right=value,
+ )
+ index = try_index
+
+ return True, index, result
+
+ return result_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,
+ 'multiplication_level',
+ )(index, tokens)
+
+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 _comparison_level_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'comparison_level_operator',
+ _addition_level_expression_parser,
+ 'comparison_level',
+ )(index, tokens)
+
+def _and_level_expression_parser(index, tokens):
+ return _left_recursive_infix_operator_parser(
+ lambda token: token.type == 'symbol' and token.match == 'and',
+ _comparison_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):
+ start_index = index