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_function_call_expression(counters, expression):
40 referenced_entry_list, instruction_list = generate_expression(
42 expression.function_expression,
48 argument=expression.argument_count,
52 return referenced_entry_list, instruction_list
54 def generate_integer_literal_expression(counters, expression):
55 referenced_entry_list = ()
56 instruction_list = (CIRInstruction(
57 instruction='push_value',
58 argument=generate_integer_literal(expression.integer),
61 return referenced_entry_list, instruction_list
63 def generate_lambda_expression(counters, expression):
64 if expression.name is None or 'lambda' in expression.name.lower():
65 import ipdb; ipdb.set_trace()
67 name_counter = counters.get(expression.name, 0)
68 counters[expression.name] = name_counter + 1
69 label = '{}${}'.format(expression.name, name_counter)
71 for argument_name in expression.argument_name_list:
72 import ipdb; ipdb.set_trace()
74 referenced_entry_list_list = []
75 instruction_list_list = []
77 for statement in expression.statement_list:
78 referenced_entry_list, instruction_list = generate_statement(counters, statement)
79 referenced_entry_list_list.append(referenced_entry_list)
80 instruction_list_list.append(instruction_list)
82 lambda_body = flatten(instruction_list_list)
83 assert lambda_body[-1].instruction == 'drop'
84 lambda_body = lambda_body[:-1] + (CIRInstruction(instruction='return', argument=None),)
86 referenced_entry_list_list.append(
87 (CIRLabel(label=label),) + lambda_body,
91 CIRInstruction(instruction='close', argument=label),
94 return flatten(referenced_entry_list_list), instruction_list
96 def generate_string_literal_expression(counters, expression):
97 referenced_entry_list = ()
98 instruction_list = (CIRInstruction(
99 instruction='push_value',
100 argument=generate_string_literal(expression.string),
103 return referenced_entry_list, instruction_list
105 def generate_symbol_expression(counters, expression):
106 referenced_entry_list = ()
107 instruction_list = (CIRInstruction(
109 argument=generate_symbol_literal(expression.symbol),
112 return referenced_entry_list, instruction_list
114 def generate_variable_expression(counters, expression):
115 referenced_entry_list = ()
116 instruction_list = (CIRInstruction(
118 argument=generate_symbol_literal(expression.variable),
121 return referenced_entry_list, instruction_list
123 def generate_expression(counters, expression):
125 conversion.CPSFunctionCallExpression: generate_function_call_expression,
126 conversion.CPSIfElseExpression: generate_if_else_expression,
127 conversion.CPSIntegerLiteralExpression: generate_integer_literal_expression,
128 conversion.CPSLambdaExpression: generate_lambda_expression,
129 conversion.CPSStringLiteralExpression: generate_string_literal_expression,
130 conversion.CPSSymbolExpression: generate_symbol_expression,
131 conversion.CPSVariableExpression: generate_variable_expression,
132 }[type(expression)](counters, expression)
134 def generate_expression_statement(counters, statement):
135 referenced_entry_list, instruction_list = generate_expression(
137 statement.expression,
140 instruction_list += (
147 return referenced_entry_list, instruction_list
149 def generate_if_else_expression(counters, statement):
150 if_counter = counters['if']
153 referenced_entry_list_list = []
155 condition_referenced_entry_list, condition_instruction_list = generate_expression(
157 statement.condition_expression,
160 if_instruction_list_list = []
161 for if_statement in statement.if_statement_list:
162 referenced_entry_list, instruction_list = generate_statement(counters, if_statement)
163 referenced_entry_list_list.append(referenced_entry_list)
164 if_instruction_list_list.append(instruction_list)
166 if_instruction_list = flatten(if_instruction_list_list)
167 assert if_instruction_list[-1].instruction == 'drop'
168 if_instruction_list = if_instruction_list[:-1]
170 else_instruction_list_list = []
172 for else_statement in statement.else_statement_list:
173 referenced_entry_list, instruction_list = generate_statement(counters, else_statement)
174 referenced_entry_list_list.append(referenced_entry_list)
175 else_instruction_list_list.append(instruction_list)
177 else_instruction_list = flatten(else_instruction_list_list)
178 assert else_instruction_list[-1].instruction == 'drop'
179 else_instruction_list = else_instruction_list[:-1]
181 if_label = '__if${}__'.format(if_counter)
182 else_label = '__else${}__'.format(if_counter)
183 endif_label = '__endif${}__'.format(if_counter)
185 instruction_list = condition_instruction_list + (
187 instruction='jump_if_false',
194 CIRLabel(label=if_label),
195 ) + if_instruction_list + (
198 argument=endif_label,
200 CIRLabel(label=else_label),
201 ) + else_instruction_list + (
202 CIRLabel(label=endif_label),
206 condition_referenced_entry_list + flatten(referenced_entry_list_list),
210 def generate_assignment_statement(counters, statement):
211 referenced_entry_list, instruction_list = generate_expression(
213 statement.expression,
216 instruction_list += (
219 argument=generate_symbol_literal(statement.target),
223 return referenced_entry_list, instruction_list
225 def generate_push_statement(counters, statement):
226 return generate_expression(counters, statement.expression)
228 def generate_variable_initialization_statement(counters, statement):
229 referenced_entry_list, instruction_list = generate_expression(
231 statement.expression,
234 instruction_list += (
237 argument=generate_symbol_literal(statement.variable),
241 return referenced_entry_list, instruction_list
243 def generate_statement(counters, statement):
245 conversion.CPSAssignmentStatement: generate_assignment_statement,
246 conversion.CPSExpressionStatement: generate_expression_statement,
247 conversion.CPSPushStatement: generate_push_statement,
248 conversion.CPSVariableInitializationStatement: generate_variable_initialization_statement,
249 }[type(statement)](counters, statement)
251 def generate(converted):
252 referenced_entry_list_list = []
253 instruction_list_list = []
258 for statement in converted.statement_list:
259 referenced_entry_list, instruction_list = generate_statement(counters, statement)
260 referenced_entry_list_list.append(referenced_entry_list)
261 instruction_list_list.append(instruction_list)
264 entry_list=flatten(referenced_entry_list_list) + (
265 CIRLabel(label='__main__'),
266 ) + flatten(instruction_list_list),
269 NO_ARGUMENT_INSTRUCTIONS = set([
274 def format_argument(arg):
282 for entry in program.entry_list:
283 if isinstance(entry, CIRInstruction):
284 if entry.instruction in NO_ARGUMENT_INSTRUCTIONS and entry.argument is None:
285 lines.append(' {}'.format(entry.instruction))
287 lines.append(' {} {}'.format(entry.instruction, format_argument(entry.argument)))
289 if isinstance(entry, CIRLabel):
290 lines.append('\n{}:'.format(entry.label))
292 return '\n'.join(lines).lstrip()