From 02f896ed7d1a088def0d12c7a55a6f67c034ab21 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Mon, 28 Dec 2020 18:01:13 -0700 Subject: implement while loops --- crowbar_reference_compiler/ast.py | 7 +++++++ crowbar_reference_compiler/ssagen.py | 23 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/crowbar_reference_compiler/ast.py b/crowbar_reference_compiler/ast.py index 142fa8e..7ae7ff9 100644 --- a/crowbar_reference_compiler/ast.py +++ b/crowbar_reference_compiler/ast.py @@ -531,6 +531,13 @@ class ASTBuilder(NodeVisitor): assert kwd.type == 'else' return IfStatement(condition, then, els) + def visit_WhileStatement(self, node, visited_children): + kwd, lparen, condition, rparen, body = visited_children + assert kwd.type == 'while' + assert lparen.type == '(' + assert rparen.type == ')' + return WhileStatement(condition, body) + def visit_ReturnStatement(self, node, visited_children): ret, body, semi = visited_children assert ret.type == 'return' diff --git a/crowbar_reference_compiler/ssagen.py b/crowbar_reference_compiler/ssagen.py index 5212440..c71ddc4 100644 --- a/crowbar_reference_compiler/ssagen.py +++ b/crowbar_reference_compiler/ssagen.py @@ -7,7 +7,8 @@ from .ast import ImplementationFile, FunctionDefinition, ExpressionStatement, Fu VariableExpression, ConstantExpression, ReturnStatement, BasicType, IfStatement, ComparisonExpression, \ AddExpression, StructPointerElementExpression, Declaration, PointerType, StructDeclaration, VariableDefinition, \ MultiplyExpression, LogicalNotExpression, DirectAssignment, UpdateAssignment, SizeofExpression, Expression, \ - ConstType, ArrayIndexExpression, ArrayType, NegativeExpression, SubtractExpression, AddressOfExpression + ConstType, ArrayIndexExpression, ArrayType, NegativeExpression, SubtractExpression, AddressOfExpression, \ + WhileStatement @dataclass @@ -181,6 +182,26 @@ def _(target: IfStatement, context: CompileContext) -> SsaResult: return result +@compile_to_ssa.register +def _(target: WhileStatement, context: CompileContext) -> SsaResult: + start_label = context.next_label + context.next_label += 1 + result = SsaResult([], [f"@l{start_label}"]) + body_label = context.next_label + context.next_label += 1 + end_label = context.next_label + context.next_label += 1 + result += compile_to_ssa(target.condition, context) + condition_dest = context.next_temp - 1 + result.code.append(f"jnz %t{condition_dest}, @l{body_label}, @l{end_label}") + result.code.append(f"@l{body_label}") + for statement in target.body: + result += compile_to_ssa(statement, context) + result.code.append(f"jmp @l{start_label}") + result.code.append(f"@l{end_label}") + return result + + @compile_to_ssa.register def _(target: ComparisonExpression, context: CompileContext) -> SsaResult: result = compile_to_ssa(target.value1, context) -- cgit v1.2.3