Skip to content

Commit 4a197d7

Browse files
authored
native: for statement : add support for all expressions handled by g.condition (#23752)
1 parent ce666a8 commit 4a197d7

5 files changed

Lines changed: 33 additions & 56 deletions

File tree

‎vlib/v/gen/native/expr.v‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,9 @@ fn (mut g Gen) local_var_ident(ident ast.Ident, var LocalVar) {
152152
}
153153

154154
fn (mut g Gen) condition(expr ast.Expr, neg bool) i32 {
155+
g.println('; condition cjmp if ${neg}:')
155156
g.expr(expr)
156-
g.code_gen.cmp_zero(g.code_gen.main_reg())
157+
g.code_gen.cmp_zero(g.code_gen.main_reg()) // 0 is false
157158
return g.code_gen.cjmp(if neg { .jne } else { .je })
158159
}
159160

‎vlib/v/gen/native/gen.v‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ mut:
180180
}
181181

182182
struct LabelPatch {
183-
id i32
184-
pos i32
183+
id i32 // id of the needed label address
184+
pos i32 // where (in the generated code) to fix the address (of a jump for example)
185185
}
186186

187187
struct BranchLabel {

‎vlib/v/gen/native/stmt.c.v‎

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
110110
ast.TypeDecl {}
111111
ast.InterfaceDecl {}
112112
else {
113-
eprintln('native.stmt(): bad node: ' + node.type_name())
113+
g.n_error('native.stmt(): bad node: ' + node.type_name())
114114
}
115115
}
116116
}
@@ -208,62 +208,23 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
208208
g.println('; label ${end_label}')
209209
return
210210
}
211-
infix_expr := node.cond as ast.InfixExpr
212-
mut jump_addr := i32(0) // location of `jne *00 00 00 00*`
211+
g.println('; for stmt {')
212+
213213
start := g.pos()
214214
start_label := g.labels.new_label()
215215
g.labels.addrs[start_label] = start
216-
g.println('; label ${start_label}')
217-
match infix_expr.left {
218-
ast.Ident {
219-
match infix_expr.right {
220-
ast.Ident {
221-
reg := g.code_gen.main_reg()
222-
g.code_gen.mov_var_to_reg(reg, infix_expr.right as ast.Ident)
223-
g.code_gen.cmp_var_reg(infix_expr.left as ast.Ident, reg)
224-
}
225-
ast.IntegerLiteral {
226-
lit := infix_expr.right as ast.IntegerLiteral
227-
g.code_gen.cmp_var(infix_expr.left as ast.Ident, i32(lit.val.int()))
228-
}
229-
else {
230-
g.n_error('unhandled expression type')
231-
}
232-
}
233-
match infix_expr.left.tok_kind {
234-
.lt {
235-
jump_addr = g.code_gen.cjmp(.jge)
236-
}
237-
.gt {
238-
jump_addr = g.code_gen.cjmp(.jle)
239-
}
240-
.le {
241-
jump_addr = g.code_gen.cjmp(.jg)
242-
}
243-
.ge {
244-
jump_addr = g.code_gen.cjmp(.jl)
245-
}
246-
.ne {
247-
jump_addr = g.code_gen.cjmp(.je)
248-
}
249-
.eq {
250-
jump_addr = g.code_gen.cjmp(.jne)
251-
}
252-
else {
253-
g.n_error('unhandled infix cond token')
254-
}
255-
}
256-
}
257-
else {
258-
g.n_error('unhandled infix.left')
259-
}
260-
}
216+
g.println('; label ${start_label} (start of for loop)')
217+
218+
// Condition
219+
mut cjmp_addr := g.condition(node.cond, false) // jmp if false, location of `jne *00 00 00 00*` (to be patched by LabelPatch)
261220
end_label := g.labels.new_label()
262221
g.labels.patches << LabelPatch{
263222
id: end_label
264-
pos: jump_addr
223+
pos: cjmp_addr
265224
}
266-
g.println('; jump to label ${end_label}')
225+
g.println('; cjmp to label ${end_label} (out of loop)')
226+
227+
// Body of the loop
267228
g.labels.branches << BranchLabel{
268229
name: node.label
269230
start: start_label
@@ -273,10 +234,11 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
273234
g.labels.branches.pop()
274235
// Go back to `cmp ...`
275236
g.code_gen.jmp_back(start)
276-
// Update the jump addr to current pos
237+
238+
g.println('; for stmt }')
239+
// Set the jump (out of the loop) addr to current pos
277240
g.labels.addrs[end_label] = g.pos()
278-
g.println('; label ${end_label}')
279-
g.println('jmp after for')
241+
g.println('; label ${end_label} (out of for loop)')
280242
}
281243

282244
fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { // Work on that
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ fn simple_for_test() {
2323
println('loop5')
2424
i--
2525
}
26+
i = 0
27+
for i * i < 3 {
28+
println('loop6')
29+
i++
30+
}
31+
i = 0
32+
for 3 > i * i {
33+
println('loop7')
34+
i++
35+
}
2636
}
2737

2838
fn break_continue_test() {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ loop4
1616
loop5
1717
loop5
1818
loop5
19+
loop6
20+
loop6
21+
loop7
22+
loop7
1923
loop1
2024
loop1
2125
loop2

0 commit comments

Comments
 (0)