c_symbol_expression.symbol,
)
+def generate_variable_expression(expression):
+ return expression.variable
+
def generate_expression(expression):
if isinstance(expression, transformation.CNegationExpression):
return generate_negation_expression(expression)
generate_expression(expression.right),
)
- raise Exception('Could not handle expresssion "{}"'.format(expression))
+ return {
+ transformation.CVariableExpression: generate_variable_expression,
+ }[type(expression)](expression)
def generate_negation_expression(c_negation_expression):
return 'builtin$negate({})'.format(
', '.join(generate_expression(argument) for argument in c_function_call.arguments),
)
-def generate_expression_statement(c_function_call_statement):
+def generate_expression_statement(statement):
# TODO Do we need to garbage collect the results of arbitrary statements?
- return '{};'.format(generate_expression(c_function_call_statement))
+ return '{};'.format(generate_expression(statement.expression))
-def generate_assignment_statement(c_assignment_statement):
+def generate_symbol_assignment_statement(c_assignment_statement):
return 'Environment_set(environment, SYMBOL_LIST[{}] /* symbol: {} */, {});'.format(
c_assignment_statement.target_symbol_list_index,
c_assignment_statement.target,
generate_expression(c_assignment_statement.expression),
)
-def generate_statement(statement):
- if isinstance(statement, transformation.CAssignmentStatement):
- return generate_assignment_statement(statement)
+def generate_variable_assignment_statement(statement):
+ return 'Object {} = {};'.format(
+ statement.variable,
+ generate_expression(statement.expression),
+ )
- return generate_expression_statement(statement)
+def generate_statement(statement):
+ return {
+ transformation.CSymbolAssignmentStatement: generate_symbol_assignment_statement,
+ transformation.CExpressionStatement: generate_expression_statement,
+ transformation.CVariableAssignmentStatement: generate_variable_assignment_statement,
+ }[type(statement)](statement)
def generate(program):
template = ENV.get_template('program.c')
import collections
+import parsing
+
+NormalVariableExpression = collections.namedtuple(
+ 'NormalVariableExpression',
+ [
+ 'variable',
+ ],
+)
+
+NormalVariableAssignmentStatement = collections.namedtuple(
+ 'NormalVariableAssignmentStatement',
+ [
+ 'variable',
+ 'expression',
+ ],
+)
+
+NormalFunctionCallExpression = collections.namedtuple(
+ 'NormalFunctionCallExpression',
+ [
+ 'function',
+ 'arguments',
+ ],
+)
+
+NormalExpressionStatement = collections.namedtuple(
+ 'NormalExpressionStatement',
+ [
+ 'expression',
+ ],
+)
+
NormalProgram = collections.namedtuple(
'NormalProgram',
[
],
)
-def flatten(iterable):
- return tuple(item for internal in iterable for item in internal)
+def normalize_function_call_expression(counter, expression):
+ prestatements = []
+ arguments = []
+
+ for argument in expression.arguments:
+ variable = '${}'.format(counter)
+ prestatements.append(NormalVariableAssignmentStatement(
+ variable=variable,
+ expression=argument, # TODO Normalize each argument
+ ))
+ arguments.append(NormalVariableExpression(
+ variable=variable,
+ ))
+ counter += 1
-def normalize_statement(statement):
- return (statement,)
+ return (
+ counter,
+ tuple(prestatements),
+ NormalFunctionCallExpression(
+ expression.function, # TODO Normalize the function
+ arguments=tuple(arguments),
+ ),
+ )
+
+def normalize_statement(counter, statement):
+ if isinstance(statement, parsing.FurExpressionStatement):
+ counter, prestatements, normalized = {
+ parsing.FurFunctionCallExpression: normalize_function_call_expression,
+ }[type(statement.expression)](counter, statement.expression)
+
+ return (
+ counter,
+ prestatements,
+ NormalExpressionStatement(expression=normalized),
+ )
+
+ return (counter, (), statement)
def normalize(program):
+ counter = 0
+ statement_list = []
+
+ for statement in program.statement_list:
+ counter, prestatements, normalized = normalize_statement(counter, statement)
+ for s in prestatements:
+ statement_list.append(s)
+ statement_list.append(normalized)
+
return NormalProgram(
- statement_list=flatten(normalize_statement(s) for s in program.statement_list),
+ statement_list=statement_list,
)
import collections
+import normalization
import parsing
CIntegerLiteral = collections.namedtuple(
],
)
+CVariableExpression = collections.namedtuple(
+ 'CVariableExpression',
+ [
+ 'variable',
+ ],
+)
+
CSymbolExpression = collections.namedtuple(
'CSymbolExpression',
[
],
)
-CAssignmentStatement = collections.namedtuple(
- 'CAssignmentStatement',
+CSymbolAssignmentStatement = collections.namedtuple(
+ 'CSymbolAssignmentStatement',
[
'target',
'target_symbol_list_index',
],
)
+CVariableAssignmentStatement = collections.namedtuple(
+ 'CVariableAssignmentStatement',
+ [
+ 'variable',
+ 'expression',
+ ],
+)
+
+CExpressionStatement = collections.namedtuple(
+ 'CExpressionStatement',
+ [
+ 'expression',
+ ],
+)
+
CProgram = collections.namedtuple(
'CProgram',
[
'true': [],
}
+def transform_variable_expression(accumulators, expression):
+ return CVariableExpression(variable=expression.variable)
+
def transform_expression(accumulators, expression):
if isinstance(expression, parsing.FurParenthesizedExpression):
# Parentheses can be removed because everything in the C output is explicitly parenthesized
right=transform_expression(accumulators, expression.right),
)
- raise Exception('Could not transform expression "{}"'.format(expression))
+ # TODO Handle all possible types in this form
+ return {
+ normalization.NormalVariableExpression: transform_variable_expression,
+ }[type(expression)](accumulators, expression)
-def transform_assignment_statement(accumulators, assignment_statement):
+def transform_symbol_assignment_statement(accumulators, assignment_statement):
# TODO Check that target is not a builtin
if assignment_statement.target not in accumulators.symbol_list:
accumulators.symbol_list.append(assignment_statement.target)
- return CAssignmentStatement(
+ return CSymbolAssignmentStatement(
target=assignment_statement.target,
target_symbol_list_index=accumulators.symbol_list.index(assignment_statement.target),
expression=transform_expression(
raise Exception()
def transform_expression_statement(accumulators, statement):
- return {
+ expression = {
parsing.FurFunctionCallExpression: transform_function_call_expression,
+ normalization.NormalFunctionCallExpression: transform_function_call_expression,
}[type(statement.expression)](accumulators, statement.expression)
+ return CExpressionStatement(
+ expression=expression,
+ )
+
+def transform_variable_assignment_statement(accumulators, statement):
+ return CVariableAssignmentStatement(
+ variable=statement.variable,
+ expression=transform_expression(accumulators, statement.expression),
+ )
+
def transform_statement(accumulators, statement):
return {
- parsing.FurAssignmentStatement: transform_assignment_statement,
+ parsing.FurAssignmentStatement: transform_symbol_assignment_statement,
parsing.FurExpressionStatement: transform_expression_statement,
+ normalization.NormalVariableAssignmentStatement: transform_variable_assignment_statement,
+ normalization.NormalExpressionStatement: transform_expression_statement,
}[type(statement)](accumulators, statement)