diff options
author | Melody Horn <melody@boringcactus.com> | 2020-12-28 18:01:13 -0700 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2020-12-28 18:01:13 -0700 |
commit | 02f896ed7d1a088def0d12c7a55a6f67c034ab21 (patch) | |
tree | 6095938f15eb8fb0cf16ef078c3e88b6b90f8f90 | |
parent | d24baa5a06d1ed235bb6cfb1c35b8490c18a3175 (diff) | |
download | reference-compiler-02f896ed7d1a088def0d12c7a55a6f67c034ab21.tar.gz reference-compiler-02f896ed7d1a088def0d12c7a55a6f67c034ab21.zip |
implement while loops
-rw-r--r-- | crowbar_reference_compiler/ast.py | 7 | ||||
-rw-r--r-- | crowbar_reference_compiler/ssagen.py | 23 |
2 files changed, 29 insertions, 1 deletions
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 @@ -182,6 +183,26 @@ def _(target: IfStatement, context: CompileContext) -> SsaResult: @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) value1_dest = context.next_temp - 1 |