Skip to content

Commit 52cca93

Browse files
authored
add test in while (arxlang#216)
1 parent 82675e4 commit 52cca93

2 files changed

Lines changed: 81 additions & 7 deletions

File tree

src/irx/builders/llvmliteir.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ def visit(self, expr: astx.WhileStmt) -> None:
12831283
self._llvm.ir_builder.branch(cond_bb)
12841284

12851285
# Start inserting into the condition check block.
1286-
self._llvm.ir_builder.position_at_start(cond_bb)
1286+
self._llvm.ir_builder.position_at_end(cond_bb)
12871287

12881288
# Emit the condition.
12891289
self.visit(expr.condition)
@@ -1309,8 +1309,8 @@ def visit(self, expr: astx.WhileStmt) -> None:
13091309
# Conditional branch based on the condition.
13101310
self._llvm.ir_builder.cbranch(cond_val, body_bb, after_bb)
13111311

1312-
# Start inserting into the loop body block.
1313-
self._llvm.ir_builder.position_at_start(body_bb)
1312+
# use position_at_end for body block
1313+
self._llvm.ir_builder.position_at_end(body_bb)
13141314

13151315
# Emit the body of the loop.
13161316
self.visit(expr.body)
@@ -1319,11 +1319,13 @@ def visit(self, expr: astx.WhileStmt) -> None:
13191319
if not body_val:
13201320
return
13211321

1322-
# Branch back to the condition check.
1323-
self._llvm.ir_builder.branch(cond_bb)
1322+
# Don't rely on result_stack for control flow.
1323+
# Only branch back if the block isn't already terminated
1324+
if not self._llvm.ir_builder.block.is_terminated:
1325+
self._llvm.ir_builder.branch(cond_bb)
13241326

1325-
# Start inserting into the block after the loop.
1326-
self._llvm.ir_builder.position_at_start(after_bb)
1327+
# use position_at_end for after block
1328+
self._llvm.ir_builder.position_at_end(after_bb)
13271329

13281330
# While loop always returns 0.
13291331
result = ir.Constant(self._llvm.INT32_TYPE, 0)

tests/test_while.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,75 @@ def test_while_expr(
9595
module.block.append(fn_main)
9696

9797
check_result(action, builder, module, expected_file)
98+
99+
100+
@pytest.mark.parametrize(
101+
"int_type, literal_type",
102+
[
103+
(astx.Int32, astx.LiteralInt32),
104+
(astx.Int16, astx.LiteralInt16),
105+
(astx.Int8, astx.LiteralInt8),
106+
(astx.Int64, astx.LiteralInt64),
107+
],
108+
)
109+
@pytest.mark.parametrize(
110+
"action,expected_file",
111+
[
112+
("build", ""),
113+
],
114+
)
115+
@pytest.mark.parametrize(
116+
"builder_class",
117+
[
118+
LLVMLiteIR,
119+
],
120+
)
121+
def test_while_false_condition(
122+
action: str,
123+
expected_file: str,
124+
builder_class: Type[Builder],
125+
int_type: type,
126+
literal_type: type,
127+
) -> None:
128+
"""
129+
title: Test While loop with a condition that is false from the start.
130+
parameters:
131+
action:
132+
type: str
133+
expected_file:
134+
type: str
135+
builder_class:
136+
type: Type[Builder]
137+
int_type:
138+
type: type
139+
literal_type:
140+
type: type
141+
"""
142+
builder = builder_class()
143+
144+
# Condition is always false: 10 < 0
145+
cond = astx.BinaryOp(
146+
op_code="<",
147+
lhs=literal_type(10),
148+
rhs=literal_type(0),
149+
)
150+
151+
# Body that should never execute
152+
body = astx.Block()
153+
body.append(literal_type(1))
154+
155+
while_expr = astx.WhileStmt(condition=cond, body=body)
156+
157+
proto = astx.FunctionPrototype(
158+
name="main", args=astx.Arguments(), return_type=int_type()
159+
)
160+
fn_block = astx.Block()
161+
fn_block.append(while_expr)
162+
fn_block.append(astx.FunctionReturn(literal_type(0)))
163+
164+
fn_main = astx.FunctionDef(prototype=proto, body=fn_block)
165+
166+
module = builder.module()
167+
module.block.append(fn_main)
168+
169+
check_result(action, builder, module, expected_file)

0 commit comments

Comments
 (0)