X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=desugaring.py;h=28d1a7820748b4ae463d1dc2b8aab73e3f47cdd7;hp=ef5163993bfc6266c72cfe9819d3e1ab970723ac;hb=3dc627f8d6b5846081ef8ed15d5546e51d2ecb8d;hpb=cccc042f21a9c90cbd78cbad28288160a5899a33 diff --git a/desugaring.py b/desugaring.py index ef51639..28d1a78 100644 --- a/desugaring.py +++ b/desugaring.py @@ -1,5 +1,108 @@ import collections +import parsing + +DesugaredBuiltinExpression = collections.namedtuple( + 'DesugaredBuiltinExpression', + ( + 'metadata', + 'symbol', + ), +) + +DesugaredFunctionCallExpression = collections.namedtuple( + 'DesugaredFunctionCallExpression', + ( + 'metadata', + 'function', + 'argument_list', + ), +) + +DesugaredIfExpression = collections.namedtuple( + 'DesugaredIfExpression', + ( + 'condition_expression', + 'if_statement_list', + 'else_statement_list', + ), +) + +DesugaredIntegerLiteralExpression = collections.namedtuple( + 'DesugaredIntegerLiteralExpression', + ( + 'integer', + ), +) + +_DesugaredLambdaExpression = collections.namedtuple( + 'DesugaredLambdaExpression', + ( + 'name', + 'argument_name_list', + 'statement_list', + ), +) + +class DesugaredLambdaExpression(_DesugaredLambdaExpression): + def __new__(cls, *args, **kwargs): + if 'name' not in kwargs: + kwargs['name'] = None + + return super(DesugaredLambdaExpression, cls).__new__(cls, *args, **kwargs) + +DesugaredListLiteralExpression = collections.namedtuple( + 'DesugaredListLiteralExpression', + ( + 'item_expression_list', + ), +) + +DesugaredStringLiteralExpression = collections.namedtuple( + 'DesugaredStringLiteralExpression', + ( + 'string', + ), +) + +DesugaredSymbolExpressionPair = collections.namedtuple( + 'DesugaredSymbolExpressionPair', + ( + 'symbol', + 'expression', + ), +) + +DesugaredStructureLiteralExpression = collections.namedtuple( + 'DesugaredStructureLiteralExpression', + ( + 'fields', + ), +) + +DesugaredSymbolExpression = collections.namedtuple( + 'DesugaredSymbolExpression', + ( + 'metadata', + 'symbol', + ), +) + +DesugaredAssignmentStatement = collections.namedtuple( + 'DesugaredAssignmentStatement', + ( + 'target', + 'expression', + ), +) + +DesugaredExpressionStatement = collections.namedtuple( + 'DesugaredExpressionStatement', + ( + 'expression', + ), +) + DesugaredProgram = collections.namedtuple( 'DesugaredProgram', ( @@ -7,7 +110,199 @@ DesugaredProgram = collections.namedtuple( ), ) +def desugar_function_call_expression(expression): + return DesugaredFunctionCallExpression( + metadata=expression.metadata, + function=desugar_expression(expression.function), + argument_list=tuple(desugar_expression(e) for e in expression.arguments), + ) + +def desugar_if_expression(expression): + return DesugaredIfExpression( + condition_expression=desugar_expression(expression.condition_expression), + if_statement_list=tuple(desugar_statement(s) for s in expression.if_statement_list), + else_statement_list=tuple(desugar_statement(s) for s in expression.else_statement_list), + ) + +def desugar_infix_expression(expression): + if expression.operator == 'and': + return DesugaredIfExpression( + condition_expression=desugar_expression(expression.left), + if_statement_list=( + DesugaredExpressionStatement(expression=desugar_expression(expression.right)), + ), + else_statement_list=( + DesugaredExpressionStatement( + expression=DesugaredSymbolExpression( + metadata=expression.metadata, + symbol='false', + ), + ), + ), + ) + + if expression.operator == 'or': + return DesugaredIfExpression( + condition_expression=desugar_expression(expression.left), + if_statement_list=( + DesugaredExpressionStatement( + expression=DesugaredSymbolExpression( + metadata=expression.metadata, + symbol='true', + ), + ), + ), + else_statement_list=( + DesugaredExpressionStatement(expression=desugar_expression(expression.right)), + ), + ) + + if expression.operator == '.': + return DesugaredFunctionCallExpression( + metadata=expression.metadata, + function=DesugaredSymbolExpression( + metadata=expression.metadata, + symbol='__field__', + ), + argument_list=( + desugar_expression(expression.left), + DesugaredStringLiteralExpression(string=expression.right.symbol), + ), + ) + + function = { + '++': '__concat__', + '+': '__add__', + '-': '__subtract__', + '*': '__multiply__', + '//': '__integer_divide__', + '%': '__modular_divide__', + '<': '__lt__', + '>': '__gt__', + '<=': '__lte__', + '>=': '__gte__', + '==': '__eq__', + '!=': '__neq__', + }[expression.operator] + + return DesugaredFunctionCallExpression( + metadata=expression.metadata, + function=DesugaredBuiltinExpression( + metadata=expression.metadata, + symbol=function, + ), + argument_list=( + desugar_expression(expression.left), + desugar_expression(expression.right), + ), + ) + +def desugar_integer_literal_expression(expression): + return DesugaredIntegerLiteralExpression( + integer=expression.integer, + ) + +def desugar_lambda_expression(expression): + return DesugaredLambdaExpression( + argument_name_list=expression.argument_name_list, + statement_list=tuple(desugar_statement(s) for s in expression.statement_list), + ) + +def desugar_list_item_expression(expression): + return DesugaredFunctionCallExpression( + metadata=expression.metadata, + function=DesugaredBuiltinExpression( + metadata=expression.metadata, + symbol='__get__', + ), + argument_list=( + desugar_expression(expression.list_expression), + desugar_expression(expression.index_expression), + ), + ) + +def desugar_list_literal_expression(expression): + return DesugaredListLiteralExpression( + item_expression_list=tuple(desugar_expression(i) for i in expression.item_expression_list), + ) + +def desugar_negation_expression(expression): + return DesugaredFunctionCallExpression( + metadata=expression.metadata, + function=DesugaredBuiltinExpression( + metadata=expression.metadata, + symbol='__negate__', + ), + argument_list=( + desugar_expression(expression.value), + ), + ) + +def desugar_string_literal_expression(expression): + return DesugaredStringLiteralExpression( + string=expression.string, + ) + +def desugar_structure_literal_expression(expression): + return DesugaredStructureLiteralExpression( + fields=tuple( + DesugaredSymbolExpressionPair( + symbol=p.symbol, + expression=desugar_expression(p.expression), + ) for p in expression.fields + ), + ) + +def desugar_symbol_expression(expression): + return DesugaredSymbolExpression( + metadata=expression.metadata, + symbol=expression.symbol, + ) + +def desugar_expression(expression): + return { + parsing.FurFunctionCallExpression: desugar_function_call_expression, + parsing.FurIfExpression: desugar_if_expression, + parsing.FurInfixExpression: desugar_infix_expression, + parsing.FurIntegerLiteralExpression: desugar_integer_literal_expression, + parsing.FurLambdaExpression: desugar_lambda_expression, + parsing.FurListItemExpression: desugar_list_item_expression, + parsing.FurListLiteralExpression: desugar_list_literal_expression, + parsing.FurNegationExpression: desugar_negation_expression, + parsing.FurStringLiteralExpression: desugar_string_literal_expression, + parsing.FurStructureLiteralExpression: desugar_structure_literal_expression, + parsing.FurSymbolExpression: desugar_symbol_expression, + }[type(expression)](expression) + +def desugar_assignment_statement(statement): + return DesugaredAssignmentStatement( + target=statement.target, + expression=desugar_expression(statement.expression), + ) + +def desugar_expression_statement(statement): + return DesugaredExpressionStatement( + expression=desugar_expression(statement.expression), + ) + +def desugar_function_definition_statement(statement): + return DesugaredAssignmentStatement( + target=statement.name, + expression=DesugaredLambdaExpression( + name=statement.name, + argument_name_list=statement.argument_name_list, + statement_list=tuple(desugar_statement(s) for s in statement.statement_list), + ), + ) + +def desugar_statement(statement): + return { + parsing.FurAssignmentStatement: desugar_assignment_statement, + parsing.FurExpressionStatement: desugar_expression_statement, + parsing.FurFunctionDefinitionStatement: desugar_function_definition_statement, + }[type(statement)](statement) + def desugar(program): return DesugaredProgram( - statement_list=program.statement_list, + statement_list=[desugar_statement(s) for s in program.statement_list], )