Skip to content

Commit ff5d114

Browse files
committed
compiler: implement call
1 parent 669e0e4 commit ff5d114

File tree

4 files changed

+240
-11
lines changed

4 files changed

+240
-11
lines changed

compile/compile.go

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func CompileAst(Ast ast.Ast, filename string, flags int, dont_inherit bool) *py.
135135
// add a return
136136
if !valueOnStack {
137137
// return None if there is nothing on the stack
138-
c.OpArg(vm.LOAD_CONST, c.Const(py.None))
138+
c.LoadConst(py.None)
139139
}
140140
c.Op(vm.RETURN_VALUE)
141141
}
@@ -192,6 +192,11 @@ func (c *compiler) Const(obj py.Object) uint32 {
192192
return uint32(len(c.Code.Consts) - 1)
193193
}
194194

195+
// Loads a constant
196+
func (c *compiler) LoadConst(obj py.Object) {
197+
c.OpArg(vm.LOAD_CONST, c.Const(obj))
198+
}
199+
195200
// Compiles a python name
196201
//
197202
// Returns the index into the Name tuple
@@ -562,8 +567,8 @@ func (c *compiler) Expr(expr ast.Expr) {
562567
// newC := Compiler
563568
code := CompileAst(node.Body, c.Code.Filename, int(c.Code.Flags)|py.CO_OPTIMIZED|py.CO_NEWLOCALS, false) // FIXME pass on compile args
564569
code.Argcount = int32(len(node.Args.Args))
565-
c.OpArg(vm.LOAD_CONST, c.Const(code))
566-
c.OpArg(vm.LOAD_CONST, c.Const(py.String("<lambda>")))
570+
c.LoadConst(code)
571+
c.LoadConst(py.String("<lambda>"))
567572
// FIXME node.Args
568573
c.OpArg(vm.MAKE_FUNCTION, 0)
569574
case *ast.IfExp:
@@ -685,19 +690,43 @@ func (c *compiler) Expr(expr ast.Expr) {
685690
// Keywords []*Keyword
686691
// Starargs Expr
687692
// Kwargs Expr
688-
panic("FIXME compile: Call not implemented")
693+
c.Expr(node.Func)
694+
args := len(node.Args)
695+
for i := range node.Args {
696+
c.Expr(node.Args[i])
697+
}
698+
kwargs := len(node.Keywords)
699+
for i := range node.Keywords {
700+
kw := node.Keywords[i]
701+
c.LoadConst(py.String(kw.Arg))
702+
c.Expr(kw.Value)
703+
}
704+
op := byte(vm.CALL_FUNCTION)
705+
if node.Starargs != nil {
706+
c.Expr(node.Starargs)
707+
if node.Kwargs != nil {
708+
c.Expr(node.Kwargs)
709+
op = vm.CALL_FUNCTION_VAR_KW
710+
} else {
711+
op = vm.CALL_FUNCTION_VAR
712+
}
713+
} else if node.Kwargs != nil {
714+
c.Expr(node.Kwargs)
715+
op = vm.CALL_FUNCTION_KW
716+
}
717+
c.OpArg(op, uint32(args+kwargs<<8))
689718
case *ast.Num:
690719
// N Object
691-
c.OpArg(vm.LOAD_CONST, c.Const(node.N))
720+
c.LoadConst(node.N)
692721
case *ast.Str:
693722
// S py.String
694-
c.OpArg(vm.LOAD_CONST, c.Const(node.S))
723+
c.LoadConst(node.S)
695724
case *ast.Bytes:
696725
// S py.Bytes
697-
c.OpArg(vm.LOAD_CONST, c.Const(node.S))
726+
c.LoadConst(node.S)
698727
case *ast.NameConstant:
699728
// Value Singleton
700-
c.OpArg(vm.LOAD_CONST, c.Const(node.Value))
729+
c.LoadConst(node.Value)
701730
case *ast.Ellipsis:
702731
panic("FIXME compile: Ellipsis not implemented")
703732
case *ast.Attribute:

compile/compile_data_test.go

Lines changed: 188 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1151,7 +1151,7 @@ var compileTestData = []struct {
11511151
Name: "<module>",
11521152
Firstlineno: 1,
11531153
Lnotab: "",
1154-
}, " 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7f37b1535db0, file \"<string>\", line 1>)\n 3 LOAD_CONST 1 ('<lambda>')\n 6 MAKE_FUNCTION 0\n 9 RETURN_VALUE\n", nil, ""},
1154+
}, " 1 0 LOAD_CONST 0 (<code object <lambda> at 0x7f94f9f31db0, file \"<string>\", line 1>)\n 3 LOAD_CONST 1 ('<lambda>')\n 6 MAKE_FUNCTION 0\n 9 RETURN_VALUE\n", nil, ""},
11551155
{"pass", "exec", &py.Code{
11561156
Argcount: 0,
11571157
Kwonlyargcount: 0,
@@ -1732,4 +1732,191 @@ var compileTestData = []struct {
17321732
Firstlineno: 1,
17331733
Lnotab: "\x0d\x01\x06\x01\x06\x01\x0a\x01",
17341734
}, " 1 0 SETUP_LOOP 38 (to 41)\n 3 LOAD_NAME 0 (b)\n 6 GET_ITER\n >> 7 FOR_ITER 24 (to 34)\n 10 STORE_NAME 1 (a)\n\n 2 13 LOAD_NAME 1 (a)\n 16 POP_JUMP_IF_FALSE 25\n\n 3 19 JUMP_ABSOLUTE 7\n 22 JUMP_FORWARD 0 (to 25)\n\n 4 >> 25 LOAD_NAME 2 (e)\n 28 STORE_NAME 3 (c)\n 31 JUMP_ABSOLUTE 7\n >> 34 POP_BLOCK\n\n 5 35 LOAD_NAME 4 (d)\n 38 STORE_NAME 3 (c)\n >> 41 LOAD_CONST 0 (None)\n 44 RETURN_VALUE\n", nil, ""},
1735+
{"f()", "eval", &py.Code{
1736+
Argcount: 0,
1737+
Kwonlyargcount: 0,
1738+
Nlocals: 0,
1739+
Stacksize: 1,
1740+
Flags: 64,
1741+
Code: "\x65\x00\x00\x83\x00\x00\x53",
1742+
Consts: []py.Object{},
1743+
Names: []string{"f"},
1744+
Varnames: []string{},
1745+
Freevars: []string{},
1746+
Cellvars: []string{},
1747+
Filename: "<string>",
1748+
Name: "<module>",
1749+
Firstlineno: 1,
1750+
Lnotab: "",
1751+
}, " 1 0 LOAD_NAME 0 (f)\n 3 CALL_FUNCTION 0 (0 positional, 0 keyword pair)\n 6 RETURN_VALUE\n", nil, ""},
1752+
{"f(a)", "eval", &py.Code{
1753+
Argcount: 0,
1754+
Kwonlyargcount: 0,
1755+
Nlocals: 0,
1756+
Stacksize: 2,
1757+
Flags: 64,
1758+
Code: "\x65\x00\x00\x65\x01\x00\x83\x01\x00\x53",
1759+
Consts: []py.Object{},
1760+
Names: []string{"f", "a"},
1761+
Varnames: []string{},
1762+
Freevars: []string{},
1763+
Cellvars: []string{},
1764+
Filename: "<string>",
1765+
Name: "<module>",
1766+
Firstlineno: 1,
1767+
Lnotab: "",
1768+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (a)\n 6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)\n 9 RETURN_VALUE\n", nil, ""},
1769+
{"f(a,b,c)", "eval", &py.Code{
1770+
Argcount: 0,
1771+
Kwonlyargcount: 0,
1772+
Nlocals: 0,
1773+
Stacksize: 4,
1774+
Flags: 64,
1775+
Code: "\x65\x00\x00\x65\x01\x00\x65\x02\x00\x65\x03\x00\x83\x03\x00\x53",
1776+
Consts: []py.Object{},
1777+
Names: []string{"f", "a", "b", "c"},
1778+
Varnames: []string{},
1779+
Freevars: []string{},
1780+
Cellvars: []string{},
1781+
Filename: "<string>",
1782+
Name: "<module>",
1783+
Firstlineno: 1,
1784+
Lnotab: "",
1785+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (a)\n 6 LOAD_NAME 2 (b)\n 9 LOAD_NAME 3 (c)\n 12 CALL_FUNCTION 3 (3 positional, 0 keyword pair)\n 15 RETURN_VALUE\n", nil, ""},
1786+
{"f(A=a)", "eval", &py.Code{
1787+
Argcount: 0,
1788+
Kwonlyargcount: 0,
1789+
Nlocals: 0,
1790+
Stacksize: 3,
1791+
Flags: 64,
1792+
Code: "\x65\x00\x00\x64\x00\x00\x65\x01\x00\x83\x00\x01\x53",
1793+
Consts: []py.Object{py.String("A")},
1794+
Names: []string{"f", "a"},
1795+
Varnames: []string{},
1796+
Freevars: []string{},
1797+
Cellvars: []string{},
1798+
Filename: "<string>",
1799+
Name: "<module>",
1800+
Firstlineno: 1,
1801+
Lnotab: "",
1802+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_CONST 0 ('A')\n 6 LOAD_NAME 1 (a)\n 9 CALL_FUNCTION 256 (0 positional, 1 keyword pair)\n 12 RETURN_VALUE\n", nil, ""},
1803+
{"f(a, b, C=d, D=d)", "eval", &py.Code{
1804+
Argcount: 0,
1805+
Kwonlyargcount: 0,
1806+
Nlocals: 0,
1807+
Stacksize: 7,
1808+
Flags: 64,
1809+
Code: "\x65\x00\x00\x65\x01\x00\x65\x02\x00\x64\x00\x00\x65\x03\x00\x64\x01\x00\x65\x03\x00\x83\x02\x02\x53",
1810+
Consts: []py.Object{py.String("C"), py.String("D")},
1811+
Names: []string{"f", "a", "b", "d"},
1812+
Varnames: []string{},
1813+
Freevars: []string{},
1814+
Cellvars: []string{},
1815+
Filename: "<string>",
1816+
Name: "<module>",
1817+
Firstlineno: 1,
1818+
Lnotab: "",
1819+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (a)\n 6 LOAD_NAME 2 (b)\n 9 LOAD_CONST 0 ('C')\n 12 LOAD_NAME 3 (d)\n 15 LOAD_CONST 1 ('D')\n 18 LOAD_NAME 3 (d)\n 21 CALL_FUNCTION 514 (2 positional, 2 keyword pair)\n 24 RETURN_VALUE\n", nil, ""},
1820+
{"f(*args)", "eval", &py.Code{
1821+
Argcount: 0,
1822+
Kwonlyargcount: 0,
1823+
Nlocals: 0,
1824+
Stacksize: 2,
1825+
Flags: 64,
1826+
Code: "\x65\x00\x00\x65\x01\x00\x8c\x00\x00\x53",
1827+
Consts: []py.Object{},
1828+
Names: []string{"f", "args"},
1829+
Varnames: []string{},
1830+
Freevars: []string{},
1831+
Cellvars: []string{},
1832+
Filename: "<string>",
1833+
Name: "<module>",
1834+
Firstlineno: 1,
1835+
Lnotab: "",
1836+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (args)\n 6 CALL_FUNCTION_VAR 0 (0 positional, 0 keyword pair)\n 9 RETURN_VALUE\n", nil, ""},
1837+
{"f(*args, **kwargs)", "eval", &py.Code{
1838+
Argcount: 0,
1839+
Kwonlyargcount: 0,
1840+
Nlocals: 0,
1841+
Stacksize: 3,
1842+
Flags: 64,
1843+
Code: "\x65\x00\x00\x65\x01\x00\x65\x02\x00\x8e\x00\x00\x53",
1844+
Consts: []py.Object{},
1845+
Names: []string{"f", "args", "kwargs"},
1846+
Varnames: []string{},
1847+
Freevars: []string{},
1848+
Cellvars: []string{},
1849+
Filename: "<string>",
1850+
Name: "<module>",
1851+
Firstlineno: 1,
1852+
Lnotab: "",
1853+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (args)\n 6 LOAD_NAME 2 (kwargs)\n 9 CALL_FUNCTION_VAR_KW 0 (0 positional, 0 keyword pair)\n 12 RETURN_VALUE\n", nil, ""},
1854+
{"f(**kwargs)", "eval", &py.Code{
1855+
Argcount: 0,
1856+
Kwonlyargcount: 0,
1857+
Nlocals: 0,
1858+
Stacksize: 2,
1859+
Flags: 64,
1860+
Code: "\x65\x00\x00\x65\x01\x00\x8d\x00\x00\x53",
1861+
Consts: []py.Object{},
1862+
Names: []string{"f", "kwargs"},
1863+
Varnames: []string{},
1864+
Freevars: []string{},
1865+
Cellvars: []string{},
1866+
Filename: "<string>",
1867+
Name: "<module>",
1868+
Firstlineno: 1,
1869+
Lnotab: "",
1870+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (kwargs)\n 6 CALL_FUNCTION_KW 0 (0 positional, 0 keyword pair)\n 9 RETURN_VALUE\n", nil, ""},
1871+
{"f(a, b, *args)", "eval", &py.Code{
1872+
Argcount: 0,
1873+
Kwonlyargcount: 0,
1874+
Nlocals: 0,
1875+
Stacksize: 4,
1876+
Flags: 64,
1877+
Code: "\x65\x00\x00\x65\x01\x00\x65\x02\x00\x65\x03\x00\x8c\x02\x00\x53",
1878+
Consts: []py.Object{},
1879+
Names: []string{"f", "a", "b", "args"},
1880+
Varnames: []string{},
1881+
Freevars: []string{},
1882+
Cellvars: []string{},
1883+
Filename: "<string>",
1884+
Name: "<module>",
1885+
Firstlineno: 1,
1886+
Lnotab: "",
1887+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (a)\n 6 LOAD_NAME 2 (b)\n 9 LOAD_NAME 3 (args)\n 12 CALL_FUNCTION_VAR 2 (2 positional, 0 keyword pair)\n 15 RETURN_VALUE\n", nil, ""},
1888+
{"f(a, b, *args, d=e, **kwargs)", "eval", &py.Code{
1889+
Argcount: 0,
1890+
Kwonlyargcount: 0,
1891+
Nlocals: 0,
1892+
Stacksize: 7,
1893+
Flags: 64,
1894+
Code: "\x65\x00\x00\x65\x01\x00\x65\x02\x00\x64\x00\x00\x65\x03\x00\x65\x04\x00\x65\x05\x00\x8e\x02\x01\x53",
1895+
Consts: []py.Object{py.String("d")},
1896+
Names: []string{"f", "a", "b", "e", "args", "kwargs"},
1897+
Varnames: []string{},
1898+
Freevars: []string{},
1899+
Cellvars: []string{},
1900+
Filename: "<string>",
1901+
Name: "<module>",
1902+
Firstlineno: 1,
1903+
Lnotab: "",
1904+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (a)\n 6 LOAD_NAME 2 (b)\n 9 LOAD_CONST 0 ('d')\n 12 LOAD_NAME 3 (e)\n 15 LOAD_NAME 4 (args)\n 18 LOAD_NAME 5 (kwargs)\n 21 CALL_FUNCTION_VAR_KW 258 (2 positional, 1 keyword pair)\n 24 RETURN_VALUE\n", nil, ""},
1905+
{"f(a, d=e, **kwargs)", "eval", &py.Code{
1906+
Argcount: 0,
1907+
Kwonlyargcount: 0,
1908+
Nlocals: 0,
1909+
Stacksize: 5,
1910+
Flags: 64,
1911+
Code: "\x65\x00\x00\x65\x01\x00\x64\x00\x00\x65\x02\x00\x65\x03\x00\x8d\x01\x01\x53",
1912+
Consts: []py.Object{py.String("d")},
1913+
Names: []string{"f", "a", "e", "kwargs"},
1914+
Varnames: []string{},
1915+
Freevars: []string{},
1916+
Cellvars: []string{},
1917+
Filename: "<string>",
1918+
Name: "<module>",
1919+
Firstlineno: 1,
1920+
Lnotab: "",
1921+
}, " 1 0 LOAD_NAME 0 (f)\n 3 LOAD_NAME 1 (a)\n 6 LOAD_CONST 0 ('d')\n 9 LOAD_NAME 2 (e)\n 12 LOAD_NAME 3 (kwargs)\n 15 CALL_FUNCTION_KW 257 (1 positional, 1 keyword pair)\n 18 RETURN_VALUE\n", nil, ""},
17351922
}

compile/compile_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,10 @@ func TestCompile(t *testing.T) {
122122
code, ok := codeObj.(*py.Code)
123123
if !ok {
124124
t.Errorf("%s: Expecting *py.Code but got %T", test.in, codeObj)
125+
} else {
126+
//t.Logf("Testing %q", test.in)
127+
EqCode(t, test.in, test.out, code)
125128
}
126-
//t.Logf("Testing %q", test.in)
127-
EqCode(t, test.in, test.out, code)
128129
}
129130
}
130131
}

compile/make_compile_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,18 @@
144144
('''for a in b: pass''', "exec"),
145145
('''for a in b:\n if a:\n break\n c = e\nelse: c = d\n''', "exec"),
146146
('''for a in b:\n if a:\n continue\n c = e\nelse: c = d\n''', "exec"),
147+
# call
148+
('''f()''', "eval"),
149+
('''f(a)''', "eval"),
150+
('''f(a,b,c)''', "eval"),
151+
('''f(A=a)''', "eval"),
152+
('''f(a, b, C=d, D=d)''', "eval"),
153+
('''f(*args)''', "eval"),
154+
('''f(*args, **kwargs)''', "eval"),
155+
('''f(**kwargs)''', "eval"),
156+
('''f(a, b, *args)''', "eval"),
157+
('''f(a, b, *args, d=e, **kwargs)''', "eval"),
158+
('''f(a, d=e, **kwargs)''', "eval"),
147159

148160
]
149161

0 commit comments

Comments
 (0)