Skip to content

Commit 8d5c74e

Browse files
committed
compile: Implement while and if
1 parent ac9ca13 commit 8d5c74e

File tree

3 files changed

+109
-5
lines changed

3 files changed

+109
-5
lines changed

compile/compile.go

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func (c *compiler) Jump(Op byte, Dest *Label) {
209209
switch Op {
210210
case vm.JUMP_IF_FALSE_OR_POP, vm.JUMP_IF_TRUE_OR_POP, vm.JUMP_ABSOLUTE, vm.POP_JUMP_IF_FALSE, vm.POP_JUMP_IF_TRUE: // Absolute
211211
c.OpCodes.Add(&JumpAbs{OpArg: OpArg{Op: Op}, Dest: Dest})
212-
case vm.JUMP_FORWARD: // Relative
212+
case vm.JUMP_FORWARD, vm.SETUP_WITH, vm.FOR_ITER, vm.SETUP_LOOP, vm.SETUP_EXCEPT, vm.SETUP_FINALLY:
213213
c.OpCodes.Add(&JumpRel{OpArg: OpArg{Op: Op}, Dest: Dest})
214214
default:
215215
panic("Jump called with non jump instruction")
@@ -314,12 +314,42 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
314314
// Test Expr
315315
// Body []Stmt
316316
// Orelse []Stmt
317-
panic("FIXME compile: While not implemented")
317+
endwhile := new(Label)
318+
endpopblock := new(Label)
319+
c.Jump(vm.SETUP_LOOP, endpopblock)
320+
while := c.NewLabel()
321+
c.Expr(node.Test)
322+
c.Jump(vm.POP_JUMP_IF_FALSE, endwhile)
323+
for _, stmt := range node.Body {
324+
c.Stmt(stmt)
325+
}
326+
c.Jump(vm.JUMP_ABSOLUTE, while)
327+
c.Label(endwhile)
328+
c.Op(vm.POP_BLOCK)
329+
for _, stmt := range node.Orelse {
330+
c.Stmt(stmt)
331+
}
332+
c.Label(endpopblock)
318333
case *ast.If:
319334
// Test Expr
320335
// Body []Stmt
321336
// Orelse []Stmt
322-
panic("FIXME compile: If not implemented")
337+
orelse := new(Label)
338+
endif := new(Label)
339+
c.Expr(node.Test)
340+
c.Jump(vm.POP_JUMP_IF_FALSE, orelse)
341+
for _, stmt := range node.Body {
342+
c.Stmt(stmt)
343+
}
344+
// FIXME this puts a JUMP_FORWARD in when not
345+
// necessary (when no Orelse statements) but it
346+
// matches python3.4
347+
c.Jump(vm.JUMP_FORWARD, endif)
348+
c.Label(orelse)
349+
for _, stmt := range node.Orelse {
350+
c.Stmt(stmt)
351+
}
352+
c.Label(endif)
323353
case *ast.With:
324354
// Items []*WithItem
325355
// Body []Stmt

compile/compile_data_test.go

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,7 @@ var compileTestData = []struct {
11491149
Name: "<module>",
11501150
Firstlineno: 1,
11511151
Lnotab: "",
1152-
}, " 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7fd0bed8ee40, file \"<string>\", line 1>)\n 3 LOAD_CONST 1 ('<lambda>')\n 6 MAKE_FUNCTION 0\n 9 RETURN_VALUE\n"},
1152+
}, " 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7f643912ce40, file \"<string>\", line 1>)\n 3 LOAD_CONST 1 ('<lambda>')\n 6 MAKE_FUNCTION 0\n 9 RETURN_VALUE\n"},
11531153
{"pass", "exec", &py.Code{
11541154
Argcount: 0,
11551155
Kwonlyargcount: 0,
@@ -1575,4 +1575,72 @@ var compileTestData = []struct {
15751575
Firstlineno: 1,
15761576
Lnotab: "",
15771577
}, " 1 0 LOAD_NAME 0 (a)\n 3 LOAD_NAME 1 (b)\n 6 RAISE_VARARGS 2\n 9 LOAD_CONST 0 (None)\n 12 RETURN_VALUE\n"},
1578+
{"if a: b = c", "exec", &py.Code{
1579+
Argcount: 0,
1580+
Kwonlyargcount: 0,
1581+
Nlocals: 0,
1582+
Stacksize: 1,
1583+
Flags: 64,
1584+
Code: "\x65\x00\x00\x72\x0f\x00\x65\x01\x00\x5a\x02\x00\x6e\x00\x00\x64\x00\x00\x53",
1585+
Consts: []py.Object{py.None},
1586+
Names: []string{"a", "c", "b"},
1587+
Varnames: []string{},
1588+
Freevars: []string{},
1589+
Cellvars: []string{},
1590+
Filename: "<string>",
1591+
Name: "<module>",
1592+
Firstlineno: 1,
1593+
Lnotab: "\x06\x00",
1594+
}, " 1 0 LOAD_NAME 0 (a)\n 3 POP_JUMP_IF_FALSE 15\n 6 LOAD_NAME 1 (c)\n 9 STORE_NAME 2 (b)\n 12 JUMP_FORWARD 0 (to 15)\n >> 15 LOAD_CONST 0 (None)\n 18 RETURN_VALUE\n"},
1595+
{"if a:\n b = c\nelse:\n c = d\n", "exec", &py.Code{
1596+
Argcount: 0,
1597+
Kwonlyargcount: 0,
1598+
Nlocals: 0,
1599+
Stacksize: 1,
1600+
Flags: 64,
1601+
Code: "\x65\x00\x00\x72\x0f\x00\x65\x01\x00\x5a\x02\x00\x6e\x06\x00\x65\x03\x00\x5a\x01\x00\x64\x00\x00\x53",
1602+
Consts: []py.Object{py.None},
1603+
Names: []string{"a", "c", "b", "d"},
1604+
Varnames: []string{},
1605+
Freevars: []string{},
1606+
Cellvars: []string{},
1607+
Filename: "<string>",
1608+
Name: "<module>",
1609+
Firstlineno: 1,
1610+
Lnotab: "\x06\x01\x09\x02",
1611+
}, " 1 0 LOAD_NAME 0 (a)\n 3 POP_JUMP_IF_FALSE 15\n\n 2 6 LOAD_NAME 1 (c)\n 9 STORE_NAME 2 (b)\n 12 JUMP_FORWARD 6 (to 21)\n\n 4 >> 15 LOAD_NAME 3 (d)\n 18 STORE_NAME 1 (c)\n >> 21 LOAD_CONST 0 (None)\n 24 RETURN_VALUE\n"},
1612+
{"while a:\n b = c", "exec", &py.Code{
1613+
Argcount: 0,
1614+
Kwonlyargcount: 0,
1615+
Nlocals: 0,
1616+
Stacksize: 1,
1617+
Flags: 64,
1618+
Code: "\x78\x10\x00\x65\x00\x00\x72\x12\x00\x65\x01\x00\x5a\x02\x00\x71\x03\x00\x57\x64\x00\x00\x53",
1619+
Consts: []py.Object{py.None},
1620+
Names: []string{"a", "c", "b"},
1621+
Varnames: []string{},
1622+
Freevars: []string{},
1623+
Cellvars: []string{},
1624+
Filename: "<string>",
1625+
Name: "<module>",
1626+
Firstlineno: 1,
1627+
Lnotab: "\x09\x01",
1628+
}, " 1 0 SETUP_LOOP 16 (to 19)\n >> 3 LOAD_NAME 0 (a)\n 6 POP_JUMP_IF_FALSE 18\n\n 2 9 LOAD_NAME 1 (c)\n 12 STORE_NAME 2 (b)\n 15 JUMP_ABSOLUTE 3\n >> 18 POP_BLOCK\n >> 19 LOAD_CONST 0 (None)\n 22 RETURN_VALUE\n"},
1629+
{"while a:\n b = c\nelse:\n b = d\n", "exec", &py.Code{
1630+
Argcount: 0,
1631+
Kwonlyargcount: 0,
1632+
Nlocals: 0,
1633+
Stacksize: 1,
1634+
Flags: 64,
1635+
Code: "\x78\x16\x00\x65\x00\x00\x72\x12\x00\x65\x01\x00\x5a\x02\x00\x71\x03\x00\x57\x65\x03\x00\x5a\x02\x00\x64\x00\x00\x53",
1636+
Consts: []py.Object{py.None},
1637+
Names: []string{"a", "c", "b", "d"},
1638+
Varnames: []string{},
1639+
Freevars: []string{},
1640+
Cellvars: []string{},
1641+
Filename: "<string>",
1642+
Name: "<module>",
1643+
Firstlineno: 1,
1644+
Lnotab: "\x09\x01\x0a\x02",
1645+
}, " 1 0 SETUP_LOOP 22 (to 25)\n >> 3 LOAD_NAME 0 (a)\n 6 POP_JUMP_IF_FALSE 18\n\n 2 9 LOAD_NAME 1 (c)\n 12 STORE_NAME 2 (b)\n 15 JUMP_ABSOLUTE 3\n >> 18 POP_BLOCK\n\n 4 19 LOAD_NAME 3 (d)\n 22 STORE_NAME 2 (b)\n >> 25 LOAD_CONST 0 (None)\n 28 RETURN_VALUE\n"},
15781646
}

compile/make_compile_test.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,13 @@
130130
('''raise''', "exec"),
131131
('''raise a''', "exec"),
132132
('''raise a from b''', "exec"),
133-
133+
# if
134+
('''if a: b = c''', "exec"),
135+
('''if a:\n b = c\nelse:\n c = d\n''', "exec"),
136+
# while
137+
('''while a:\n b = c''', "exec"),
138+
('''while a:\n b = c\nelse:\n b = d\n''', "exec"),
139+
# FIXME break
134140

135141
]
136142

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy