-CInfixDeclaration = collections.namedtuple(
- 'CInfixDeclaration',
- [
- 'name',
- 'in_type',
- 'out_type',
- 'operator',
- ],
-)
-
-FUR_INFIX_OPERATOR_TO_C_FUNCTION = {
- '++': 'concatenate',
-}
-
-FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR = {
- '+': CInfixDeclaration(name='add', in_type='integer', out_type='integer', operator='+'),
- '-': CInfixDeclaration(name='subtract', in_type='integer', out_type='integer', operator='-'),
- '*': CInfixDeclaration(name='multiply', in_type='integer', out_type='integer', operator='*'),
- '//': CInfixDeclaration(name='integerDivide', in_type='integer', out_type='integer', operator='/'),
- '%': CInfixDeclaration(name='modularDivide', in_type='integer', out_type='integer', operator='%'),
- 'and': CInfixDeclaration(name='and', in_type='boolean', out_type='boolean', operator='&&'),
- 'or': CInfixDeclaration(name='or', in_type='boolean', out_type='boolean', operator='||'),
- '==': CInfixDeclaration(name='equals', in_type='integer', out_type='boolean', operator='=='),
- '!=': CInfixDeclaration(name='notEquals', in_type='integer', out_type='boolean', operator='!='),
- '<=': CInfixDeclaration(name='lessThanOrEqual', in_type='integer', out_type='boolean', operator='<='),
- '>=': CInfixDeclaration(name='greaterThanOrEqual', in_type='integer', out_type='boolean', operator='>='),
- '<': CInfixDeclaration(name='lessThan', in_type='integer', out_type='boolean', operator='<'),
- '>': CInfixDeclaration(name='greaterThan', in_type='integer', out_type='boolean', operator='>'),
-}
-
-def transform_comparison_level_expression(accumulators, expression):
- accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator])
-
- # Transform expressions like 1 < 2 < 3 into expressions like 1 < 2 && 2 < 3
- if isinstance(expression.left, parsing.FurInfixExpression) and expression.left.order == 'comparison_level':
- left = transform_comparison_level_expression(
- accumulators,
- expression.left
- )
-
- middle = left.right
-
- right = transform_expression(
- accumulators,
- expression.right,
- )
-
- # TODO Don't evaluate the middle expression twice
- return CFunctionCallForFurInfixOperator(
- name='and',
- left=left,
- right=CFunctionCallForFurInfixOperator(
- name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
- left=middle,
- right=right,
- ),
- )
-
- return CFunctionCallForFurInfixOperator(
- name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
- left=transform_expression(accumulators, expression.left),
- right=transform_expression(accumulators, expression.right),
- )
-
-def transform_infix_operator_without_c_equivalent(accumulators, expression):
- return CFunctionCallForFurInfixOperator(
- name='concatenate',
- left=transform_expression(accumulators, expression.left),
- right=transform_expression(accumulators, expression.right),
- )
-def transform_infix_expression(accumulators, expression):
- if expression.operator in FUR_INFIX_OPERATOR_TO_C_FUNCTION:
- return transform_infix_operator_without_c_equivalent(accumulators, expression)
-
- if expression.order == 'comparison_level':
- return transform_comparison_level_expression(accumulators, expression)
-
- accumulators.operator_set.add(FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator])
-
- return CFunctionCallForFurInfixOperator(
- name=FUR_INFIX_OPERATOR_TO_C_INFIX_OPERATOR[expression.operator].name,
- left=transform_expression(accumulators, expression.left),
- right=transform_expression(accumulators, expression.right),
- )
-