Add boolean operators
authorDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 6 Aug 2017 20:43:21 +0000 (16:43 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 6 Aug 2017 20:43:21 +0000 (16:43 -0400)
examples/14_boolean_operators.fur [new file with mode: 0644]
examples/14_boolean_operators.fur.output.txt [new file with mode: 0644]
parsing.py
templates/program.c
tokenization.py
transformation.py

diff --git a/examples/14_boolean_operators.fur b/examples/14_boolean_operators.fur
new file mode 100644 (file)
index 0000000..1b24fb7
--- /dev/null
@@ -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 (file)
index 0000000..60b33ea
--- /dev/null
@@ -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
index df29c0d..5a88fdc 100644 (file)
@@ -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
index 58ddd36..1d283be 100644 (file)
@@ -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)
 {
index e6cad0a..ff79307 100644 (file)
@@ -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))
index f67d0a4..3e898d8 100644 (file)
@@ -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(