6 return tuple(x for xs in xses for x in xs)
8 CIRProgram = collections.namedtuple(
15 CIRLabel = collections.namedtuple(
22 CIRInstruction = collections.namedtuple(
30 def generate_integer_literal(integer):
33 def generate_string_literal(string):
34 return '"{}"'.format(string)
36 def generate_symbol_literal(symbol):
37 return 'sym({})'.format(symbol)
39 def generate_instruction_name_from_builtin(builtin):
42 # Environment operations
47 '__integer_divide__': 'idiv',
48 '__modular_divide__': 'mod',
49 '__multiply__': 'mul',
51 '__subtract__': 'sub',
62 '__concat__': 'concat',
64 # Structure operations
69 import ipdb; ipdb.set_trace()
71 def generate_function_call_expression(counters, expression):
72 if isinstance(expression.function_expression, conversion.CPSBuiltinExpression):
77 instruction=generate_instruction_name_from_builtin(
78 expression.function_expression.symbol,
80 argument=expression.argument_count,
85 referenced_entry_list, instruction_list = generate_expression(
87 expression.function_expression,
93 argument=expression.argument_count,
97 return referenced_entry_list, instruction_list
99 def generate_integer_literal_expression(counters, expression):
100 referenced_entry_list = ()
101 instruction_list = (CIRInstruction(
102 instruction='push_integer',
103 argument=generate_integer_literal(expression.integer),
106 return referenced_entry_list, instruction_list
108 def escape_name(name):
109 return name.replace('$','$$').replace('_','$')
111 def generate_lambda_expression(counters, expression):
112 if expression.name is None:
115 name = escape_name(expression.name)
117 name_counter = counters.get(name, 0)
118 counters[expression.name] = name_counter + 1
119 label = '{}${}'.format(name, name_counter)
121 referenced_entry_list_list = []
122 instruction_list_list = []
124 for statement in expression.statement_list:
125 referenced_entry_list, instruction_list = generate_statement(counters, statement)
126 referenced_entry_list_list.append(referenced_entry_list)
127 instruction_list_list.append(instruction_list)
129 # Pop from the stack in reversed order, because arguments were pushed onto
131 argument_bindings = tuple(
132 CIRInstruction(instruction='pop', argument='sym({})'.format(arg))
133 for arg in reversed(expression.argument_name_list)
136 lambda_body = flatten(instruction_list_list)
137 assert lambda_body[-1].instruction == 'drop'
138 lambda_body = argument_bindings + lambda_body[:-1] + (CIRInstruction(instruction='return', argument=None),)
140 referenced_entry_list_list.append(
141 (CIRLabel(label=label),) + lambda_body,
145 CIRInstruction(instruction='close', argument=label),
148 return flatten(referenced_entry_list_list), instruction_list
150 def generate_list_construct_expression(counters, expression):
151 referenced_entry_list = ()
152 instruction_list = (CIRInstruction(
156 return referenced_entry_list, instruction_list
158 def generate_string_literal_expression(counters, expression):
159 referenced_entry_list = ()
160 instruction_list = (CIRInstruction(
161 instruction='push_string',
162 argument=generate_string_literal(expression.string),
165 return referenced_entry_list, instruction_list
167 def generate_structure_literal_expression(counters, expression):
168 referenced_entry_list = ()
169 instruction_list = (CIRInstruction(
170 instruction='structure',
171 argument=expression.field_count,
174 return referenced_entry_list, instruction_list
176 def generate_symbol_expression(counters, expression):
177 referenced_entry_list = ()
178 instruction_list = (CIRInstruction(
180 argument=generate_symbol_literal(expression.symbol),
183 return referenced_entry_list, instruction_list
185 def generate_symbol_literal_expression(counters, expression):
186 referenced_entry_list = ()
187 instruction_list = (CIRInstruction(
188 instruction='push_symbol',
189 argument=generate_symbol_literal(expression.symbol),
192 return referenced_entry_list, instruction_list
194 def generate_variable_expression(counters, expression):
195 referenced_entry_list = ()
196 instruction_list = (CIRInstruction(
198 argument=generate_symbol_literal(expression.variable),
201 return referenced_entry_list, instruction_list
203 def generate_expression(counters, expression):
205 conversion.CPSFunctionCallExpression: generate_function_call_expression,
206 conversion.CPSIfElseExpression: generate_if_else_expression,
207 conversion.CPSIntegerLiteralExpression: generate_integer_literal_expression,
208 conversion.CPSLambdaExpression: generate_lambda_expression,
209 conversion.CPSListConstructExpression: generate_list_construct_expression,
210 conversion.CPSStringLiteralExpression: generate_string_literal_expression,
211 conversion.CPSStructureLiteralExpression: generate_structure_literal_expression,
212 conversion.CPSSymbolExpression: generate_symbol_expression,
213 conversion.CPSSymbolLiteralExpression: generate_symbol_literal_expression,
214 conversion.CPSVariableExpression: generate_variable_expression,
215 }[type(expression)](counters, expression)
217 def generate_expression_statement(counters, statement):
218 referenced_entry_list, instruction_list = generate_expression(
220 statement.expression,
223 instruction_list += (
230 return referenced_entry_list, instruction_list
232 def generate_if_else_expression(counters, statement):
233 if_counter = counters['if']
236 referenced_entry_list_list = []
238 condition_referenced_entry_list, condition_instruction_list = generate_expression(
240 statement.condition_expression,
243 if_instruction_list_list = []
244 for if_statement in statement.if_statement_list:
245 referenced_entry_list, instruction_list = generate_statement(counters, if_statement)
246 referenced_entry_list_list.append(referenced_entry_list)
247 if_instruction_list_list.append(instruction_list)
249 if_instruction_list = flatten(if_instruction_list_list)
250 assert if_instruction_list[-1].instruction == 'drop'
251 if_instruction_list = if_instruction_list[:-1]
253 else_instruction_list_list = []
255 for else_statement in statement.else_statement_list:
256 referenced_entry_list, instruction_list = generate_statement(counters, else_statement)
257 referenced_entry_list_list.append(referenced_entry_list)
258 else_instruction_list_list.append(instruction_list)
260 else_instruction_list = flatten(else_instruction_list_list)
261 assert else_instruction_list[-1].instruction == 'drop'
262 else_instruction_list = else_instruction_list[:-1]
264 if_label = '__if${}__'.format(if_counter)
265 else_label = '__else${}__'.format(if_counter)
266 endif_label = '__endif${}__'.format(if_counter)
268 instruction_list = condition_instruction_list + (
270 instruction='jump_if_false',
277 CIRLabel(label=if_label),
278 ) + if_instruction_list + (
281 argument=endif_label,
283 CIRLabel(label=else_label),
284 ) + else_instruction_list + (
285 CIRLabel(label=endif_label),
289 condition_referenced_entry_list + flatten(referenced_entry_list_list),
293 def generate_assignment_statement(counters, statement):
294 referenced_entry_list, instruction_list = generate_expression(
296 statement.expression,
299 instruction_list += (
302 argument=generate_symbol_literal(statement.target),
306 return referenced_entry_list, instruction_list
308 def generate_push_statement(counters, statement):
309 return generate_expression(counters, statement.expression)
311 def generate_variable_initialization_statement(counters, statement):
312 referenced_entry_list, instruction_list = generate_expression(
314 statement.expression,
317 instruction_list += (
320 argument=generate_symbol_literal(statement.variable),
324 return referenced_entry_list, instruction_list
326 def generate_statement(counters, statement):
328 conversion.CPSAssignmentStatement: generate_assignment_statement,
329 conversion.CPSExpressionStatement: generate_expression_statement,
330 conversion.CPSPushStatement: generate_push_statement,
331 conversion.CPSVariableInitializationStatement: generate_variable_initialization_statement,
332 }[type(statement)](counters, statement)
334 def generate(converted):
335 referenced_entry_list_list = []
336 instruction_list_list = []
341 for statement in converted.statement_list:
342 referenced_entry_list, instruction_list = generate_statement(counters, statement)
343 referenced_entry_list_list.append(referenced_entry_list)
344 instruction_list_list.append(instruction_list)
347 entry_list=flatten(referenced_entry_list_list) + (
348 CIRLabel(label='__main__'),
349 ) + flatten(instruction_list_list) + (
350 CIRInstruction(instruction='end', argument=None),
354 NO_ARGUMENT_INSTRUCTIONS = set([
359 def format_argument(arg):
367 for entry in program.entry_list:
368 if isinstance(entry, CIRInstruction):
369 if entry.instruction in NO_ARGUMENT_INSTRUCTIONS and entry.argument is None:
370 lines.append(' {}'.format(entry.instruction))
372 lines.append(' {} {}'.format(entry.instruction, format_argument(entry.argument)))
374 if isinstance(entry, CIRLabel):
375 lines.append('\n{}:'.format(entry.label))
377 return '\n'.join(lines).lstrip()