return result;
}
-Object operator$add(Object left, Object right)
+{% for od in operator_declarations %}
+Object operator${{ od.name }}(Object left, Object right)
{
- assert(left.type == INTEGER);
- assert(right.type == INTEGER);
-
- Object result;
- result.type = INTEGER;
- result.instance.integer = left.instance.integer + right.instance.integer;
- return result;
-}
-
-Object operator$subtract(Object left, Object right)
-{
- assert(left.type == INTEGER);
- assert(right.type == INTEGER);
-
- Object result;
- result.type = INTEGER;
- result.instance.integer = left.instance.integer - right.instance.integer;
- return result;
-}
-
-Object operator$multiply(Object left, Object right)
-{
- assert(left.type == INTEGER);
- assert(right.type == INTEGER);
-
- Object result;
- result.type = INTEGER;
- result.instance.integer = left.instance.integer * right.instance.integer;
- return result;
-}
-
-Object operator$integerDivide(Object left, Object right)
-{
- assert(left.type == INTEGER);
- assert(right.type == INTEGER);
+ assert(left.type == {{ od.input_type.upper() }});
+ assert(right.type == {{ od.input_type.upper() }});
Object result;
- result.type = INTEGER;
- result.instance.integer = left.instance.integer / right.instance.integer;
- return result;
-}
-
-Object operator$modularDivide(Object left, Object right)
-{
- assert(left.type == INTEGER);
- assert(right.type == INTEGER);
-
- Object result;
- result.type = INTEGER;
- result.instance.integer = left.instance.integer % right.instance.integer;
+ result.type = {{ od.result_type.upper() }};
+ result.instance.{{ od.result_type.lower() }} = left.instance.{{ od.input_type.lower() }} {{ od.c_operator }} right.instance.{{ od.input_type.lower() }};
return result;
}
+{% endfor %}
Object operator$equals(Object left, Object right)
{
return result;
}
-Object operator$and(Object left, Object right)
-{
- assert(left.type == BOOLEAN);
- assert(right.type == BOOLEAN);
-
- Object result = { BOOLEAN, { left.instance.boolean && right.instance.boolean } };
- return result;
-}
-
-Object operator$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$implementation(Environment* parent, size_t argc, Object* args)
{
[
'builtin_set',
'function_definition_list',
+ 'operator_declarations',
'statements',
'standard_libraries',
'string_literal_list',
symbol_list_index=accumulators.symbol_list.index(expression.value),
)
+CInfixOperatorDeclaration = collections.namedtuple(
+ 'CInfixOperatorDeclaration',
+ [
+ 'name',
+ 'input_type',
+ 'result_type',
+ 'c_operator',
+ ],
+)
+
+INFIX_OPERATOR_TO_DECLARATION = {
+ '+': CInfixOperatorDeclaration(name='add', input_type='INTEGER', result_type='INTEGER', c_operator='+'),
+ '-': CInfixOperatorDeclaration(name='subtract', input_type='INTEGER', result_type='INTEGER', c_operator='-'),
+ '*': CInfixOperatorDeclaration(name='multiply', input_type='INTEGER', result_type='INTEGER', c_operator='*'),
+ '//': CInfixOperatorDeclaration(name='integerDivide', input_type='INTEGER', result_type='INTEGER', c_operator='/'),
+ '%': CInfixOperatorDeclaration(name='modularDivide', input_type='INTEGER', result_type='INTEGER', c_operator='%'),
+ 'and': CInfixOperatorDeclaration(name='and', input_type='BOOLEAN', result_type='BOOLEAN', c_operator='&&'),
+ 'or': CInfixOperatorDeclaration(name='or', input_type='BOOLEAN', result_type='BOOLEAN', c_operator='||'),
+}
+
def transform_infix_expression(accumulators, expression):
if expression.order == 'comparison_level':
return transform_comparison_level_expression(accumulators, expression)
- INFIX_OPERATOR_TO_FUNCTION_NAME = {
- '+': 'add',
- '-': 'subtract',
- '*': 'multiply',
- '//': 'integerDivide',
- '%': 'modularDivide',
- 'and': 'and',
- 'or': 'or',
- }
+ accumulators.operator_set.add(INFIX_OPERATOR_TO_DECLARATION[expression.operator])
return CFunctionCallForFurInfixOperator(
- name=INFIX_OPERATOR_TO_FUNCTION_NAME[expression.operator],
+ name=INFIX_OPERATOR_TO_DECLARATION[expression.operator].name,
left=transform_expression(accumulators, expression.left),
right=transform_expression(accumulators, expression.right),
)
# Parentheses can be removed because everything in the C output is explicitly parenthesized
return transform_expression(accumulators, expression.internal)
+def transform_negation_expression(accumulators, expression):
+ return CNegationExpression(
+ value=transform_expression(accumulators, expression.internal_expression),
+ )
+
def transform_expression(accumulators, expression):
# TODO Clean up handlers for parsing expressions
return {
),
)
-def transform_negation_expression(accumulators, expression):
- return CNegationExpression(
- value=transform_expression(accumulators, expression.internal_expression),
- )
-
def transform_function_call_expression(accumulators, function_call):
if function_call.function.value in BUILTINS.keys():
# TODO Check that the builtin is actually callable
return CProgram(
builtin_set=accumulators.builtin_set,
function_definition_list=accumulators.function_definition_list,
+ operator_declarations=tuple(sorted(accumulators.operator_set)),
statements=statement_list,
standard_libraries=standard_library_set,
string_literal_list=accumulators.string_literal_list,