X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=crossplatform_ir_generation.py;h=f9c7fa9d4c0c16211fca73974804b415ccdd162a;hp=332a74ff76e15037feb81c8b8920236f2e460d12;hb=4f86ad3f093ca0c51e77a28b208e7751629d4948;hpb=ecbec68813b8dbd559354d9f0fe023a01d351fe9 diff --git a/crossplatform_ir_generation.py b/crossplatform_ir_generation.py index 332a74f..f9c7fa9 100644 --- a/crossplatform_ir_generation.py +++ b/crossplatform_ir_generation.py @@ -36,7 +36,49 @@ def generate_string_literal(string): def generate_symbol_literal(symbol): return 'sym({})'.format(symbol) +def generate_instruction_name_from_builtin(builtin): + try: + return { + # Environment operations + '__get__': 'get', + + # Integer operations + '__add__': 'add', + '__integer_divide__': 'idiv', + '__modular_divide__': 'mod', + '__multiply__': 'mul', + '__negate__': 'neg', + '__subtract__': 'sub', + + # Boolean operations + '__eq__': 'eq', + '__neq__': 'neq', + '__lt__': 'lt', + '__lte__': 'lte', + '__gt__': 'gt', + '__gte__': 'gte', + + # String operations + '__concat__': 'concat', + }[builtin] + + except KeyError: + import ipdb; ipdb.set_trace() + def generate_function_call_expression(counters, expression): + if isinstance(expression.function_expression, conversion.CPSBuiltinExpression): + return ( + (), + ( + CIRInstruction( + instruction=generate_instruction_name_from_builtin( + expression.function_expression.symbol, + ), + argument=expression.argument_count, + ), + ) + ) + referenced_entry_list, instruction_list = generate_expression( counters, expression.function_expression, @@ -54,22 +96,24 @@ def generate_function_call_expression(counters, expression): def generate_integer_literal_expression(counters, expression): referenced_entry_list = () instruction_list = (CIRInstruction( - instruction='push_value', + instruction='push_integer', argument=generate_integer_literal(expression.integer), ),) return referenced_entry_list, instruction_list +def escape_name(name): + return name.replace('$','$$').replace('_','$') + def generate_lambda_expression(counters, expression): - if expression.name is None or 'lambda' in expression.name.lower(): - import ipdb; ipdb.set_trace() + if expression.name is None: + name = '__lambda__' + else: + name = escape_name(expression.name) - name_counter = counters.get(expression.name, 0) + name_counter = counters.get(name, 0) counters[expression.name] = name_counter + 1 - label = '{}${}'.format(expression.name, name_counter) - - for argument_name in expression.argument_name_list: - import ipdb; ipdb.set_trace() + label = '{}${}'.format(name, name_counter) referenced_entry_list_list = [] instruction_list_list = [] @@ -79,9 +123,16 @@ def generate_lambda_expression(counters, expression): referenced_entry_list_list.append(referenced_entry_list) instruction_list_list.append(instruction_list) + # Pop from the stack in reversed order, because arguments were pushed onto + # the stack in order + argument_bindings = tuple( + CIRInstruction(instruction='pop', argument='sym({})'.format(arg)) + for arg in reversed(expression.argument_name_list) + ) + lambda_body = flatten(instruction_list_list) assert lambda_body[-1].instruction == 'drop' - lambda_body = lambda_body[:-1] + (CIRInstruction(instruction='return', argument=None),) + lambda_body = argument_bindings + lambda_body[:-1] + (CIRInstruction(instruction='return', argument=None),) referenced_entry_list_list.append( (CIRLabel(label=label),) + lambda_body, @@ -93,15 +144,32 @@ def generate_lambda_expression(counters, expression): return flatten(referenced_entry_list_list), instruction_list +def generate_list_construct_expression(counters, expression): + referenced_entry_list = () + instruction_list = (CIRInstruction( + instruction='list', + argument=2, + ),) + return referenced_entry_list, instruction_list + def generate_string_literal_expression(counters, expression): referenced_entry_list = () instruction_list = (CIRInstruction( - instruction='push_value', + instruction='push_string', argument=generate_string_literal(expression.string), ),) return referenced_entry_list, instruction_list +def generate_structure_literal_expression(counters, expression): + referenced_entry_list = () + instruction_list = (CIRInstruction( + instruction='structure', + argument=expression.field_count, + ),) + + return referenced_entry_list, instruction_list + def generate_symbol_expression(counters, expression): referenced_entry_list = () instruction_list = (CIRInstruction( @@ -111,6 +179,15 @@ def generate_symbol_expression(counters, expression): return referenced_entry_list, instruction_list +def generate_symbol_literal_expression(counters, expression): + referenced_entry_list = () + instruction_list = (CIRInstruction( + instruction='push_symbol', + argument=generate_symbol_literal(expression.symbol), + ),) + + return referenced_entry_list, instruction_list + def generate_variable_expression(counters, expression): referenced_entry_list = () instruction_list = (CIRInstruction( @@ -126,8 +203,11 @@ def generate_expression(counters, expression): conversion.CPSIfElseExpression: generate_if_else_expression, conversion.CPSIntegerLiteralExpression: generate_integer_literal_expression, conversion.CPSLambdaExpression: generate_lambda_expression, + conversion.CPSListConstructExpression: generate_list_construct_expression, conversion.CPSStringLiteralExpression: generate_string_literal_expression, + conversion.CPSStructureLiteralExpression: generate_structure_literal_expression, conversion.CPSSymbolExpression: generate_symbol_expression, + conversion.CPSSymbolLiteralExpression: generate_symbol_literal_expression, conversion.CPSVariableExpression: generate_variable_expression, }[type(expression)](counters, expression) @@ -263,7 +343,9 @@ def generate(converted): return CIRProgram( entry_list=flatten(referenced_entry_list_list) + ( CIRLabel(label='__main__'), - ) + flatten(instruction_list_list), + ) + flatten(instruction_list_list) + ( + CIRInstruction(instruction='end', argument=None), + ) ) NO_ARGUMENT_INSTRUCTIONS = set([