From eab88b322191c40168553b8671b968d1b1558084 Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Sun, 6 Aug 2017 16:43:21 -0400 Subject: [PATCH] Add boolean operators --- examples/14_boolean_operators.fur | 23 +++++++++++++++++ examples/14_boolean_operators.fur.output.txt | 8 ++++++ parsing.py | 26 +++++++++++++++----- templates/program.c | 9 +++++++ tokenization.py | 2 +- transformation.py | 12 +++++---- 6 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 examples/14_boolean_operators.fur create mode 100644 examples/14_boolean_operators.fur.output.txt diff --git a/examples/14_boolean_operators.fur b/examples/14_boolean_operators.fur new file mode 100644 index 0000000..1b24fb7 --- /dev/null +++ b/examples/14_boolean_operators.fur @@ -0,0 +1,23 @@ +print('false and false: ') +print(false and false) +print('\n') +print('false and true: ') +print(false and true) +print('\n') +print('true and false: ') +print(true and false) +print('\n') +print('true and true: ') +print(true and true) +print('\n') +print('false or false: ') +print(false or false) +print('\n') +print('false or true: ') +print(false or true) +print('\n') +print('true or false: ') +print(true or false) +print('\n') +print('true or true: ') +print(true or true) diff --git a/examples/14_boolean_operators.fur.output.txt b/examples/14_boolean_operators.fur.output.txt new file mode 100644 index 0000000..60b33ea --- /dev/null +++ b/examples/14_boolean_operators.fur.output.txt @@ -0,0 +1,8 @@ +false and false: false +false and true: false +true and false: false +true and true: true +false or false: false +false or true: true +true or false: true +true or true: true \ No newline at end of file diff --git a/parsing.py b/parsing.py index df29c0d..5a88fdc 100644 --- a/parsing.py +++ b/parsing.py @@ -142,7 +142,7 @@ def _literal_level_expression_parser(index, tokens): _symbol_expression_parser, )(index, tokens) -def _left_recursive_infix_operator_parser(token_type, operand_parser, order): +def _left_recursive_infix_operator_parser(operator_token_matcher, operand_parser, order): def result_parser(index, tokens): failure = (False, index, None) @@ -151,7 +151,7 @@ def _left_recursive_infix_operator_parser(token_type, operand_parser, order): if not success: return failure - while success and index < len(tokens) and tokens[index].type == token_type: + while success and index < len(tokens) and operator_token_matcher(tokens[index]): success = False if index + 1 < len(tokens): @@ -172,25 +172,39 @@ def _left_recursive_infix_operator_parser(token_type, operand_parser, order): def _multiplication_level_expression_parser(index, tokens): return _left_recursive_infix_operator_parser( - 'multiplication_level_operator', + 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( - 'addition_level_operator', + lambda token: token.type == 'addition_level_operator', _multiplication_level_expression_parser, 'addition_level', )(index, tokens) def _equality_level_expression_parser(index, tokens): return _left_recursive_infix_operator_parser( - 'equality_level_operator', + lambda token: token.type == 'equality_level_operator', _addition_level_expression_parser, 'equality_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', + _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) @@ -266,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 diff --git a/templates/program.c b/templates/program.c index 58ddd36..1d283be 100644 --- a/templates/program.c +++ b/templates/program.c @@ -327,6 +327,15 @@ Object builtin$and(Object left, Object right) return result; } +Object builtin$or(Object left, Object right) +{ + assert(left.type == BOOLEAN); + assert(right.type == BOOLEAN); + + Object result = { BOOLEAN, left.instance.boolean || right.instance.boolean }; + return result; +} + {% if 'pow' in builtins %} Object builtin$pow(Object base, Object exponent) { diff --git a/tokenization.py b/tokenization.py index e6cad0a..ff79307 100644 --- a/tokenization.py +++ b/tokenization.py @@ -40,9 +40,9 @@ _TOKEN_MATCHERS = [ ('symbol', r'[a-z]+'), ('single_quoted_string_literal', r"'.*?'"), ('equality_level_operator', r'(<=|>=|==|!=|<|>)'), + ('assignment_operator', r'='), ('addition_level_operator', r'(\+|-)'), ('multiplication_level_operator', r'(\*|//|%)'), - ('assignment_operator', r'='), ] _TOKEN_MATCHERS = list(map(_make_token_matcher, _TOKEN_MATCHERS)) diff --git a/transformation.py b/transformation.py index f67d0a4..3e898d8 100644 --- a/transformation.py +++ b/transformation.py @@ -160,11 +160,13 @@ def transform_expression(builtin_dependencies, symbol_list, expression): return transform_equality_level_expression(builtin_dependencies, symbol_list, expression) INFIX_OPERATOR_TO_FUNCTION_NAME = { - '+': 'add', - '-': 'subtract', - '*': 'multiply', - '//': 'integerDivide', - '%': 'modularDivide', + '+': 'add', + '-': 'subtract', + '*': 'multiply', + '//': 'integerDivide', + '%': 'modularDivide', + 'and': 'and', + 'or': 'or', } return CFunctionCallForFurInfixOperator( -- 2.20.1