Make stuctures and lists work
[fur] / crossplatform_ir_generation.py
index c6adb95..f9c7fa9 100644 (file)
@@ -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,19 +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)
+    label = '{}${}'.format(name, name_counter)
 
     referenced_entry_list_list = []
     instruction_list_list = []
@@ -97,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(
@@ -115,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(
@@ -130,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)
 
@@ -267,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([