Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a35ffcc27 | ||
|
|
5eae8f9af6 | ||
|
|
25381e20d2 | ||
|
|
fc35ff5cd1 | ||
|
|
b10d00b426 | ||
|
|
c634dc25b4 | ||
|
|
2fb4561bf8 | ||
|
|
f167c6dcca | ||
|
|
555ace9e2e | ||
|
|
d07ffb36ad | ||
|
|
9e2b8b77c9 | ||
|
|
29e4af4fb2 | ||
|
|
91513a12b4 | ||
|
|
ee3f55dd41 | ||
|
|
c2e5a78076 | ||
|
|
da3ac3e93d | ||
|
|
278ebbc9bd | ||
|
|
546f93147e | ||
|
|
3e7bfbb45c | ||
|
|
c2cf0443ef | ||
|
|
59d68c6438 | ||
|
|
e0ee199bf1 | ||
|
|
c1bf895674 | ||
|
|
ea4d92e671 | ||
|
|
e3f56105d4 | ||
|
|
c447a87605 | ||
|
|
584e5b1f01 | ||
|
|
207dc4c112 | ||
|
|
6a3581f7a3 | ||
|
|
11e74975b3 | ||
|
|
75ef9ec524 | ||
|
|
9b742e777b | ||
|
|
5d93565e16 | ||
|
|
cebfe5c95b | ||
|
|
7881f3a53b | ||
|
|
56269bd52b | ||
|
|
68c43a2cc9 | ||
|
|
120b507c75 | ||
|
|
44fe7e8dc4 | ||
|
|
75d679f141 | ||
|
|
e9570f2400 | ||
|
|
5b8567310c | ||
|
|
f882221db3 | ||
|
|
8c4d7bd641 | ||
|
|
6a78695fde | ||
|
|
73ad16dedd | ||
|
|
dd98112c5a | ||
|
|
47521d3579 | ||
|
|
0c31300578 | ||
|
|
6340ff7da0 | ||
|
|
b66cb49d80 | ||
|
|
c884184220 | ||
|
|
091fee61e0 | ||
|
|
172a268e77 | ||
|
|
924715fe34 | ||
|
|
35a73b4cde | ||
|
|
238f9593f9 | ||
|
|
9e8b5703dc | ||
|
|
d8bd8be57e | ||
|
|
a4d4e8b3a9 | ||
|
|
703dd17e33 | ||
|
|
bc654a462e | ||
|
|
11535825c0 | ||
|
|
196df40c99 | ||
|
|
7aee6c3a15 | ||
|
|
372b566d23 | ||
|
|
9550354442 | ||
|
|
95c3ddfc39 | ||
|
|
bf4f2b6fa0 | ||
|
|
d3f75a92ad | ||
|
|
369495c8d3 | ||
|
|
dd52f71069 | ||
|
|
af8e2bc19d | ||
|
|
947e5591ea | ||
|
|
521376e8e8 | ||
|
|
55c0adb23d | ||
|
|
b20ad7047f | ||
|
|
fa3149c660 | ||
|
|
1463ed4835 | ||
|
|
b959de18d5 | ||
|
|
edac3f73c2 | ||
|
|
388b19eed5 | ||
|
|
a337136389 | ||
|
|
31d5a8ac10 | ||
|
|
46527f56ce | ||
|
|
a575c17eca | ||
|
|
a6ea3b1e6f | ||
|
|
4d2ad842a4 | ||
|
|
ce0f5f3797 | ||
|
|
9e0d22ac90 | ||
|
|
ddc2c56115 | ||
|
|
acfbe6902a | ||
|
|
f7dfab481b | ||
|
|
23692430d5 | ||
|
|
03fe594339 | ||
|
|
45babef689 | ||
|
|
9ac0450255 | ||
|
|
b1d55f657d | ||
|
|
aac5e7b3cd | ||
|
|
791634c377 | ||
|
|
090149eab6 | ||
|
|
acecbf587d | ||
|
|
4ef46971d0 | ||
|
|
2e3cc49782 | ||
|
|
8a0189b079 | ||
|
|
0edd7f6df0 | ||
|
|
0b058bc2e8 | ||
|
|
f9ef9cab81 | ||
|
|
fbb2150d88 | ||
|
|
0912f1f509 | ||
|
|
64c13fa9ae | ||
|
|
2a5f9d9641 | ||
|
|
6c32fe87e6 | ||
|
|
09e9cc99d3 | ||
|
|
94a7ee024a | ||
|
|
a2d7a8c978 | ||
|
|
15499ddc14 | ||
|
|
97cb312386 | ||
|
|
92827a1f04 | ||
|
|
00222c7808 | ||
|
|
427d87be68 | ||
|
|
2560a333b6 | ||
|
|
c6b76db789 | ||
|
|
1414853fce | ||
|
|
cbe384a3be | ||
|
|
cca46573ea | ||
|
|
2589c23998 | ||
|
|
29830865d9 | ||
|
|
35dbc7b0b5 | ||
|
|
cd266213ce | ||
|
|
875eadeb19 | ||
|
|
67896c63a7 | ||
|
|
c643f734e9 | ||
|
|
31d91f5e87 | ||
|
|
2a92f1bc55 | ||
|
|
d9db5528f5 | ||
|
|
22a4ffb78b | ||
|
|
1fb37c37fe | ||
|
|
aae663e5e5 | ||
|
|
e985eda857 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,11 +13,13 @@ llgo_autogen.ll
|
|||||||
stories*.bin
|
stories*.bin
|
||||||
.DS_Store
|
.DS_Store
|
||||||
err.log
|
err.log
|
||||||
|
numpy.txt
|
||||||
|
|
||||||
_go/
|
_go/
|
||||||
_runtime/
|
_runtime/
|
||||||
_tinygo/
|
_tinygo/
|
||||||
build.dir/
|
build.dir/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
|||||||
[submodule "x/llama2/llama2.c"]
|
[submodule "x/llama2/llama2.c"]
|
||||||
path = x/llama2/llama2.c
|
path = x/llama2/llama2.c
|
||||||
url = https://github.com/karpathy/llama2.c.git
|
url = https://github.com/karpathy/llama2.c.git
|
||||||
[submodule "x/sqlite/sqlite"]
|
|
||||||
path = x/sqlite/sqlite
|
|
||||||
url = https://github.com/sqlite/sqlite.git
|
|
||||||
|
|||||||
199
README.md
199
README.md
@@ -8,7 +8,185 @@ llgo - A Go compiler based on LLVM
|
|||||||
[](https://pkg.go.dev/github.com/goplus/llgo)
|
[](https://pkg.go.dev/github.com/goplus/llgo)
|
||||||
[](https://github.com/goplus/gop)
|
[](https://github.com/goplus/gop)
|
||||||
|
|
||||||
This is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem. It's a subproject of [the Go+ project](https://github.com/goplus/gop).
|
LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop).
|
||||||
|
|
||||||
|
|
||||||
|
## C standard libary support
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/goplus/llgo/c"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c.Printf(c.Str("Hello world\n"))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a simple example of calling the C `printf` function to print `Hello world`. Here, `c.Str` is not a function for converting a Go string to a C string, but a built-in instruction supported by `llgo` for generating a C string constant.
|
||||||
|
|
||||||
|
The `_demo` directory contains some C standard libary related demos (it start with `_` to prevent the `go` command from compiling it):
|
||||||
|
|
||||||
|
* [hello](_demo/hello/hello.go): call C `printf` to print `Hello world`
|
||||||
|
* [concat](_demo/concat/concat.go): call C `fprintf` with `stderr`
|
||||||
|
* [qsort](_demo/qsort/qsort.go): call C function with a callback (eg. `qsort`)
|
||||||
|
|
||||||
|
To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export LLGOROOT=`pwd`
|
||||||
|
cd <demo-directory> # eg. cd _demo/genints
|
||||||
|
llgo run .
|
||||||
|
```
|
||||||
|
|
||||||
|
See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for more detials.
|
||||||
|
|
||||||
|
|
||||||
|
## Python support
|
||||||
|
|
||||||
|
You can import a Python library in LLGo!
|
||||||
|
|
||||||
|
And you can import any Python library into `llgo` through a program called `llpyg`. The currently imported libraries include:
|
||||||
|
|
||||||
|
* [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
|
||||||
|
* [os](https://pkg.go.dev/github.com/goplus/llgo/py/os)
|
||||||
|
* [math](https://pkg.go.dev/github.com/goplus/llgo/py/math)
|
||||||
|
* [json](https://pkg.go.dev/github.com/goplus/llgo/py/json)
|
||||||
|
* [inspect](https://pkg.go.dev/github.com/goplus/llgo/py/inspect)
|
||||||
|
* [statistics](https://pkg.go.dev/github.com/goplus/llgo/py/statistics)
|
||||||
|
* [numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy)
|
||||||
|
|
||||||
|
Here is an example using the Python `math` library:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := math.Sqrt(py.Float(2))
|
||||||
|
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python’s `math.sqrt` to get `x`. Then use `x.Float64()` to convert x to Go's `float64` type, and print the value through the C `printf` function.
|
||||||
|
|
||||||
|
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/numpy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a := py.List(
|
||||||
|
py.List(1.0, 2.0, 3.0),
|
||||||
|
py.List(4.0, 5.0, 6.0),
|
||||||
|
py.List(7.0, 8.0, 9.0),
|
||||||
|
)
|
||||||
|
b := py.List(
|
||||||
|
py.List(9.0, 8.0, 7.0),
|
||||||
|
py.List(6.0, 5.0, 4.0),
|
||||||
|
py.List(3.0, 2.0, 1.0),
|
||||||
|
)
|
||||||
|
x := numpy.Add(a, b)
|
||||||
|
c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here we define two 3x3 matrices a and b, add them to get x, and then print the result.
|
||||||
|
|
||||||
|
The `_pydemo` directory contains some python related demos:
|
||||||
|
|
||||||
|
* [callpy](_pydemo/callpy/callpy.go): call Python standard library function `math.sqrt`
|
||||||
|
* [pi](_pydemo/pi/pi.go): print python constants `math.pi`
|
||||||
|
* [statistics](_pydemo/statistics/statistics.go): define a python list and call `statistics.mean` to get the mean
|
||||||
|
* [matrix](_pydemo/matrix/matrix.go): a basic `numpy` demo
|
||||||
|
|
||||||
|
To run these demos, you need to set the `LLGO_LIB_PYTHON` environment variable first.
|
||||||
|
|
||||||
|
If Python is in the search path for `clang` linking, then `LLGO_LIB_PYTHON` only needs to be set to the name of the Python library. For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export LLGO_LIB_PYTHON=python3.12
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also specify the path to tell `llgo` where the Python library is located:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export LLGO_LIB_PYTHON=/foo/bar/python3.12
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python library location under macOS. So we should set it like this:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the file name must be written in a platform-independent format, using `python3.12` instead of `libpython3.12.dylib`.
|
||||||
|
|
||||||
|
Then you can run the demos:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export LLGOROOT=`pwd`
|
||||||
|
cd <demo-directory> # eg. cd _pydemo/callpy
|
||||||
|
llgo run .
|
||||||
|
```
|
||||||
|
|
||||||
|
See [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py) for more detials.
|
||||||
|
|
||||||
|
|
||||||
|
## Other frequently used libraries
|
||||||
|
|
||||||
|
LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports.
|
||||||
|
|
||||||
|
The currently imported libraries include:
|
||||||
|
|
||||||
|
* [llama2.c](https://pkg.go.dev/github.com/goplus/llgo/x/llama2)
|
||||||
|
* [cjson](https://pkg.go.dev/github.com/goplus/llgo/x/cjson)
|
||||||
|
* [sqlite](https://pkg.go.dev/github.com/goplus/llgo/x/sqlite)
|
||||||
|
|
||||||
|
Here are some examples related to them:
|
||||||
|
|
||||||
|
* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
|
||||||
|
* [mkjson](x/cjson/_demo/mkjson/mkjson.go): create a json object and print it
|
||||||
|
* [sqlite](x/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo
|
||||||
|
|
||||||
|
|
||||||
|
## Go syntax support
|
||||||
|
|
||||||
|
The priority of `llgo` feature iteration is:
|
||||||
|
|
||||||
|
* Popular C/Python libraries
|
||||||
|
* Full Go syntax
|
||||||
|
* Go standard libraries
|
||||||
|
* Popular Go packages
|
||||||
|
|
||||||
|
Common Go syntax is already supported. Except for the following, which needs to be improved:
|
||||||
|
|
||||||
|
* interface (Limited support)
|
||||||
|
* map (Very limited support)
|
||||||
|
* panic (Limited support)
|
||||||
|
* recover (Not supported yet)
|
||||||
|
* defer (Not supported yet)
|
||||||
|
* gc (Not supported yet)
|
||||||
|
* chan (Not supported yet)
|
||||||
|
* goroutine (Not supported yet)
|
||||||
|
* generics (Not supported yet)
|
||||||
|
|
||||||
|
Here are some examples related to Go syntax:
|
||||||
|
|
||||||
|
* [concat](_demo/concat/concat.go): define a variadic function
|
||||||
|
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
||||||
|
|
||||||
|
|
||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
@@ -35,22 +213,3 @@ go install -v ./...
|
|||||||
### on Windows
|
### on Windows
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
|
||||||
## Demo
|
|
||||||
|
|
||||||
The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it):
|
|
||||||
|
|
||||||
* [hello](_demo/hello/hello.go): call C printf to print `Hello world`
|
|
||||||
* [concat](_demo/concat/concat.go): call C fprintf with stderr, and Go variadic function
|
|
||||||
* [qsort](_demo/qsort/qsort.go): call C function with a callback (eg. qsort)
|
|
||||||
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
|
||||||
* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example)
|
|
||||||
* [hellopy](https://github.com/goplus/cpython/blob/main/_demo/hellopy/hello.go): link Python to Go and say `Hello world`
|
|
||||||
|
|
||||||
### How to run demos
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cd <demo-directory> # eg. cd _demo/genints
|
|
||||||
llgo run .
|
|
||||||
```
|
|
||||||
|
|||||||
12
_pydemo/callpy/callpy.go
Normal file
12
_pydemo/callpy/callpy.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := math.Sqrt(py.Float(2))
|
||||||
|
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
|
||||||
|
}
|
||||||
22
_pydemo/matrix/matrix.go
Normal file
22
_pydemo/matrix/matrix.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/numpy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a := py.List(
|
||||||
|
py.List(1.0, 2.0, 3.0),
|
||||||
|
py.List(4.0, 5.0, 6.0),
|
||||||
|
py.List(7.0, 8.0, 9.0),
|
||||||
|
)
|
||||||
|
b := py.List(
|
||||||
|
py.List(9.0, 8.0, 7.0),
|
||||||
|
py.List(6.0, 5.0, 4.0),
|
||||||
|
py.List(3.0, 2.0, 1.0),
|
||||||
|
)
|
||||||
|
x := numpy.Add(a, b)
|
||||||
|
c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
|
||||||
|
}
|
||||||
10
_pydemo/pi/pi.go
Normal file
10
_pydemo/pi/pi.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c.Printf(c.Str("pi = %f\n"), math.Pi.Float64())
|
||||||
|
}
|
||||||
13
_pydemo/statistics/statistics.go
Normal file
13
_pydemo/statistics/statistics.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/statistics"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
list := py.List(1.0, 2.0, 3.0, 4.0, 4.0)
|
||||||
|
mean := statistics.Mean(list)
|
||||||
|
c.Printf(c.Str("mean(1, 2, 3, 4, 4) = %f\n"), mean.Float64())
|
||||||
|
}
|
||||||
6
c/c.go
6
c/c.go
@@ -28,6 +28,10 @@ type (
|
|||||||
Char = int8
|
Char = int8
|
||||||
Int = C.int
|
Int = C.int
|
||||||
Uint = C.uint
|
Uint = C.uint
|
||||||
|
Long = int32
|
||||||
|
Ulong = uint32
|
||||||
|
LongLong = int64
|
||||||
|
UlongLong = uint64
|
||||||
Float = float32
|
Float = float32
|
||||||
Pointer = unsafe.Pointer
|
Pointer = unsafe.Pointer
|
||||||
FilePtr = unsafe.Pointer
|
FilePtr = unsafe.Pointer
|
||||||
@@ -66,7 +70,7 @@ func Memset(s Pointer, c Int, n uintptr) Pointer
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
//go:linkname GoStringData github.com/goplus/llgo/internal/runtime.StringData
|
//go:linkname GoStringData llgo.stringData
|
||||||
func GoStringData(string) *Char
|
func GoStringData(string) *Char
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
60
chore/_xtool/pydump/pydump.go
Normal file
60
chore/_xtool/pydump/pydump.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/inspect"
|
||||||
|
"github.com/goplus/llgo/x/cjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if c.Argc < 2 {
|
||||||
|
c.Fprintf(c.Stderr, c.Str("Usage: pydump <pythonLibPath>\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pyLib := c.Index(c.Argv, 1)
|
||||||
|
|
||||||
|
py.Initialize()
|
||||||
|
|
||||||
|
root := cjson.Object()
|
||||||
|
root.SetItem(c.Str("name"), cjson.String(pyLib))
|
||||||
|
|
||||||
|
items := cjson.Array()
|
||||||
|
mod := py.ImportModule(pyLib)
|
||||||
|
keys := mod.ModuleGetDict().DictKeys()
|
||||||
|
for i, n := uintptr(0), keys.ListLen(); i < n; i++ {
|
||||||
|
key := keys.ListItem(i)
|
||||||
|
val := mod.GetAttr(key)
|
||||||
|
doc := val.GetAttrString(c.Str("__doc__"))
|
||||||
|
sym := cjson.Object()
|
||||||
|
sym.SetItem(c.Str("type"), cjson.String(val.Type().TypeName().CStr()))
|
||||||
|
sym.SetItem(c.Str("name"), cjson.String(key.CStr()))
|
||||||
|
if doc != nil {
|
||||||
|
sym.SetItem(c.Str("doc"), cjson.String(doc.CStr()))
|
||||||
|
}
|
||||||
|
if val.Callable() != 0 {
|
||||||
|
sig := inspect.Signature(val)
|
||||||
|
sym.SetItem(c.Str("sig"), cjson.String(sig.Str().CStr()))
|
||||||
|
}
|
||||||
|
items.AddItem(sym)
|
||||||
|
}
|
||||||
|
root.SetItem(c.Str("items"), items)
|
||||||
|
|
||||||
|
c.Printf(c.Str("%s\n"), root.CStr())
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/goplus/llgo/x/ar"
|
"github.com/goplus/llgo/xtool/ar"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/goplus/llgo/x/clang/parser"
|
"github.com/goplus/llgo/xtool/clang/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/goplus/llgo/x/clang/preprocessor"
|
"github.com/goplus/llgo/xtool/clang/preprocessor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ func main() {
|
|||||||
|
|
||||||
llgenDir(dir + "/cl/_testlibc")
|
llgenDir(dir + "/cl/_testlibc")
|
||||||
llgenDir(dir + "/cl/_testrt")
|
llgenDir(dir + "/cl/_testrt")
|
||||||
|
llgenDir(dir+"/cl/_testpy", "")
|
||||||
llgenDir(dir+"/cl/_testdata", "")
|
llgenDir(dir+"/cl/_testdata", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
200
chore/llpyg/llpyg.go
Normal file
200
chore/llpyg/llpyg.go
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
"go/token"
|
||||||
|
"go/types"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/goplus/gogen"
|
||||||
|
"github.com/goplus/llgo/ssa"
|
||||||
|
)
|
||||||
|
|
||||||
|
type symbol struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Doc string `json:"doc"`
|
||||||
|
Sig string `json:"sig"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type module struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Items []*symbol `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Fprintln(os.Stderr, "Usage: llpyg <pythonLibPath>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pyLib := os.Args[1]
|
||||||
|
|
||||||
|
var out bytes.Buffer
|
||||||
|
pydump := exec.Command("pydump", pyLib)
|
||||||
|
pydump.Stdout = &out
|
||||||
|
pydump.Run()
|
||||||
|
|
||||||
|
var mod module
|
||||||
|
json.Unmarshal(out.Bytes(), &mod)
|
||||||
|
|
||||||
|
modName := mod.Name
|
||||||
|
if modName == "" {
|
||||||
|
log.Printf("import module %s failed\n", pyLib)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
pkg := gogen.NewPackage("", modName, nil)
|
||||||
|
pkg.Import("unsafe").MarkForceUsed(pkg) // import _ "unsafe"
|
||||||
|
py := pkg.Import("github.com/goplus/llgo/py") // import "github.com/goplus/llgo/py"
|
||||||
|
|
||||||
|
f := func(cb *gogen.CodeBuilder) int {
|
||||||
|
cb.Val("py." + modName)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
defs := pkg.NewConstDefs(pkg.Types.Scope())
|
||||||
|
defs.New(f, 0, 0, nil, "LLGoPackage")
|
||||||
|
|
||||||
|
obj := py.Ref("Object").(*types.TypeName).Type().(*types.Named)
|
||||||
|
objPtr := types.NewPointer(obj)
|
||||||
|
ret := types.NewTuple(pkg.NewParam(0, "", objPtr))
|
||||||
|
|
||||||
|
ctx := &context{pkg, obj, objPtr, ret, py}
|
||||||
|
for _, sym := range mod.Items {
|
||||||
|
switch sym.Type {
|
||||||
|
case "builtin_function_or_method", "function", "ufunc", "method-wrapper":
|
||||||
|
ctx.genFunc(pkg, sym)
|
||||||
|
case "str", "float", "bool", "type", "dict", "tuple", "list", "object",
|
||||||
|
"module", "int", "set", "frozenset", "flags", "bool_": // skip
|
||||||
|
default:
|
||||||
|
t := sym.Type
|
||||||
|
if len(t) > 0 && (t[0] >= 'a' && t[0] <= 'z') && !strings.HasSuffix(t, "_info") {
|
||||||
|
log.Panicln("unsupport type:", sym.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pkg.WriteTo(os.Stdout)
|
||||||
|
}
|
||||||
|
|
||||||
|
type context struct {
|
||||||
|
pkg *gogen.Package
|
||||||
|
obj *types.Named
|
||||||
|
objPtr *types.Pointer
|
||||||
|
ret *types.Tuple
|
||||||
|
py gogen.PkgRef
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) {
|
||||||
|
name, symSig := sym.Name, sym.Sig
|
||||||
|
if len(name) == 0 || name[0] == '_' {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params, variadic, skip := ctx.genParams(pkg, symSig)
|
||||||
|
if skip {
|
||||||
|
// TODO(xsw): don't skip any func
|
||||||
|
log.Println("skip func:", name, symSig)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
name = genName(name, -1)
|
||||||
|
sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic)
|
||||||
|
fn := pkg.NewFuncDecl(token.NoPos, name, sig)
|
||||||
|
list := ctx.genDoc(sym.Doc)
|
||||||
|
list = append(list, emptyCommentLine)
|
||||||
|
list = append(list, ctx.genLinkname(name, sym))
|
||||||
|
fn.SetComments(pkg, &ast.CommentGroup{List: list})
|
||||||
|
// fn.BodyStart(pkg).End()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool, bool) {
|
||||||
|
if sig == "<NULL>" {
|
||||||
|
return nil, false, true
|
||||||
|
}
|
||||||
|
sig = strings.TrimSuffix(strings.TrimPrefix(sig, "("), ")")
|
||||||
|
if sig == "" { // empty params
|
||||||
|
return nil, false, false
|
||||||
|
}
|
||||||
|
parts := strings.Split(sig, ",")
|
||||||
|
n := len(parts)
|
||||||
|
objPtr := ctx.objPtr
|
||||||
|
list := make([]*types.Var, 0, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
part := strings.TrimSpace(parts[i])
|
||||||
|
if part == "/" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if part == "*" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(part, "*") {
|
||||||
|
if part[1] != '*' {
|
||||||
|
list = append(list, ssa.VArg())
|
||||||
|
return types.NewTuple(list...), true, false
|
||||||
|
}
|
||||||
|
return types.NewTuple(list...), false, false
|
||||||
|
}
|
||||||
|
pos := strings.IndexByte(part, '=')
|
||||||
|
if pos >= 0 {
|
||||||
|
if strings.HasPrefix(part[pos+1:], "<") { // skip complex default value
|
||||||
|
return nil, false, true
|
||||||
|
}
|
||||||
|
part = part[:pos]
|
||||||
|
}
|
||||||
|
list = append(list, pkg.NewParam(0, genName(part, 0), objPtr))
|
||||||
|
}
|
||||||
|
return types.NewTuple(list...), false, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func genName(name string, idxDontTitle int) string {
|
||||||
|
parts := strings.Split(name, "_")
|
||||||
|
for i, part := range parts {
|
||||||
|
if i != idxDontTitle && part != "" {
|
||||||
|
if c := part[0]; c >= 'a' && c <= 'z' {
|
||||||
|
part = string(c+'A'-'a') + part[1:]
|
||||||
|
}
|
||||||
|
parts[i] = part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name = strings.Join(parts, "")
|
||||||
|
switch name {
|
||||||
|
case "default", "func", "":
|
||||||
|
name += "_"
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *context) genLinkname(name string, sym *symbol) *ast.Comment {
|
||||||
|
return &ast.Comment{Text: "//go:linkname " + name + " py." + sym.Name}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *context) genDoc(doc string) []*ast.Comment {
|
||||||
|
lines := strings.Split(doc, "\n")
|
||||||
|
list := make([]*ast.Comment, len(lines), len(lines)+2)
|
||||||
|
for i, line := range lines {
|
||||||
|
list[i] = &ast.Comment{Text: "// " + line}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
emptyCommentLine = &ast.Comment{Text: "//"}
|
||||||
|
)
|
||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/goplus/llgo/x/env/llvm"
|
"github.com/goplus/llgo/xtool/env/llvm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/goplus/llgo/x/env/llvm"
|
"github.com/goplus/llgo/xtool/env/llvm"
|
||||||
"github.com/goplus/llgo/x/nm"
|
"github.com/goplus/llgo/xtool/nm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -73,6 +73,11 @@ func makeIndex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func query(q string) {
|
func query(q string) {
|
||||||
|
if len(q) > 0 {
|
||||||
|
if c := q[0]; c != '*' && c != '_' {
|
||||||
|
q = "_" + q
|
||||||
|
}
|
||||||
|
}
|
||||||
files, err := nm.Query(indexDir(), q)
|
files, err := nm.Query(indexDir(), q)
|
||||||
check(err)
|
check(err)
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ func gwrite(b []byte) {
|
|||||||
c.Printf(c.Str("%s"), b)
|
c.Printf(c.Str("%s"), b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printbool(v bool) {
|
||||||
|
if v {
|
||||||
|
printstring("true")
|
||||||
|
} else {
|
||||||
|
printstring("false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func printfloat(v float64) {
|
func printfloat(v float64) {
|
||||||
switch {
|
switch {
|
||||||
case v != v:
|
case v != v:
|
||||||
@@ -177,14 +185,37 @@ func main() {
|
|||||||
printnl()
|
printnl()
|
||||||
prinfsub(100.1)
|
prinfsub(100.1)
|
||||||
printnl()
|
printnl()
|
||||||
printnum(float32(1e9))
|
printany(float32(1e9))
|
||||||
printnl()
|
printnl()
|
||||||
printnum(float64(2e9))
|
printany(float64(2e9))
|
||||||
|
printnl()
|
||||||
|
var b bool = true
|
||||||
|
if b == true && b != false {
|
||||||
|
println("check bool", b)
|
||||||
|
}
|
||||||
|
n1 := 0b1001
|
||||||
|
n2 := 0b0011
|
||||||
|
println("check &^", n1&^n2 == 0b1000, n2&^n1 == 0b0010)
|
||||||
|
println(true, false, 'a', 'A', rune('中'),
|
||||||
|
int8(1), int16(2), int32(3), int64(4), 5,
|
||||||
|
uint8(1), uint16(2), uint32(3), uint64(4), uintptr(5),
|
||||||
|
"llgo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func println(args ...any) {
|
||||||
|
for i, v := range args {
|
||||||
|
if i != 0 {
|
||||||
|
printstring(" ")
|
||||||
|
}
|
||||||
|
printany(v)
|
||||||
|
}
|
||||||
printnl()
|
printnl()
|
||||||
}
|
}
|
||||||
|
|
||||||
func printnum(v any) {
|
func printany(v any) {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
|
case bool:
|
||||||
|
printbool(v)
|
||||||
case int:
|
case int:
|
||||||
printint(int64(v))
|
printint(int64(v))
|
||||||
case int8:
|
case int8:
|
||||||
@@ -211,6 +242,8 @@ func printnum(v any) {
|
|||||||
printfloat(float64(v))
|
printfloat(float64(v))
|
||||||
case float64:
|
case float64:
|
||||||
printfloat(float64(v))
|
printfloat(float64(v))
|
||||||
|
case string:
|
||||||
|
printstring(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,19 @@ source_filename = "main"
|
|||||||
@__llgo_argc = global ptr null
|
@__llgo_argc = global ptr null
|
||||||
@__llgo_argv = global ptr null
|
@__llgo_argv = global ptr null
|
||||||
@1 = private unnamed_addr constant [5 x i8] c"llgo\00", align 1
|
@1 = private unnamed_addr constant [5 x i8] c"llgo\00", align 1
|
||||||
@2 = private unnamed_addr constant [4 x i8] c"NaN\00", align 1
|
@2 = private unnamed_addr constant [11 x i8] c"check bool\00", align 1
|
||||||
@3 = private unnamed_addr constant [5 x i8] c"+Inf\00", align 1
|
@3 = private unnamed_addr constant [9 x i8] c"check &^\00", align 1
|
||||||
@4 = private unnamed_addr constant [5 x i8] c"-Inf\00", align 1
|
@4 = private unnamed_addr constant [5 x i8] c"llgo\00", align 1
|
||||||
@5 = private unnamed_addr constant [17 x i8] c"0123456789abcdef\00", align 1
|
@5 = private unnamed_addr constant [5 x i8] c"true\00", align 1
|
||||||
@6 = private unnamed_addr constant [2 x i8] c"-\00", align 1
|
@6 = private unnamed_addr constant [6 x i8] c"false\00", align 1
|
||||||
@7 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
|
@7 = private unnamed_addr constant [4 x i8] c"NaN\00", align 1
|
||||||
@8 = private unnamed_addr constant [2 x i8] c" \00", align 1
|
@8 = private unnamed_addr constant [5 x i8] c"+Inf\00", align 1
|
||||||
|
@9 = private unnamed_addr constant [5 x i8] c"-Inf\00", align 1
|
||||||
|
@10 = private unnamed_addr constant [17 x i8] c"0123456789abcdef\00", align 1
|
||||||
|
@11 = private unnamed_addr constant [2 x i8] c"-\00", align 1
|
||||||
|
@12 = private unnamed_addr constant [2 x i8] c" \00", align 1
|
||||||
|
@13 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
|
||||||
|
@14 = private unnamed_addr constant [2 x i8] c" \00", align 1
|
||||||
|
|
||||||
define %"github.com/goplus/llgo/internal/runtime.Slice" @main.bytes(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
define %"github.com/goplus/llgo/internal/runtime.Slice" @main.bytes(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
@@ -45,7 +51,7 @@ _llgo_0:
|
|||||||
|
|
||||||
define void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
define void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
|
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
|
||||||
%2 = icmp eq i64 %1, 0
|
%2 = icmp eq i64 %1, 0
|
||||||
br i1 %2, label %_llgo_1, label %_llgo_2
|
br i1 %2, label %_llgo_1, label %_llgo_2
|
||||||
|
|
||||||
@@ -94,13 +100,115 @@ _llgo_0:
|
|||||||
call void @main.printnl()
|
call void @main.printnl()
|
||||||
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
|
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
|
||||||
%4 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %3, i64 1315859240)
|
%4 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %3, i64 1315859240)
|
||||||
call void @main.printnum(%"github.com/goplus/llgo/internal/runtime.iface" %4)
|
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %4)
|
||||||
call void @main.printnl()
|
call void @main.printnl()
|
||||||
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
|
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
|
||||||
%6 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %5, i64 4746175415993761792)
|
%6 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %5, i64 4746175415993761792)
|
||||||
call void @main.printnum(%"github.com/goplus/llgo/internal/runtime.iface" %6)
|
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %6)
|
||||||
call void @main.printnl()
|
call void @main.printnl()
|
||||||
|
br i1 true, label %_llgo_3, label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_3
|
||||||
|
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
|
||||||
|
%8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %7, i64 0
|
||||||
|
%9 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 10)
|
||||||
|
%10 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %9)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %10, ptr %8, align 8
|
||||||
|
%11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %7, i64 1
|
||||||
|
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
|
||||||
|
%13 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %12, i64 -1)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %13, ptr %11, align 8
|
||||||
|
%14 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %7, i64 16, i64 2, i64 0, i64 2, i64 2)
|
||||||
|
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %14)
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_3, %_llgo_1, %_llgo_0
|
||||||
|
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
|
||||||
|
%16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %15, i64 0
|
||||||
|
%17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 8)
|
||||||
|
%18 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %17)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %18, ptr %16, align 8
|
||||||
|
%19 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %15, i64 1
|
||||||
|
%20 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
|
||||||
|
%21 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %20, i64 -1)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %21, ptr %19, align 8
|
||||||
|
%22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %15, i64 2
|
||||||
|
%23 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
|
||||||
|
%24 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %23, i64 -1)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %24, ptr %22, align 8
|
||||||
|
%25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %15, i64 16, i64 3, i64 0, i64 3, i64 3)
|
||||||
|
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %25)
|
||||||
|
%26 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 256)
|
||||||
|
%27 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 0
|
||||||
|
%28 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
|
||||||
|
%29 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %28, i64 -1)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %29, ptr %27, align 8
|
||||||
|
%30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 1
|
||||||
|
%31 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
|
||||||
|
%32 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %31, i64 0)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %32, ptr %30, align 8
|
||||||
|
%33 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 2
|
||||||
|
%34 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
|
||||||
|
%35 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %34, i64 97)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %35, ptr %33, align 8
|
||||||
|
%36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 3
|
||||||
|
%37 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
|
||||||
|
%38 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %37, i64 65)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %38, ptr %36, align 8
|
||||||
|
%39 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 4
|
||||||
|
%40 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
|
||||||
|
%41 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %40, i64 20013)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %41, ptr %39, align 8
|
||||||
|
%42 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 5
|
||||||
|
%43 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
|
||||||
|
%44 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %43, i64 1)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %44, ptr %42, align 8
|
||||||
|
%45 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 6
|
||||||
|
%46 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
|
||||||
|
%47 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %46, i64 2)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %47, ptr %45, align 8
|
||||||
|
%48 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 7
|
||||||
|
%49 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
|
||||||
|
%50 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %49, i64 3)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %50, ptr %48, align 8
|
||||||
|
%51 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 8
|
||||||
|
%52 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
|
||||||
|
%53 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %52, i64 4)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %53, ptr %51, align 8
|
||||||
|
%54 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 9
|
||||||
|
%55 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
|
||||||
|
%56 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %55, i64 5)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %56, ptr %54, align 8
|
||||||
|
%57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 10
|
||||||
|
%58 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
|
||||||
|
%59 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %58, i64 1)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %59, ptr %57, align 8
|
||||||
|
%60 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 11
|
||||||
|
%61 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
|
||||||
|
%62 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %61, i64 2)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %62, ptr %60, align 8
|
||||||
|
%63 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 12
|
||||||
|
%64 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
|
||||||
|
%65 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %64, i64 3)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %65, ptr %63, align 8
|
||||||
|
%66 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 13
|
||||||
|
%67 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
|
||||||
|
%68 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %67, i64 4)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %68, ptr %66, align 8
|
||||||
|
%69 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 14
|
||||||
|
%70 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
|
||||||
|
%71 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %70, i64 5)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %71, ptr %69, align 8
|
||||||
|
%72 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %26, i64 15
|
||||||
|
%73 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 4)
|
||||||
|
%74 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %73)
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.iface" %74, ptr %72, align 8
|
||||||
|
%75 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %26, i64 16, i64 16, i64 0, i64 16, i64 16)
|
||||||
|
call void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %75)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_0
|
||||||
|
br i1 true, label %_llgo_1, label %_llgo_2
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @main.prinfsub(double %0) {
|
define void @main.prinfsub(double %0) {
|
||||||
@@ -117,18 +225,223 @@ _llgo_0:
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 1)
|
||||||
|
%2 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %1)
|
||||||
|
%3 = extractvalue { i64, i1 } %2, 0
|
||||||
|
%4 = trunc i64 %3 to i1
|
||||||
|
%5 = extractvalue { i64, i1 } %2, 1
|
||||||
|
br i1 %5, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_30, %_llgo_29, %_llgo_28, %_llgo_26, %_llgo_24, %_llgo_22, %_llgo_20, %_llgo_18, %_llgo_16, %_llgo_14, %_llgo_12, %_llgo_10, %_llgo_8, %_llgo_6, %_llgo_4, %_llgo_2
|
||||||
|
ret void
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_0
|
||||||
|
call void @main.printbool(i1 %4)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_0
|
||||||
|
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
|
||||||
|
%7 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %6)
|
||||||
|
%8 = extractvalue { i64, i1 } %7, 0
|
||||||
|
%9 = extractvalue { i64, i1 } %7, 1
|
||||||
|
br i1 %9, label %_llgo_4, label %_llgo_5
|
||||||
|
|
||||||
|
_llgo_4: ; preds = %_llgo_3
|
||||||
|
call void @main.printint(i64 %8)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_5: ; preds = %_llgo_3
|
||||||
|
%10 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
|
||||||
|
%11 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %10)
|
||||||
|
%12 = extractvalue { i64, i1 } %11, 0
|
||||||
|
%13 = trunc i64 %12 to i8
|
||||||
|
%14 = extractvalue { i64, i1 } %11, 1
|
||||||
|
br i1 %14, label %_llgo_6, label %_llgo_7
|
||||||
|
|
||||||
|
_llgo_6: ; preds = %_llgo_5
|
||||||
|
%15 = sext i8 %13 to i64
|
||||||
|
call void @main.printint(i64 %15)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_7: ; preds = %_llgo_5
|
||||||
|
%16 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
|
||||||
|
%17 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %16)
|
||||||
|
%18 = extractvalue { i64, i1 } %17, 0
|
||||||
|
%19 = trunc i64 %18 to i16
|
||||||
|
%20 = extractvalue { i64, i1 } %17, 1
|
||||||
|
br i1 %20, label %_llgo_8, label %_llgo_9
|
||||||
|
|
||||||
|
_llgo_8: ; preds = %_llgo_7
|
||||||
|
%21 = sext i16 %19 to i64
|
||||||
|
call void @main.printint(i64 %21)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_9: ; preds = %_llgo_7
|
||||||
|
%22 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
|
||||||
|
%23 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %22)
|
||||||
|
%24 = extractvalue { i64, i1 } %23, 0
|
||||||
|
%25 = trunc i64 %24 to i32
|
||||||
|
%26 = extractvalue { i64, i1 } %23, 1
|
||||||
|
br i1 %26, label %_llgo_10, label %_llgo_11
|
||||||
|
|
||||||
|
_llgo_10: ; preds = %_llgo_9
|
||||||
|
%27 = sext i32 %25 to i64
|
||||||
|
call void @main.printint(i64 %27)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_11: ; preds = %_llgo_9
|
||||||
|
%28 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
|
||||||
|
%29 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %28)
|
||||||
|
%30 = extractvalue { i64, i1 } %29, 0
|
||||||
|
%31 = extractvalue { i64, i1 } %29, 1
|
||||||
|
br i1 %31, label %_llgo_12, label %_llgo_13
|
||||||
|
|
||||||
|
_llgo_12: ; preds = %_llgo_11
|
||||||
|
call void @main.printint(i64 %30)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_13: ; preds = %_llgo_11
|
||||||
|
%32 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 7)
|
||||||
|
%33 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %32)
|
||||||
|
%34 = extractvalue { i64, i1 } %33, 0
|
||||||
|
%35 = extractvalue { i64, i1 } %33, 1
|
||||||
|
br i1 %35, label %_llgo_14, label %_llgo_15
|
||||||
|
|
||||||
|
_llgo_14: ; preds = %_llgo_13
|
||||||
|
call void @main.printuint(i64 %34)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_15: ; preds = %_llgo_13
|
||||||
|
%36 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
|
||||||
|
%37 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %36)
|
||||||
|
%38 = extractvalue { i64, i1 } %37, 0
|
||||||
|
%39 = trunc i64 %38 to i8
|
||||||
|
%40 = extractvalue { i64, i1 } %37, 1
|
||||||
|
br i1 %40, label %_llgo_16, label %_llgo_17
|
||||||
|
|
||||||
|
_llgo_16: ; preds = %_llgo_15
|
||||||
|
%41 = sext i8 %39 to i64
|
||||||
|
call void @main.printuint(i64 %41)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_17: ; preds = %_llgo_15
|
||||||
|
%42 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
|
||||||
|
%43 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %42)
|
||||||
|
%44 = extractvalue { i64, i1 } %43, 0
|
||||||
|
%45 = trunc i64 %44 to i16
|
||||||
|
%46 = extractvalue { i64, i1 } %43, 1
|
||||||
|
br i1 %46, label %_llgo_18, label %_llgo_19
|
||||||
|
|
||||||
|
_llgo_18: ; preds = %_llgo_17
|
||||||
|
%47 = sext i16 %45 to i64
|
||||||
|
call void @main.printuint(i64 %47)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_19: ; preds = %_llgo_17
|
||||||
|
%48 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
|
||||||
|
%49 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %48)
|
||||||
|
%50 = extractvalue { i64, i1 } %49, 0
|
||||||
|
%51 = trunc i64 %50 to i32
|
||||||
|
%52 = extractvalue { i64, i1 } %49, 1
|
||||||
|
br i1 %52, label %_llgo_20, label %_llgo_21
|
||||||
|
|
||||||
|
_llgo_20: ; preds = %_llgo_19
|
||||||
|
%53 = sext i32 %51 to i64
|
||||||
|
call void @main.printuint(i64 %53)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_21: ; preds = %_llgo_19
|
||||||
|
%54 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
|
||||||
|
%55 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %54)
|
||||||
|
%56 = extractvalue { i64, i1 } %55, 0
|
||||||
|
%57 = extractvalue { i64, i1 } %55, 1
|
||||||
|
br i1 %57, label %_llgo_22, label %_llgo_23
|
||||||
|
|
||||||
|
_llgo_22: ; preds = %_llgo_21
|
||||||
|
call void @main.printuint(i64 %56)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_23: ; preds = %_llgo_21
|
||||||
|
%58 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
|
||||||
|
%59 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %58)
|
||||||
|
%60 = extractvalue { i64, i1 } %59, 0
|
||||||
|
%61 = extractvalue { i64, i1 } %59, 1
|
||||||
|
br i1 %61, label %_llgo_24, label %_llgo_25
|
||||||
|
|
||||||
|
_llgo_24: ; preds = %_llgo_23
|
||||||
|
call void @main.printuint(i64 %60)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_25: ; preds = %_llgo_23
|
||||||
|
%62 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
|
||||||
|
%63 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %62)
|
||||||
|
%64 = extractvalue { i64, i1 } %63, 0
|
||||||
|
%65 = trunc i64 %64 to i32
|
||||||
|
%66 = bitcast i32 %65 to float
|
||||||
|
%67 = extractvalue { i64, i1 } %63, 1
|
||||||
|
br i1 %67, label %_llgo_26, label %_llgo_27
|
||||||
|
|
||||||
|
_llgo_26: ; preds = %_llgo_25
|
||||||
|
%68 = fpext float %66 to double
|
||||||
|
call void @main.printfloat(double %68)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_27: ; preds = %_llgo_25
|
||||||
|
%69 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
|
||||||
|
%70 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %69)
|
||||||
|
%71 = extractvalue { i64, i1 } %70, 0
|
||||||
|
%72 = bitcast i64 %71 to double
|
||||||
|
%73 = extractvalue { i64, i1 } %70, 1
|
||||||
|
br i1 %73, label %_llgo_28, label %_llgo_29
|
||||||
|
|
||||||
|
_llgo_28: ; preds = %_llgo_27
|
||||||
|
call void @main.printfloat(double %72)
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_29: ; preds = %_llgo_27
|
||||||
|
%74 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 24)
|
||||||
|
%75 = call { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %74)
|
||||||
|
%76 = extractvalue { %"github.com/goplus/llgo/internal/runtime.String", i1 } %75, 0
|
||||||
|
%77 = extractvalue { %"github.com/goplus/llgo/internal/runtime.String", i1 } %75, 1
|
||||||
|
br i1 %77, label %_llgo_30, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_30: ; preds = %_llgo_29
|
||||||
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %76)
|
||||||
|
br label %_llgo_1
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main.printbool(i1 %0) {
|
||||||
|
_llgo_0:
|
||||||
|
br i1 %0, label %_llgo_1, label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
%1 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 4)
|
||||||
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %1)
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_3, %_llgo_1
|
||||||
|
ret void
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_0
|
||||||
|
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 5)
|
||||||
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
|
||||||
|
br label %_llgo_2
|
||||||
|
}
|
||||||
|
|
||||||
define void @main.printfloat(double %0) {
|
define void @main.printfloat(double %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = fcmp one double %0, %0
|
%1 = fcmp one double %0, %0
|
||||||
br i1 %1, label %_llgo_1, label %_llgo_3
|
br i1 %1, label %_llgo_1, label %_llgo_3
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 3)
|
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 3)
|
||||||
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_7
|
_llgo_2: ; preds = %_llgo_7
|
||||||
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 4)
|
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 4)
|
||||||
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %3)
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %3)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
@@ -138,7 +451,7 @@ _llgo_3: ; preds = %_llgo_0
|
|||||||
br i1 %5, label %_llgo_6, label %_llgo_7
|
br i1 %5, label %_llgo_6, label %_llgo_7
|
||||||
|
|
||||||
_llgo_4: ; preds = %_llgo_10
|
_llgo_4: ; preds = %_llgo_10
|
||||||
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 4)
|
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 4)
|
||||||
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %6)
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %6)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
@@ -310,8 +623,8 @@ _llgo_0:
|
|||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_3
|
_llgo_1: ; preds = %_llgo_3
|
||||||
%2 = urem i64 %14, 16
|
%2 = urem i64 %14, 16
|
||||||
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 16)
|
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 16)
|
||||||
%4 = call ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %3)
|
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %3, 0
|
||||||
%5 = getelementptr inbounds i8, ptr %4, i64 %2
|
%5 = getelementptr inbounds i8, ptr %4, i64 %2
|
||||||
%6 = load i8, ptr %5, align 1
|
%6 = load i8, ptr %5, align 1
|
||||||
%7 = getelementptr inbounds i8, ptr %1, i64 %15
|
%7 = getelementptr inbounds i8, ptr %1, i64 %15
|
||||||
@@ -354,7 +667,7 @@ _llgo_0:
|
|||||||
br i1 %1, label %_llgo_1, label %_llgo_2
|
br i1 %1, label %_llgo_1, label %_llgo_2
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 1)
|
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @11, i64 1)
|
||||||
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2)
|
||||||
%3 = sub i64 0, %0
|
%3 = sub i64 0, %0
|
||||||
br label %_llgo_2
|
br label %_llgo_2
|
||||||
@@ -365,165 +678,48 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
|
||||||
|
br label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_5, %_llgo_0
|
||||||
|
%2 = phi i64 [ -1, %_llgo_0 ], [ %3, %_llgo_5 ]
|
||||||
|
%3 = add i64 %2, 1
|
||||||
|
%4 = icmp slt i64 %3, %1
|
||||||
|
br i1 %4, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1
|
||||||
|
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
|
||||||
|
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3
|
||||||
|
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8
|
||||||
|
%8 = icmp ne i64 %3, 0
|
||||||
|
br i1 %8, label %_llgo_4, label %_llgo_5
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_1
|
||||||
|
call void @main.printnl()
|
||||||
|
ret void
|
||||||
|
|
||||||
|
_llgo_4: ; preds = %_llgo_2
|
||||||
|
%9 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @12, i64 1)
|
||||||
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %9)
|
||||||
|
br label %_llgo_5
|
||||||
|
|
||||||
|
_llgo_5: ; preds = %_llgo_4, %_llgo_2
|
||||||
|
call void @main.printany(%"github.com/goplus/llgo/internal/runtime.iface" %7)
|
||||||
|
br label %_llgo_1
|
||||||
|
}
|
||||||
|
|
||||||
define void @main.printnl() {
|
define void @main.printnl() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 1)
|
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @13, i64 1)
|
||||||
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0)
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @main.printnum(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
|
|
||||||
_llgo_0:
|
|
||||||
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
|
|
||||||
%2 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %1)
|
|
||||||
%3 = extractvalue { i64, i1 } %2, 0
|
|
||||||
%4 = extractvalue { i64, i1 } %2, 1
|
|
||||||
br i1 %4, label %_llgo_2, label %_llgo_3
|
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_26, %_llgo_25, %_llgo_24, %_llgo_22, %_llgo_20, %_llgo_18, %_llgo_16, %_llgo_14, %_llgo_12, %_llgo_10, %_llgo_8, %_llgo_6, %_llgo_4, %_llgo_2
|
|
||||||
ret void
|
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_0
|
|
||||||
call void @main.printint(i64 %3)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_3: ; preds = %_llgo_0
|
|
||||||
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
|
|
||||||
%6 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %5)
|
|
||||||
%7 = extractvalue { i64, i1 } %6, 0
|
|
||||||
%8 = extractvalue { i64, i1 } %6, 1
|
|
||||||
br i1 %8, label %_llgo_4, label %_llgo_5
|
|
||||||
|
|
||||||
_llgo_4: ; preds = %_llgo_3
|
|
||||||
call void @main.printint(i64 %7)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_5: ; preds = %_llgo_3
|
|
||||||
%9 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
|
|
||||||
%10 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %9)
|
|
||||||
%11 = extractvalue { i64, i1 } %10, 0
|
|
||||||
%12 = extractvalue { i64, i1 } %10, 1
|
|
||||||
br i1 %12, label %_llgo_6, label %_llgo_7
|
|
||||||
|
|
||||||
_llgo_6: ; preds = %_llgo_5
|
|
||||||
call void @main.printint(i64 %11)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_7: ; preds = %_llgo_5
|
|
||||||
%13 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
|
|
||||||
%14 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %13)
|
|
||||||
%15 = extractvalue { i64, i1 } %14, 0
|
|
||||||
%16 = extractvalue { i64, i1 } %14, 1
|
|
||||||
br i1 %16, label %_llgo_8, label %_llgo_9
|
|
||||||
|
|
||||||
_llgo_8: ; preds = %_llgo_7
|
|
||||||
call void @main.printint(i64 %15)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_9: ; preds = %_llgo_7
|
|
||||||
%17 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
|
|
||||||
%18 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %17)
|
|
||||||
%19 = extractvalue { i64, i1 } %18, 0
|
|
||||||
%20 = extractvalue { i64, i1 } %18, 1
|
|
||||||
br i1 %20, label %_llgo_10, label %_llgo_11
|
|
||||||
|
|
||||||
_llgo_10: ; preds = %_llgo_9
|
|
||||||
call void @main.printint(i64 %19)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_11: ; preds = %_llgo_9
|
|
||||||
%21 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 7)
|
|
||||||
%22 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %21)
|
|
||||||
%23 = extractvalue { i64, i1 } %22, 0
|
|
||||||
%24 = extractvalue { i64, i1 } %22, 1
|
|
||||||
br i1 %24, label %_llgo_12, label %_llgo_13
|
|
||||||
|
|
||||||
_llgo_12: ; preds = %_llgo_11
|
|
||||||
call void @main.printuint(i64 %23)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_13: ; preds = %_llgo_11
|
|
||||||
%25 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
|
|
||||||
%26 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %25)
|
|
||||||
%27 = extractvalue { i64, i1 } %26, 0
|
|
||||||
%28 = extractvalue { i64, i1 } %26, 1
|
|
||||||
br i1 %28, label %_llgo_14, label %_llgo_15
|
|
||||||
|
|
||||||
_llgo_14: ; preds = %_llgo_13
|
|
||||||
call void @main.printuint(i64 %27)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_15: ; preds = %_llgo_13
|
|
||||||
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
|
|
||||||
%30 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %29)
|
|
||||||
%31 = extractvalue { i64, i1 } %30, 0
|
|
||||||
%32 = extractvalue { i64, i1 } %30, 1
|
|
||||||
br i1 %32, label %_llgo_16, label %_llgo_17
|
|
||||||
|
|
||||||
_llgo_16: ; preds = %_llgo_15
|
|
||||||
call void @main.printuint(i64 %31)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_17: ; preds = %_llgo_15
|
|
||||||
%33 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
|
|
||||||
%34 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %33)
|
|
||||||
%35 = extractvalue { i64, i1 } %34, 0
|
|
||||||
%36 = extractvalue { i64, i1 } %34, 1
|
|
||||||
br i1 %36, label %_llgo_18, label %_llgo_19
|
|
||||||
|
|
||||||
_llgo_18: ; preds = %_llgo_17
|
|
||||||
call void @main.printuint(i64 %35)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_19: ; preds = %_llgo_17
|
|
||||||
%37 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
|
|
||||||
%38 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %37)
|
|
||||||
%39 = extractvalue { i64, i1 } %38, 0
|
|
||||||
%40 = extractvalue { i64, i1 } %38, 1
|
|
||||||
br i1 %40, label %_llgo_20, label %_llgo_21
|
|
||||||
|
|
||||||
_llgo_20: ; preds = %_llgo_19
|
|
||||||
call void @main.printuint(i64 %39)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_21: ; preds = %_llgo_19
|
|
||||||
%41 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
|
|
||||||
%42 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %41)
|
|
||||||
%43 = extractvalue { i64, i1 } %42, 0
|
|
||||||
%44 = extractvalue { i64, i1 } %42, 1
|
|
||||||
br i1 %44, label %_llgo_22, label %_llgo_23
|
|
||||||
|
|
||||||
_llgo_22: ; preds = %_llgo_21
|
|
||||||
call void @main.printuint(i64 %43)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_23: ; preds = %_llgo_21
|
|
||||||
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
|
|
||||||
%46 = call { float, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float32"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %45)
|
|
||||||
%47 = extractvalue { float, i1 } %46, 0
|
|
||||||
%48 = extractvalue { float, i1 } %46, 1
|
|
||||||
br i1 %48, label %_llgo_24, label %_llgo_25
|
|
||||||
|
|
||||||
_llgo_24: ; preds = %_llgo_23
|
|
||||||
%49 = fpext float %47 to double
|
|
||||||
call void @main.printfloat(double %49)
|
|
||||||
br label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_25: ; preds = %_llgo_23
|
|
||||||
%50 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
|
|
||||||
%51 = call { double, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float64"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %50)
|
|
||||||
%52 = extractvalue { double, i1 } %51, 0
|
|
||||||
%53 = extractvalue { double, i1 } %51, 1
|
|
||||||
br i1 %53, label %_llgo_26, label %_llgo_1
|
|
||||||
|
|
||||||
_llgo_26: ; preds = %_llgo_25
|
|
||||||
call void @main.printfloat(double %52)
|
|
||||||
br label %_llgo_1
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @main.printsp() {
|
define void @main.printsp() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1)
|
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @14, i64 1)
|
||||||
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0)
|
call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
@@ -587,8 +783,6 @@ _llgo_0:
|
|||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
@@ -599,12 +793,10 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
|
|||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr, i64)
|
||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String")
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
||||||
|
|
||||||
declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
|
declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
|
||||||
|
|
||||||
declare { float, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float32"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
|
declare { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
|
||||||
|
|
||||||
declare { double, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float64"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ _llgo_0:
|
|||||||
|
|
||||||
define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
|
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||||
@@ -58,7 +58,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
|
|||||||
br i1 %4, label %_llgo_2, label %_llgo_3
|
br i1 %4, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1
|
_llgo_2: ; preds = %_llgo_1
|
||||||
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
|
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
|
||||||
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3
|
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3
|
||||||
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8
|
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8
|
||||||
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
|
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
|
||||||
@@ -80,10 +80,6 @@ declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llg
|
|||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
|
declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
|
||||||
|
|
||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ _llgo_0:
|
|||||||
br i1 %1, label %_llgo_1, label %_llgo_2
|
br i1 %1, label %_llgo_1, label %_llgo_2
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_0
|
_llgo_1: ; preds = %_llgo_0
|
||||||
%2 = call ptr @sqlite3_errstr()
|
%2 = call ptr @sqlite3_errstr(i32 %0)
|
||||||
%3 = call i32 (ptr, ...) @printf(ptr @0, i32 %0, ptr %2)
|
%3 = call i32 (ptr, ...) @printf(ptr @0, i32 %0, ptr %2)
|
||||||
call void @exit(i32 1)
|
call void @exit(i32 1)
|
||||||
br label %_llgo_2
|
br label %_llgo_2
|
||||||
@@ -45,11 +45,11 @@ _llgo_0:
|
|||||||
%3 = extractvalue { ptr, i32 } %2, 0
|
%3 = extractvalue { ptr, i32 } %2, 0
|
||||||
%4 = extractvalue { ptr, i32 } %2, 1
|
%4 = extractvalue { ptr, i32 } %2, 1
|
||||||
call void @main.check(i32 %4)
|
call void @main.check(i32 %4)
|
||||||
%5 = call i32 @sqlite3_close()
|
%5 = call i32 @sqlite3_close(ptr %3)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare ptr @sqlite3_errstr()
|
declare ptr @sqlite3_errstr(i32)
|
||||||
|
|
||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
@@ -59,4 +59,4 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
|||||||
|
|
||||||
declare { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr, i32, ptr)
|
declare { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr, i32, ptr)
|
||||||
|
|
||||||
declare i32 @sqlite3_close()
|
declare i32 @sqlite3_close(ptr)
|
||||||
|
|||||||
15
cl/_testpy/callpy/in.go
Normal file
15
cl/_testpy/callpy/in.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
"github.com/goplus/llgo/py/os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := math.Sqrt(py.Float(2))
|
||||||
|
wd := os.Getcwd()
|
||||||
|
c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
|
||||||
|
c.Printf(c.Str("cwd = %s\n"), wd.CStr())
|
||||||
|
}
|
||||||
74
cl/_testpy/callpy/out.ll
Normal file
74
cl/_testpy/callpy/out.ll
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@__llgo_py.math.sqrt = linkonce global ptr null
|
||||||
|
@__llgo_py.os.getcwd = linkonce global ptr null
|
||||||
|
@0 = private unnamed_addr constant [14 x i8] c"sqrt(2) = %f\0A\00", align 1
|
||||||
|
@1 = private unnamed_addr constant [10 x i8] c"cwd = %s\0A\00", align 1
|
||||||
|
@__llgo_py.math = external global ptr
|
||||||
|
@2 = private unnamed_addr constant [5 x i8] c"sqrt\00", align 1
|
||||||
|
@__llgo_py.os = external global ptr
|
||||||
|
@3 = private unnamed_addr constant [7 x i8] c"getcwd\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
call void @"github.com/goplus/llgo/py/os.init"()
|
||||||
|
%1 = load ptr, ptr @__llgo_py.math, align 8
|
||||||
|
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @2, ptr @__llgo_py.math.sqrt, ptr null)
|
||||||
|
%2 = load ptr, ptr @__llgo_py.os, align 8
|
||||||
|
call void (ptr, ...) @llgoLoadPyModSyms(ptr %2, ptr @3, ptr @__llgo_py.os.getcwd, ptr null)
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
call void @Py_Initialize()
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = call ptr @PyFloat_FromDouble(double 2.000000e+00)
|
||||||
|
%3 = load ptr, ptr @__llgo_py.math.sqrt, align 8
|
||||||
|
%4 = call ptr @PyObject_CallOneArg(ptr %3, ptr %2)
|
||||||
|
%5 = load ptr, ptr @__llgo_py.os.getcwd, align 8
|
||||||
|
%6 = call ptr @PyObject_CallNoArgs(ptr %5)
|
||||||
|
%7 = call double @PyFloat_AsDouble(ptr %4)
|
||||||
|
%8 = call i32 (ptr, ...) @printf(ptr @0, double %7)
|
||||||
|
%9 = call ptr @PyUnicode_AsUTF8(ptr %6)
|
||||||
|
%10 = call i32 (ptr, ...) @printf(ptr @1, ptr %9)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/os.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @PyFloat_FromDouble(double)
|
||||||
|
|
||||||
|
declare ptr @PyObject_CallOneArg(ptr, ptr)
|
||||||
|
|
||||||
|
declare ptr @PyObject_CallNoArgs(ptr)
|
||||||
|
|
||||||
|
declare double @PyFloat_AsDouble(ptr)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare ptr @PyUnicode_AsUTF8(ptr)
|
||||||
|
|
||||||
|
declare void @llgoLoadPyModSyms(ptr, ...)
|
||||||
|
|
||||||
|
declare void @Py_Initialize()
|
||||||
12
cl/_testpy/gcd/in.go
Normal file
12
cl/_testpy/gcd/in.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := math.Gcd(py.Long(60), py.Long(20), py.Long(25))
|
||||||
|
c.Printf(c.Str("gcd(60, 20, 25) = %d\n"), x.Long())
|
||||||
|
}
|
||||||
59
cl/_testpy/gcd/out.ll
Normal file
59
cl/_testpy/gcd/out.ll
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@__llgo_py.math.gcd = linkonce global ptr null
|
||||||
|
@0 = private unnamed_addr constant [22 x i8] c"gcd(60, 20, 25) = %d\0A\00", align 1
|
||||||
|
@__llgo_py.math = external global ptr
|
||||||
|
@1 = private unnamed_addr constant [4 x i8] c"gcd\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
%1 = load ptr, ptr @__llgo_py.math, align 8
|
||||||
|
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.gcd, ptr null)
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
call void @Py_Initialize()
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = call ptr @PyLong_FromLong(i32 60)
|
||||||
|
%3 = call ptr @PyLong_FromLong(i32 20)
|
||||||
|
%4 = call ptr @PyLong_FromLong(i32 25)
|
||||||
|
%5 = load ptr, ptr @__llgo_py.math.gcd, align 8
|
||||||
|
%6 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %5, ptr %2, ptr %3, ptr %4, ptr null)
|
||||||
|
%7 = call i32 @PyLong_AsLong(ptr %6)
|
||||||
|
%8 = call i32 (ptr, ...) @printf(ptr @0, i32 %7)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @PyLong_FromLong(i32)
|
||||||
|
|
||||||
|
declare ptr @PyObject_CallFunctionObjArgs(ptr, ...)
|
||||||
|
|
||||||
|
declare i32 @PyLong_AsLong(ptr)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare void @llgoLoadPyModSyms(ptr, ...)
|
||||||
|
|
||||||
|
declare void @Py_Initialize()
|
||||||
14
cl/_testpy/math/in.go
Normal file
14
cl/_testpy/math/in.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package math
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "py.math"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:linkname Sqrt py.sqrt
|
||||||
|
func Sqrt(x *py.Object) *py.Object
|
||||||
28
cl/_testpy/math/out.ll
Normal file
28
cl/_testpy/math/out.ll
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
; ModuleID = 'math'
|
||||||
|
source_filename = "math"
|
||||||
|
|
||||||
|
@"math.init$guard" = global ptr null
|
||||||
|
@__llgo_py.math = linkonce global ptr null
|
||||||
|
@0 = private unnamed_addr constant [5 x i8] c"math\00", align 1
|
||||||
|
|
||||||
|
define void @math.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"math.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"math.init$guard", align 1
|
||||||
|
%1 = load ptr, ptr @__llgo_py.math, align 8
|
||||||
|
%2 = icmp ne ptr %1, null
|
||||||
|
br i1 %2, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_3, %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_1
|
||||||
|
%3 = call ptr @PyImport_ImportModule(ptr @0)
|
||||||
|
store ptr %3, ptr @__llgo_py.math, align 8
|
||||||
|
br label %_llgo_2
|
||||||
|
}
|
||||||
|
|
||||||
|
declare ptr @PyImport_ImportModule(ptr)
|
||||||
24
cl/_testpy/matrix/in.go
Normal file
24
cl/_testpy/matrix/in.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/numpy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a := py.List(
|
||||||
|
py.List(1.0, 2.0, 3.0),
|
||||||
|
py.List(4.0, 5.0, 6.0),
|
||||||
|
py.List(7.0, 8.0, 9.0),
|
||||||
|
)
|
||||||
|
b := py.List(
|
||||||
|
py.List(9.0, 8.0, 7.0),
|
||||||
|
py.List(6.0, 5.0, 4.0),
|
||||||
|
py.List(3.0, 2.0, 1.0),
|
||||||
|
)
|
||||||
|
x := numpy.Add(a, b)
|
||||||
|
c.Printf(c.Str("a = %s\n"), a.Str().CStr())
|
||||||
|
c.Printf(c.Str("a = %s\n"), b.Str().CStr())
|
||||||
|
c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
|
||||||
|
}
|
||||||
121
cl/_testpy/matrix/out.ll
Normal file
121
cl/_testpy/matrix/out.ll
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@__llgo_py.numpy.add = linkonce global ptr null
|
||||||
|
@0 = private unnamed_addr constant [8 x i8] c"a = %s\0A\00", align 1
|
||||||
|
@1 = private unnamed_addr constant [8 x i8] c"a = %s\0A\00", align 1
|
||||||
|
@2 = private unnamed_addr constant [10 x i8] c"a+b = %s\0A\00", align 1
|
||||||
|
@__llgo_py.numpy = external global ptr
|
||||||
|
@3 = private unnamed_addr constant [4 x i8] c"add\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"github.com/goplus/llgo/py/numpy.init"()
|
||||||
|
%1 = load ptr, ptr @__llgo_py.numpy, align 8
|
||||||
|
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @3, ptr @__llgo_py.numpy.add, ptr null)
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
call void @Py_Initialize()
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = call ptr @PyList_New(i64 3)
|
||||||
|
%3 = call ptr @PyFloat_FromDouble(double 1.000000e+00)
|
||||||
|
%4 = call i32 @PyList_SetItem(ptr %2, i64 0, ptr %3)
|
||||||
|
%5 = call ptr @PyFloat_FromDouble(double 2.000000e+00)
|
||||||
|
%6 = call i32 @PyList_SetItem(ptr %2, i64 1, ptr %5)
|
||||||
|
%7 = call ptr @PyFloat_FromDouble(double 3.000000e+00)
|
||||||
|
%8 = call i32 @PyList_SetItem(ptr %2, i64 2, ptr %7)
|
||||||
|
%9 = call ptr @PyList_New(i64 3)
|
||||||
|
%10 = call ptr @PyFloat_FromDouble(double 4.000000e+00)
|
||||||
|
%11 = call i32 @PyList_SetItem(ptr %9, i64 0, ptr %10)
|
||||||
|
%12 = call ptr @PyFloat_FromDouble(double 5.000000e+00)
|
||||||
|
%13 = call i32 @PyList_SetItem(ptr %9, i64 1, ptr %12)
|
||||||
|
%14 = call ptr @PyFloat_FromDouble(double 6.000000e+00)
|
||||||
|
%15 = call i32 @PyList_SetItem(ptr %9, i64 2, ptr %14)
|
||||||
|
%16 = call ptr @PyList_New(i64 3)
|
||||||
|
%17 = call ptr @PyFloat_FromDouble(double 7.000000e+00)
|
||||||
|
%18 = call i32 @PyList_SetItem(ptr %16, i64 0, ptr %17)
|
||||||
|
%19 = call ptr @PyFloat_FromDouble(double 8.000000e+00)
|
||||||
|
%20 = call i32 @PyList_SetItem(ptr %16, i64 1, ptr %19)
|
||||||
|
%21 = call ptr @PyFloat_FromDouble(double 9.000000e+00)
|
||||||
|
%22 = call i32 @PyList_SetItem(ptr %16, i64 2, ptr %21)
|
||||||
|
%23 = call ptr @PyList_New(i64 3)
|
||||||
|
%24 = call i32 @PyList_SetItem(ptr %23, i64 0, ptr %2)
|
||||||
|
%25 = call i32 @PyList_SetItem(ptr %23, i64 1, ptr %9)
|
||||||
|
%26 = call i32 @PyList_SetItem(ptr %23, i64 2, ptr %16)
|
||||||
|
%27 = call ptr @PyList_New(i64 3)
|
||||||
|
%28 = call ptr @PyFloat_FromDouble(double 9.000000e+00)
|
||||||
|
%29 = call i32 @PyList_SetItem(ptr %27, i64 0, ptr %28)
|
||||||
|
%30 = call ptr @PyFloat_FromDouble(double 8.000000e+00)
|
||||||
|
%31 = call i32 @PyList_SetItem(ptr %27, i64 1, ptr %30)
|
||||||
|
%32 = call ptr @PyFloat_FromDouble(double 7.000000e+00)
|
||||||
|
%33 = call i32 @PyList_SetItem(ptr %27, i64 2, ptr %32)
|
||||||
|
%34 = call ptr @PyList_New(i64 3)
|
||||||
|
%35 = call ptr @PyFloat_FromDouble(double 6.000000e+00)
|
||||||
|
%36 = call i32 @PyList_SetItem(ptr %34, i64 0, ptr %35)
|
||||||
|
%37 = call ptr @PyFloat_FromDouble(double 5.000000e+00)
|
||||||
|
%38 = call i32 @PyList_SetItem(ptr %34, i64 1, ptr %37)
|
||||||
|
%39 = call ptr @PyFloat_FromDouble(double 4.000000e+00)
|
||||||
|
%40 = call i32 @PyList_SetItem(ptr %34, i64 2, ptr %39)
|
||||||
|
%41 = call ptr @PyList_New(i64 3)
|
||||||
|
%42 = call ptr @PyFloat_FromDouble(double 3.000000e+00)
|
||||||
|
%43 = call i32 @PyList_SetItem(ptr %41, i64 0, ptr %42)
|
||||||
|
%44 = call ptr @PyFloat_FromDouble(double 2.000000e+00)
|
||||||
|
%45 = call i32 @PyList_SetItem(ptr %41, i64 1, ptr %44)
|
||||||
|
%46 = call ptr @PyFloat_FromDouble(double 1.000000e+00)
|
||||||
|
%47 = call i32 @PyList_SetItem(ptr %41, i64 2, ptr %46)
|
||||||
|
%48 = call ptr @PyList_New(i64 3)
|
||||||
|
%49 = call i32 @PyList_SetItem(ptr %48, i64 0, ptr %27)
|
||||||
|
%50 = call i32 @PyList_SetItem(ptr %48, i64 1, ptr %34)
|
||||||
|
%51 = call i32 @PyList_SetItem(ptr %48, i64 2, ptr %41)
|
||||||
|
%52 = load ptr, ptr @__llgo_py.numpy.add, align 8
|
||||||
|
%53 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %52, ptr %23, ptr %48, ptr null)
|
||||||
|
%54 = call ptr @PyObject_Str(ptr %23)
|
||||||
|
%55 = call ptr @PyUnicode_AsUTF8(ptr %54)
|
||||||
|
%56 = call i32 (ptr, ...) @printf(ptr @0, ptr %55)
|
||||||
|
%57 = call ptr @PyObject_Str(ptr %48)
|
||||||
|
%58 = call ptr @PyUnicode_AsUTF8(ptr %57)
|
||||||
|
%59 = call i32 (ptr, ...) @printf(ptr @1, ptr %58)
|
||||||
|
%60 = call ptr @PyObject_Str(ptr %53)
|
||||||
|
%61 = call ptr @PyUnicode_AsUTF8(ptr %60)
|
||||||
|
%62 = call i32 (ptr, ...) @printf(ptr @2, ptr %61)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/numpy.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @PyList_New(i64)
|
||||||
|
|
||||||
|
declare ptr @PyFloat_FromDouble(double)
|
||||||
|
|
||||||
|
declare i32 @PyList_SetItem(ptr, i64, ptr)
|
||||||
|
|
||||||
|
declare ptr @PyObject_CallFunctionObjArgs(ptr, ...)
|
||||||
|
|
||||||
|
declare ptr @PyObject_Str(ptr)
|
||||||
|
|
||||||
|
declare ptr @PyUnicode_AsUTF8(ptr)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare void @llgoLoadPyModSyms(ptr, ...)
|
||||||
|
|
||||||
|
declare void @Py_Initialize()
|
||||||
10
cl/_testpy/pi/in.go
Normal file
10
cl/_testpy/pi/in.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c.Printf(c.Str("pi = %f\n"), math.Pi.Float64())
|
||||||
|
}
|
||||||
49
cl/_testpy/pi/out.ll
Normal file
49
cl/_testpy/pi/out.ll
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@0 = private unnamed_addr constant [9 x i8] c"pi = %f\0A\00", align 1
|
||||||
|
@__llgo_py.math = external global ptr
|
||||||
|
@1 = private unnamed_addr constant [3 x i8] c"pi\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
call void @Py_Initialize()
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = load ptr, ptr @__llgo_py.math, align 8
|
||||||
|
%3 = call ptr @PyObject_GetAttrString(ptr %2, ptr @1)
|
||||||
|
%4 = call double @PyFloat_AsDouble(ptr %3)
|
||||||
|
%5 = call i32 (ptr, ...) @printf(ptr @0, double %4)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @PyObject_GetAttrString(ptr, ptr)
|
||||||
|
|
||||||
|
declare double @PyFloat_AsDouble(ptr)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare void @Py_Initialize()
|
||||||
12
cl/_testpy/pow/in.go
Normal file
12
cl/_testpy/pow/in.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
"github.com/goplus/llgo/py/math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
x := math.Pow(py.Float(2), py.Float(3))
|
||||||
|
c.Printf(c.Str("pow(2, 3) = %f\n"), x.Float64())
|
||||||
|
}
|
||||||
58
cl/_testpy/pow/out.ll
Normal file
58
cl/_testpy/pow/out.ll
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@__llgo_py.math.pow = linkonce global ptr null
|
||||||
|
@0 = private unnamed_addr constant [16 x i8] c"pow(2, 3) = %f\0A\00", align 1
|
||||||
|
@__llgo_py.math = external global ptr
|
||||||
|
@1 = private unnamed_addr constant [4 x i8] c"pow\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
call void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
%1 = load ptr, ptr @__llgo_py.math, align 8
|
||||||
|
call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.pow, ptr null)
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
call void @Py_Initialize()
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = call ptr @PyFloat_FromDouble(double 2.000000e+00)
|
||||||
|
%3 = call ptr @PyFloat_FromDouble(double 3.000000e+00)
|
||||||
|
%4 = load ptr, ptr @__llgo_py.math.pow, align 8
|
||||||
|
%5 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %4, ptr %2, ptr %3, ptr null)
|
||||||
|
%6 = call double @PyFloat_AsDouble(ptr %5)
|
||||||
|
%7 = call i32 (ptr, ...) @printf(ptr @0, double %6)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/py/math.init"()
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @PyFloat_FromDouble(double)
|
||||||
|
|
||||||
|
declare ptr @PyObject_CallFunctionObjArgs(ptr, ...)
|
||||||
|
|
||||||
|
declare double @PyFloat_AsDouble(ptr)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare void @llgoLoadPyModSyms(ptr, ...)
|
||||||
|
|
||||||
|
declare void @Py_Initialize()
|
||||||
@@ -34,7 +34,7 @@ _llgo_0:
|
|||||||
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
call void @main.init()
|
call void @main.init()
|
||||||
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @main.hello()
|
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @main.hello()
|
||||||
%3 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %2)
|
%3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1
|
||||||
%4 = add i64 %3, 1
|
%4 = add i64 %3, 1
|
||||||
%5 = alloca i8, i64 %4, align 1
|
%5 = alloca i8, i64 %4, align 1
|
||||||
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %5, %"github.com/goplus/llgo/internal/runtime.String" %2)
|
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %5, %"github.com/goplus/llgo/internal/runtime.String" %2)
|
||||||
@@ -46,8 +46,6 @@ declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/ll
|
|||||||
|
|
||||||
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ func main() {
|
|||||||
string_len("hello"[1:])
|
string_len("hello"[1:])
|
||||||
string_len("hello"[1:2])
|
string_len("hello"[1:2])
|
||||||
string_len("hello"[5:])
|
string_len("hello"[5:])
|
||||||
|
|
||||||
|
s = append(s, 5, 6, 7, 8)
|
||||||
|
out(len(s))
|
||||||
|
data := []byte{'a', 'b', 'c'}
|
||||||
|
data = append(data, "def"...)
|
||||||
|
out(len(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func string_len(s string) {
|
func string_len(s string) {
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ source_filename = "main"
|
|||||||
@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
||||||
@2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
@2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
||||||
@3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
@3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
|
||||||
@4 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
@4 = private unnamed_addr constant [4 x i8] c"def\00", align 1
|
||||||
|
@5 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
|
||||||
|
|
||||||
define void @main.init() {
|
define void @main.init() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
@@ -57,7 +58,7 @@ _llgo_0:
|
|||||||
store i64 2, ptr %10, align 4
|
store i64 2, ptr %10, align 4
|
||||||
store i64 3, ptr %11, align 4
|
store i64 3, ptr %11, align 4
|
||||||
store i64 4, ptr %12, align 4
|
store i64 4, ptr %12, align 4
|
||||||
%13 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%13 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 1
|
||||||
call void @main.out(i64 %13)
|
call void @main.out(i64 %13)
|
||||||
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
|
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
|
||||||
%15 = getelementptr inbounds i64, ptr %14, i64 0
|
%15 = getelementptr inbounds i64, ptr %14, i64 0
|
||||||
@@ -69,90 +70,119 @@ _llgo_0:
|
|||||||
%18 = getelementptr inbounds i64, ptr %14, i64 3
|
%18 = getelementptr inbounds i64, ptr %14, i64 3
|
||||||
store i64 4, ptr %18, align 4
|
store i64 4, ptr %18, align 4
|
||||||
%19 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %14, i64 8, i64 4, i64 0, i64 4, i64 4)
|
%19 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %14, i64 8, i64 4, i64 0, i64 4, i64 4)
|
||||||
%20 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %19)
|
%20 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %19, 1
|
||||||
call void @main.out(i64 %20)
|
call void @main.out(i64 %20)
|
||||||
call void @main.out(i64 4)
|
call void @main.out(i64 4)
|
||||||
call void @main.out(i64 4)
|
call void @main.out(i64 4)
|
||||||
call void @main.out(i64 4)
|
call void @main.out(i64 4)
|
||||||
%21 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%21 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
call void @main.out(i64 %21)
|
call void @main.out(i64 %21)
|
||||||
call void @main.out(i64 4)
|
call void @main.out(i64 4)
|
||||||
call void @main.out(i64 4)
|
call void @main.out(i64 4)
|
||||||
%22 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%22 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%23 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%24 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%24 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
|
||||||
%25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %24, i64 8, i64 %22, i64 1, i64 %23, i64 %22)
|
%25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %24, i64 8, i64 %22, i64 1, i64 %23, i64 %22)
|
||||||
%26 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %25)
|
%26 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %25, 1
|
||||||
call void @main.out(i64 %26)
|
call void @main.out(i64 %26)
|
||||||
%27 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%27 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%28 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%28 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%29 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
|
||||||
%30 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 %27, i64 1, i64 %28, i64 %27)
|
%30 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 %27, i64 1, i64 %28, i64 %27)
|
||||||
%31 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %30)
|
%31 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %30, 2
|
||||||
call void @main.out(i64 %31)
|
call void @main.out(i64 %31)
|
||||||
%32 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%32 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%33 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%33 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
|
||||||
%34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %33, i64 8, i64 %32, i64 1, i64 2, i64 %32)
|
%34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %33, i64 8, i64 %32, i64 1, i64 2, i64 %32)
|
||||||
%35 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %34)
|
%35 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %34, 1
|
||||||
call void @main.out(i64 %35)
|
call void @main.out(i64 %35)
|
||||||
%36 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%36 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%37 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%37 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
|
||||||
%38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %37, i64 8, i64 %36, i64 1, i64 2, i64 %36)
|
%38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %37, i64 8, i64 %36, i64 1, i64 2, i64 %36)
|
||||||
%39 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %38)
|
%39 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %38, 2
|
||||||
call void @main.out(i64 %39)
|
call void @main.out(i64 %39)
|
||||||
%40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%41 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%41 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
|
||||||
%42 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %41, i64 8, i64 %40, i64 1, i64 2, i64 2)
|
%42 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %41, i64 8, i64 %40, i64 1, i64 2, i64 2)
|
||||||
%43 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %42)
|
%43 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %42, 1
|
||||||
call void @main.out(i64 %43)
|
call void @main.out(i64 %43)
|
||||||
%44 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
|
||||||
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7)
|
%45 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
|
||||||
%46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %44, i64 1, i64 2, i64 2)
|
%46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %44, i64 1, i64 2, i64 2)
|
||||||
%47 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %46)
|
%47 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %46, 2
|
||||||
call void @main.out(i64 %47)
|
call void @main.out(i64 %47)
|
||||||
%48 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
|
%48 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
|
||||||
%49 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %48)
|
%49 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %48, 1
|
||||||
call void @main.out(i64 %49)
|
call void @main.out(i64 %49)
|
||||||
%50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
|
%50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
|
||||||
%51 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %50)
|
%51 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %50, 2
|
||||||
call void @main.out(i64 %51)
|
call void @main.out(i64 %51)
|
||||||
%52 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
|
%52 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
|
||||||
%53 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %52)
|
%53 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %52, 1
|
||||||
call void @main.out(i64 %53)
|
call void @main.out(i64 %53)
|
||||||
%54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
|
%54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
|
||||||
%55 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %54)
|
%55 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %54, 2
|
||||||
call void @main.out(i64 %55)
|
call void @main.out(i64 %55)
|
||||||
%56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
|
%56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
|
||||||
%57 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %56)
|
%57 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %56, 1
|
||||||
call void @main.out(i64 %57)
|
call void @main.out(i64 %57)
|
||||||
%58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
|
%58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
|
||||||
%59 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %58)
|
%59 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %58, 2
|
||||||
call void @main.out(i64 %59)
|
call void @main.out(i64 %59)
|
||||||
%60 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5)
|
%60 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5)
|
||||||
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %60)
|
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %60)
|
||||||
%61 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5)
|
%61 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5)
|
||||||
%62 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %61)
|
%62 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %61, 1
|
||||||
%63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %61, i64 1, i64 %62)
|
%63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %61, i64 1, i64 %62)
|
||||||
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %63)
|
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %63)
|
||||||
%64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5)
|
%64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5)
|
||||||
%65 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %64, i64 1, i64 2)
|
%65 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %64, i64 1, i64 2)
|
||||||
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %65)
|
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %65)
|
||||||
%66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5)
|
%66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5)
|
||||||
%67 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %66)
|
%67 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %66, 1
|
||||||
%68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %66, i64 5, i64 %67)
|
%68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %66, i64 5, i64 %67)
|
||||||
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %68)
|
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %68)
|
||||||
|
%69 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
|
||||||
|
%70 = getelementptr inbounds i64, ptr %69, i64 0
|
||||||
|
store i64 5, ptr %70, align 4
|
||||||
|
%71 = getelementptr inbounds i64, ptr %69, i64 1
|
||||||
|
store i64 6, ptr %71, align 4
|
||||||
|
%72 = getelementptr inbounds i64, ptr %69, i64 2
|
||||||
|
store i64 7, ptr %72, align 4
|
||||||
|
%73 = getelementptr inbounds i64, ptr %69, i64 3
|
||||||
|
store i64 8, ptr %73, align 4
|
||||||
|
%74 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %69, i64 8, i64 4, i64 0, i64 4, i64 4)
|
||||||
|
%75 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 0
|
||||||
|
%76 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 1
|
||||||
|
%77 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %7, ptr %75, i64 %76, i64 8)
|
||||||
|
%78 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %77, 1
|
||||||
|
call void @main.out(i64 %78)
|
||||||
|
%79 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 3)
|
||||||
|
%80 = getelementptr inbounds i8, ptr %79, i64 0
|
||||||
|
store i8 97, ptr %80, align 1
|
||||||
|
%81 = getelementptr inbounds i8, ptr %79, i64 1
|
||||||
|
store i8 98, ptr %81, align 1
|
||||||
|
%82 = getelementptr inbounds i8, ptr %79, i64 2
|
||||||
|
store i8 99, ptr %82, align 1
|
||||||
|
%83 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %79, i64 1, i64 3, i64 0, i64 3, i64 3)
|
||||||
|
%84 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 3)
|
||||||
|
%85 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %84, 0
|
||||||
|
%86 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %84, 1
|
||||||
|
%87 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %83, ptr %85, i64 %86, i64 1)
|
||||||
|
%88 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %87, 1
|
||||||
|
call void @main.out(i64 %88)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @main.out(i64 %0) {
|
define void @main.out(i64 %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = call i32 (ptr, ...) @printf(ptr @4, i64 %0)
|
%1 = call i32 (ptr, ...) @printf(ptr @5, i64 %0)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
define void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %0)
|
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1
|
||||||
call void @main.out(i64 %1)
|
call void @main.out(i64 %1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
@@ -163,16 +193,10 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
|||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
|
|
||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64)
|
||||||
|
|
||||||
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice", ptr, i64, i64)
|
||||||
|
|
||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ func concat(args ...string) (ret string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func info(s string) string {
|
||||||
|
return "" + s + "..."
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
result := concat("Hello", " ", "World")
|
result := concat("Hello", " ", "World")
|
||||||
c.Fprintf(c.Stderr, c.Str("Hi, %s\n"), c.AllocaCStr(result))
|
c.Fprintf(c.Stderr, c.Str("Hi, %s\n"), c.AllocaCStr(result))
|
||||||
|
|||||||
@@ -6,17 +6,19 @@ source_filename = "main"
|
|||||||
|
|
||||||
@"main.init$guard" = global ptr null
|
@"main.init$guard" = global ptr null
|
||||||
@0 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
@0 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||||
|
@1 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||||
|
@2 = private unnamed_addr constant [4 x i8] c"...\00", align 1
|
||||||
@__llgo_argc = global ptr null
|
@__llgo_argc = global ptr null
|
||||||
@__llgo_argv = global ptr null
|
@__llgo_argv = global ptr null
|
||||||
@1 = private unnamed_addr constant [6 x i8] c"Hello\00", align 1
|
@3 = private unnamed_addr constant [6 x i8] c"Hello\00", align 1
|
||||||
@2 = private unnamed_addr constant [2 x i8] c" \00", align 1
|
@4 = private unnamed_addr constant [2 x i8] c" \00", align 1
|
||||||
@3 = private unnamed_addr constant [6 x i8] c"World\00", align 1
|
@5 = private unnamed_addr constant [6 x i8] c"World\00", align 1
|
||||||
@__stderrp = external global ptr
|
@__stderrp = external global ptr
|
||||||
@4 = private unnamed_addr constant [8 x i8] c"Hi, %s\0A\00", align 1
|
@6 = private unnamed_addr constant [8 x i8] c"Hi, %s\0A\00", align 1
|
||||||
|
|
||||||
define %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
define %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
|
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
|
||||||
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 0)
|
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 0)
|
||||||
%3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 0
|
%3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 0
|
||||||
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1
|
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1
|
||||||
@@ -37,7 +39,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
|
|||||||
br i1 %13, label %_llgo_2, label %_llgo_3
|
br i1 %13, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1
|
_llgo_2: ; preds = %_llgo_1
|
||||||
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
|
%14 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
|
||||||
%15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %14, i64 %12
|
%15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %14, i64 %12
|
||||||
%16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8
|
%16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8
|
||||||
%17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %16)
|
%17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %16)
|
||||||
@@ -49,6 +51,15 @@ _llgo_3: ; preds = %_llgo_1
|
|||||||
ret %"github.com/goplus/llgo/internal/runtime.String" %11
|
ret %"github.com/goplus/llgo/internal/runtime.String" %11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define %"github.com/goplus/llgo/internal/runtime.String" @main.info(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 0)
|
||||||
|
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %1, %"github.com/goplus/llgo/internal/runtime.String" %0)
|
||||||
|
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 3)
|
||||||
|
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %2, %"github.com/goplus/llgo/internal/runtime.String" %3)
|
||||||
|
ret %"github.com/goplus/llgo/internal/runtime.String" %4
|
||||||
|
}
|
||||||
|
|
||||||
define void @main.init() {
|
define void @main.init() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%0 = load i1, ptr @"main.init$guard", align 1
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
@@ -70,29 +81,25 @@ _llgo_0:
|
|||||||
call void @main.init()
|
call void @main.init()
|
||||||
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
|
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48)
|
||||||
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 0
|
%3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 0
|
||||||
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5)
|
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5)
|
||||||
store %"github.com/goplus/llgo/internal/runtime.String" %4, ptr %3, align 8
|
store %"github.com/goplus/llgo/internal/runtime.String" %4, ptr %3, align 8
|
||||||
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 1
|
%5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 1
|
||||||
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1)
|
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1)
|
||||||
store %"github.com/goplus/llgo/internal/runtime.String" %6, ptr %5, align 8
|
store %"github.com/goplus/llgo/internal/runtime.String" %6, ptr %5, align 8
|
||||||
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 2
|
%7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 2
|
||||||
%8 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5)
|
%8 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 5)
|
||||||
store %"github.com/goplus/llgo/internal/runtime.String" %8, ptr %7, align 8
|
store %"github.com/goplus/llgo/internal/runtime.String" %8, ptr %7, align 8
|
||||||
%9 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %2, i64 16, i64 3, i64 0, i64 3, i64 3)
|
%9 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %2, i64 16, i64 3, i64 0, i64 3, i64 3)
|
||||||
%10 = call %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %9)
|
%10 = call %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %9)
|
||||||
%11 = load ptr, ptr @__stderrp, align 8
|
%11 = load ptr, ptr @__stderrp, align 8
|
||||||
%12 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %10)
|
%12 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %10, 1
|
||||||
%13 = add i64 %12, 1
|
%13 = add i64 %12, 1
|
||||||
%14 = alloca i8, i64 %13, align 1
|
%14 = alloca i8, i64 %13, align 1
|
||||||
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %14, %"github.com/goplus/llgo/internal/runtime.String" %10)
|
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %14, %"github.com/goplus/llgo/internal/runtime.String" %10)
|
||||||
%16 = call i32 (ptr, ptr, ...) @fprintf(ptr %11, ptr @4, ptr %15)
|
%16 = call i32 (ptr, ptr, ...) @fprintf(ptr %11, ptr @6, ptr %15)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String")
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
|
||||||
@@ -103,8 +110,6 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
|||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
declare i32 @fprintf(ptr, ptr, ...)
|
declare i32 @fprintf(ptr, ptr, ...)
|
||||||
|
|||||||
@@ -119,12 +119,12 @@ _llgo_0:
|
|||||||
%61 = load i64, ptr %60, align 4
|
%61 = load i64, ptr %60, align 4
|
||||||
%62 = call i32 (ptr, ...) @printf(ptr @3, i64 %61)
|
%62 = call i32 (ptr, ...) @printf(ptr @3, i64 %61)
|
||||||
%63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 6)
|
%63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 6)
|
||||||
%64 = call ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %63)
|
%64 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %63, 0
|
||||||
%65 = getelementptr inbounds i8, ptr %64, i64 2
|
%65 = getelementptr inbounds i8, ptr %64, i64 2
|
||||||
%66 = load i8, ptr %65, align 1
|
%66 = load i8, ptr %65, align 1
|
||||||
%67 = call i32 (ptr, ...) @printf(ptr @4, i8 %66)
|
%67 = call i32 (ptr, ...) @printf(ptr @4, i8 %66)
|
||||||
%68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 6)
|
%68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 6)
|
||||||
%69 = call ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %68)
|
%69 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %68, 0
|
||||||
%70 = getelementptr inbounds i8, ptr %69, i64 1
|
%70 = getelementptr inbounds i8, ptr %69, i64 1
|
||||||
%71 = load i8, ptr %70, align 1
|
%71 = load i8, ptr %70, align 1
|
||||||
%72 = call i32 (ptr, ...) @printf(ptr @6, i8 %71)
|
%72 = call i32 (ptr, ...) @printf(ptr @6, i8 %71)
|
||||||
@@ -138,5 +138,3 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64)
|
|||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String")
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ _llgo_0:
|
|||||||
%2 = mul i64 %0, 4
|
%2 = mul i64 %0, 4
|
||||||
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %2)
|
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %2)
|
||||||
%4 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %3, i64 %0, i64 %0)
|
%4 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %3, i64 %0, i64 %0)
|
||||||
%5 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %4)
|
%5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 1
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||||
@@ -29,7 +29,7 @@ _llgo_2: ; preds = %_llgo_1
|
|||||||
%9 = extractvalue { ptr, ptr } %1, 1
|
%9 = extractvalue { ptr, ptr } %1, 1
|
||||||
%10 = extractvalue { ptr, ptr } %1, 0
|
%10 = extractvalue { ptr, ptr } %1, 0
|
||||||
%11 = call i32 %10(ptr %9)
|
%11 = call i32 %10(ptr %9)
|
||||||
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4)
|
%12 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 0
|
||||||
%13 = getelementptr inbounds i32, ptr %12, i64 %7
|
%13 = getelementptr inbounds i32, ptr %12, i64 %7
|
||||||
store i32 %11, ptr %13, align 4
|
store i32 %11, ptr %13, align 4
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
@@ -76,7 +76,7 @@ _llgo_0:
|
|||||||
store ptr null, ptr %4, align 8
|
store ptr null, ptr %4, align 8
|
||||||
%5 = load { ptr, ptr }, ptr %2, align 8
|
%5 = load { ptr, ptr }, ptr %2, align 8
|
||||||
%6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %5)
|
%6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %5)
|
||||||
%7 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %6)
|
%7 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 1
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||||
@@ -86,7 +86,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
|
|||||||
br i1 %10, label %_llgo_2, label %_llgo_3
|
br i1 %10, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1
|
_llgo_2: ; preds = %_llgo_1
|
||||||
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %6)
|
%11 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 0
|
||||||
%12 = getelementptr inbounds i32, ptr %11, i64 %9
|
%12 = getelementptr inbounds i32, ptr %11, i64 %9
|
||||||
%13 = load i32, ptr %12, align 4
|
%13 = load i32, ptr %12, align 4
|
||||||
%14 = call i32 (ptr, ...) @printf(ptr @0, i32 %13)
|
%14 = call i32 (ptr, ...) @printf(ptr @0, i32 %13)
|
||||||
@@ -105,7 +105,7 @@ _llgo_3: ; preds = %_llgo_1
|
|||||||
store ptr %16, ptr %20, align 8
|
store ptr %16, ptr %20, align 8
|
||||||
%21 = load { ptr, ptr }, ptr %18, align 8
|
%21 = load { ptr, ptr }, ptr %18, align 8
|
||||||
%22 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %21)
|
%22 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %21)
|
||||||
%23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %22)
|
%23 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 1
|
||||||
br label %_llgo_4
|
br label %_llgo_4
|
||||||
|
|
||||||
_llgo_4: ; preds = %_llgo_5, %_llgo_3
|
_llgo_4: ; preds = %_llgo_5, %_llgo_3
|
||||||
@@ -115,7 +115,7 @@ _llgo_4: ; preds = %_llgo_5, %_llgo_3
|
|||||||
br i1 %26, label %_llgo_5, label %_llgo_6
|
br i1 %26, label %_llgo_5, label %_llgo_6
|
||||||
|
|
||||||
_llgo_5: ; preds = %_llgo_4
|
_llgo_5: ; preds = %_llgo_4
|
||||||
%27 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %22)
|
%27 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 0
|
||||||
%28 = getelementptr inbounds i32, ptr %27, i64 %25
|
%28 = getelementptr inbounds i32, ptr %27, i64 %25
|
||||||
%29 = load i32, ptr %28, align 4
|
%29 = load i32, ptr %28, align 4
|
||||||
%30 = call i32 (ptr, ...) @printf(ptr @1, i32 %29)
|
%30 = call i32 (ptr, ...) @printf(ptr @1, i32 %29)
|
||||||
@@ -135,7 +135,7 @@ _llgo_6: ; preds = %_llgo_4
|
|||||||
store ptr %33, ptr %37, align 8
|
store ptr %33, ptr %37, align 8
|
||||||
%38 = load { ptr, ptr }, ptr %35, align 8
|
%38 = load { ptr, ptr }, ptr %35, align 8
|
||||||
%39 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %38)
|
%39 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %38)
|
||||||
%40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %39)
|
%40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 1
|
||||||
br label %_llgo_7
|
br label %_llgo_7
|
||||||
|
|
||||||
_llgo_7: ; preds = %_llgo_8, %_llgo_6
|
_llgo_7: ; preds = %_llgo_8, %_llgo_6
|
||||||
@@ -145,7 +145,7 @@ _llgo_7: ; preds = %_llgo_8, %_llgo_6
|
|||||||
br i1 %43, label %_llgo_8, label %_llgo_9
|
br i1 %43, label %_llgo_8, label %_llgo_9
|
||||||
|
|
||||||
_llgo_8: ; preds = %_llgo_7
|
_llgo_8: ; preds = %_llgo_7
|
||||||
%44 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %39)
|
%44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 0
|
||||||
%45 = getelementptr inbounds i32, ptr %44, i64 %42
|
%45 = getelementptr inbounds i32, ptr %44, i64 %42
|
||||||
%46 = load i32, ptr %45, align 4
|
%46 = load i32, ptr %45, align 4
|
||||||
%47 = call i32 (ptr, ...) @printf(ptr @2, i32 %46)
|
%47 = call i32 (ptr, ...) @printf(ptr @2, i32 %46)
|
||||||
@@ -159,10 +159,6 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
|||||||
|
|
||||||
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64)
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
declare i32 @rand()
|
declare i32 @rand()
|
||||||
|
|||||||
39
cl/_testrt/named/in.go
Normal file
39
cl/_testrt/named/in.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/goplus/llgo/internal/runtime/c"
|
||||||
|
|
||||||
|
type mSpanList struct {
|
||||||
|
first *mspan
|
||||||
|
last *mspan
|
||||||
|
}
|
||||||
|
|
||||||
|
type minfo struct {
|
||||||
|
span *mspan
|
||||||
|
info int
|
||||||
|
}
|
||||||
|
|
||||||
|
type mspan struct {
|
||||||
|
next *mspan
|
||||||
|
prev *mspan
|
||||||
|
list *mSpanList
|
||||||
|
info minfo
|
||||||
|
value int
|
||||||
|
check func(int) int
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := &mspan{}
|
||||||
|
m.value = 100
|
||||||
|
m.next = &mspan{}
|
||||||
|
m.next.value = 200
|
||||||
|
m.list = &mSpanList{}
|
||||||
|
m.list.last = &mspan{}
|
||||||
|
m.list.last.value = 300
|
||||||
|
m.info.info = 10
|
||||||
|
m.info.span = m
|
||||||
|
m.check = func(n int) int {
|
||||||
|
return m.value * n
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("%d %d %d %d %d %d\n"), m.next.value, m.list.last.value, m.info.info,
|
||||||
|
m.info.span.value, m.check(-2), m.info.span.check(-3))
|
||||||
|
}
|
||||||
143
cl/_testrt/named/out.ll
Normal file
143
cl/_testrt/named/out.ll
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
%main.mspan = type { ptr, ptr, ptr, %main.minfo, i64, { ptr, ptr } }
|
||||||
|
%main.minfo = type { ptr, i64 }
|
||||||
|
%main.mSpanList = type { ptr, ptr }
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@0 = private unnamed_addr constant [19 x i8] c"%d %d %d %d %d %d\0A\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8)
|
||||||
|
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 64)
|
||||||
|
store ptr %3, ptr %2, align 8
|
||||||
|
%4 = load ptr, ptr %2, align 8
|
||||||
|
%5 = getelementptr inbounds %main.mspan, ptr %4, i32 0, i32 4
|
||||||
|
store i64 100, ptr %5, align 4
|
||||||
|
%6 = load ptr, ptr %2, align 8
|
||||||
|
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 64)
|
||||||
|
%8 = getelementptr inbounds %main.mspan, ptr %6, i32 0, i32 0
|
||||||
|
store ptr %7, ptr %8, align 8
|
||||||
|
%9 = load ptr, ptr %2, align 8
|
||||||
|
%10 = getelementptr inbounds %main.mspan, ptr %9, i32 0, i32 0
|
||||||
|
%11 = load ptr, ptr %10, align 8
|
||||||
|
%12 = getelementptr inbounds %main.mspan, ptr %11, i32 0, i32 4
|
||||||
|
store i64 200, ptr %12, align 4
|
||||||
|
%13 = load ptr, ptr %2, align 8
|
||||||
|
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
|
||||||
|
%15 = getelementptr inbounds %main.mspan, ptr %13, i32 0, i32 2
|
||||||
|
store ptr %14, ptr %15, align 8
|
||||||
|
%16 = load ptr, ptr %2, align 8
|
||||||
|
%17 = getelementptr inbounds %main.mspan, ptr %16, i32 0, i32 2
|
||||||
|
%18 = load ptr, ptr %17, align 8
|
||||||
|
%19 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 64)
|
||||||
|
%20 = getelementptr inbounds %main.mSpanList, ptr %18, i32 0, i32 1
|
||||||
|
store ptr %19, ptr %20, align 8
|
||||||
|
%21 = load ptr, ptr %2, align 8
|
||||||
|
%22 = getelementptr inbounds %main.mspan, ptr %21, i32 0, i32 2
|
||||||
|
%23 = load ptr, ptr %22, align 8
|
||||||
|
%24 = getelementptr inbounds %main.mSpanList, ptr %23, i32 0, i32 1
|
||||||
|
%25 = load ptr, ptr %24, align 8
|
||||||
|
%26 = getelementptr inbounds %main.mspan, ptr %25, i32 0, i32 4
|
||||||
|
store i64 300, ptr %26, align 4
|
||||||
|
%27 = load ptr, ptr %2, align 8
|
||||||
|
%28 = getelementptr inbounds %main.mspan, ptr %27, i32 0, i32 3
|
||||||
|
%29 = getelementptr inbounds %main.minfo, ptr %28, i32 0, i32 1
|
||||||
|
store i64 10, ptr %29, align 4
|
||||||
|
%30 = load ptr, ptr %2, align 8
|
||||||
|
%31 = getelementptr inbounds %main.mspan, ptr %30, i32 0, i32 3
|
||||||
|
%32 = load ptr, ptr %2, align 8
|
||||||
|
%33 = getelementptr inbounds %main.minfo, ptr %31, i32 0, i32 0
|
||||||
|
store ptr %32, ptr %33, align 8
|
||||||
|
%34 = load ptr, ptr %2, align 8
|
||||||
|
%35 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
|
||||||
|
%36 = getelementptr inbounds { ptr }, ptr %35, i32 0, i32 0
|
||||||
|
store ptr %2, ptr %36, align 8
|
||||||
|
%37 = alloca { ptr, ptr }, align 8
|
||||||
|
%38 = getelementptr inbounds { ptr, ptr }, ptr %37, i32 0, i32 0
|
||||||
|
store ptr @"main.main$1", ptr %38, align 8
|
||||||
|
%39 = getelementptr inbounds { ptr, ptr }, ptr %37, i32 0, i32 1
|
||||||
|
store ptr %35, ptr %39, align 8
|
||||||
|
%40 = load { ptr, ptr }, ptr %37, align 8
|
||||||
|
%41 = getelementptr inbounds %main.mspan, ptr %34, i32 0, i32 5
|
||||||
|
store { ptr, ptr } %40, ptr %41, align 8
|
||||||
|
%42 = load ptr, ptr %2, align 8
|
||||||
|
%43 = getelementptr inbounds %main.mspan, ptr %42, i32 0, i32 0
|
||||||
|
%44 = load ptr, ptr %43, align 8
|
||||||
|
%45 = getelementptr inbounds %main.mspan, ptr %44, i32 0, i32 4
|
||||||
|
%46 = load i64, ptr %45, align 4
|
||||||
|
%47 = load ptr, ptr %2, align 8
|
||||||
|
%48 = getelementptr inbounds %main.mspan, ptr %47, i32 0, i32 2
|
||||||
|
%49 = load ptr, ptr %48, align 8
|
||||||
|
%50 = getelementptr inbounds %main.mSpanList, ptr %49, i32 0, i32 1
|
||||||
|
%51 = load ptr, ptr %50, align 8
|
||||||
|
%52 = getelementptr inbounds %main.mspan, ptr %51, i32 0, i32 4
|
||||||
|
%53 = load i64, ptr %52, align 4
|
||||||
|
%54 = load ptr, ptr %2, align 8
|
||||||
|
%55 = getelementptr inbounds %main.mspan, ptr %54, i32 0, i32 3
|
||||||
|
%56 = getelementptr inbounds %main.minfo, ptr %55, i32 0, i32 1
|
||||||
|
%57 = load i64, ptr %56, align 4
|
||||||
|
%58 = load ptr, ptr %2, align 8
|
||||||
|
%59 = getelementptr inbounds %main.mspan, ptr %58, i32 0, i32 3
|
||||||
|
%60 = getelementptr inbounds %main.minfo, ptr %59, i32 0, i32 0
|
||||||
|
%61 = load ptr, ptr %60, align 8
|
||||||
|
%62 = getelementptr inbounds %main.mspan, ptr %61, i32 0, i32 4
|
||||||
|
%63 = load i64, ptr %62, align 4
|
||||||
|
%64 = load ptr, ptr %2, align 8
|
||||||
|
%65 = getelementptr inbounds %main.mspan, ptr %64, i32 0, i32 5
|
||||||
|
%66 = load { ptr, ptr }, ptr %65, align 8
|
||||||
|
%67 = extractvalue { ptr, ptr } %66, 1
|
||||||
|
%68 = extractvalue { ptr, ptr } %66, 0
|
||||||
|
%69 = call i64 %68(ptr %67, i64 -2)
|
||||||
|
%70 = load ptr, ptr %2, align 8
|
||||||
|
%71 = getelementptr inbounds %main.mspan, ptr %70, i32 0, i32 3
|
||||||
|
%72 = getelementptr inbounds %main.minfo, ptr %71, i32 0, i32 0
|
||||||
|
%73 = load ptr, ptr %72, align 8
|
||||||
|
%74 = getelementptr inbounds %main.mspan, ptr %73, i32 0, i32 5
|
||||||
|
%75 = load { ptr, ptr }, ptr %74, align 8
|
||||||
|
%76 = extractvalue { ptr, ptr } %75, 1
|
||||||
|
%77 = extractvalue { ptr, ptr } %75, 0
|
||||||
|
%78 = call i64 %77(ptr %76, i64 -3)
|
||||||
|
%79 = call i32 (ptr, ...) @printf(ptr @0, i64 %46, i64 %53, i64 %57, i64 %63, i64 %69, i64 %78)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
||||||
|
|
||||||
|
define i64 @"main.main$1"(ptr %0, i64 %1) {
|
||||||
|
_llgo_0:
|
||||||
|
%2 = load { ptr }, ptr %0, align 8
|
||||||
|
%3 = extractvalue { ptr } %2, 0
|
||||||
|
%4 = load ptr, ptr %3, align 8
|
||||||
|
%5 = getelementptr inbounds %main.mspan, ptr %4, i32 0, i32 4
|
||||||
|
%6 = load i64, ptr %5, align 4
|
||||||
|
%7 = mul i64 %6, %1
|
||||||
|
ret i64 %7
|
||||||
|
}
|
||||||
|
|
||||||
|
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
@@ -44,7 +44,7 @@ _llgo_0:
|
|||||||
|
|
||||||
define i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
define i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
|
%1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
|
||||||
br label %_llgo_1
|
br label %_llgo_1
|
||||||
|
|
||||||
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
_llgo_1: ; preds = %_llgo_2, %_llgo_0
|
||||||
@@ -55,7 +55,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
|
|||||||
br i1 %5, label %_llgo_2, label %_llgo_3
|
br i1 %5, label %_llgo_2, label %_llgo_3
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1
|
_llgo_2: ; preds = %_llgo_1
|
||||||
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0)
|
%6 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
|
||||||
%7 = getelementptr inbounds i64, ptr %6, i64 %4
|
%7 = getelementptr inbounds i64, ptr %6, i64 %4
|
||||||
%8 = load i64, ptr %7, align 4
|
%8 = load i64, ptr %7, align 4
|
||||||
%9 = add i64 %2, %8
|
%9 = add i64 %2, %8
|
||||||
@@ -72,7 +72,3 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
|
|||||||
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
|
||||||
|
|
||||||
declare i32 @printf(ptr, ...)
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
|
||||||
|
|||||||
@@ -226,5 +226,5 @@ func TestErrVarOf(t *testing.T) {
|
|||||||
}
|
}
|
||||||
ssaPkg := &ssa.Package{Pkg: pkgTypes}
|
ssaPkg := &ssa.Package{Pkg: pkgTypes}
|
||||||
g := &ssa.Global{Pkg: ssaPkg}
|
g := &ssa.Global{Pkg: ssaPkg}
|
||||||
ctx.varOf(g)
|
ctx.varOf(nil, g)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,11 +147,23 @@ func TestCompileEx(t *testing.T, src any, fname, expected string) {
|
|||||||
}
|
}
|
||||||
return rt
|
return rt
|
||||||
})
|
})
|
||||||
|
prog.SetPython(func() *types.Package {
|
||||||
|
rt, err := imp.Import(llssa.PkgPython)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("load python failed:", err)
|
||||||
|
}
|
||||||
|
return rt
|
||||||
|
})
|
||||||
|
|
||||||
ret, err := cl.NewPackage(prog, foo, files)
|
ret, err := cl.NewPackage(prog, foo, files)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("cl.NewPackage failed:", err)
|
t.Fatal("cl.NewPackage failed:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if prog.NeedPyInit { // call PyInit if needed
|
||||||
|
ret.PyInit()
|
||||||
|
}
|
||||||
|
|
||||||
if v := ret.String(); v != expected {
|
if v := ret.String(); v != expected {
|
||||||
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
|
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
|
||||||
}
|
}
|
||||||
|
|||||||
182
cl/compile.go
182
cl/compile.go
@@ -123,6 +123,7 @@ type instrOrValue interface {
|
|||||||
const (
|
const (
|
||||||
PkgNormal = iota
|
PkgNormal = iota
|
||||||
PkgLLGo
|
PkgLLGo
|
||||||
|
PkgPyModule // py.<module>
|
||||||
PkgNoInit // noinit: a package that don't need to be initialized
|
PkgNoInit // noinit: a package that don't need to be initialized
|
||||||
PkgDeclOnly // decl: a package that only have declarations
|
PkgDeclOnly // decl: a package that only have declarations
|
||||||
PkgLinkIR // link llvm ir (.ll)
|
PkgLinkIR // link llvm ir (.ll)
|
||||||
@@ -142,6 +143,7 @@ type context struct {
|
|||||||
goProg *ssa.Program
|
goProg *ssa.Program
|
||||||
goTyps *types.Package
|
goTyps *types.Package
|
||||||
goPkg *ssa.Package
|
goPkg *ssa.Package
|
||||||
|
pyMod string
|
||||||
link map[string]string // pkgPath.nameInPkg => linkname
|
link map[string]string // pkgPath.nameInPkg => linkname
|
||||||
loaded map[*types.Package]*pkgInfo // loaded packages
|
loaded map[*types.Package]*pkgInfo // loaded packages
|
||||||
bvals map[ssa.Value]llssa.Expr // block values
|
bvals map[ssa.Value]llssa.Expr // block values
|
||||||
@@ -183,7 +185,7 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
|
|||||||
func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
|
func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
|
||||||
typ := gbl.Type()
|
typ := gbl.Type()
|
||||||
name, vtype := p.varName(gbl.Pkg.Pkg, gbl)
|
name, vtype := p.varName(gbl.Pkg.Pkg, gbl)
|
||||||
if ignoreName(name) || checkCgo(gbl.Name()) {
|
if vtype == pyVar || ignoreName(name) || checkCgo(gbl.Name()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if debugInstr {
|
if debugInstr {
|
||||||
@@ -209,14 +211,21 @@ var (
|
|||||||
argvTy = types.NewPointer(types.NewPointer(types.Typ[types.Int8]))
|
argvTy = types.NewPointer(types.NewPointer(types.Typ[types.Int8]))
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) llssa.Function {
|
func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Function, llssa.PyObjRef, int) {
|
||||||
pkgTypes, name, ftype := p.funcName(f, true)
|
pkgTypes, name, ftype := p.funcName(f, true)
|
||||||
if ftype != goFunc {
|
if ftype != goFunc {
|
||||||
return nil
|
/*
|
||||||
|
if ftype == pyFunc {
|
||||||
|
// TODO(xsw): pyMod == ""
|
||||||
|
fnName := pysymPrefix + p.pyMod + "." + name
|
||||||
|
return nil, pkg.NewPyFunc(fnName, f.Signature, call), pyFunc
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return nil, nil, ignoredFunc
|
||||||
}
|
}
|
||||||
fn := pkg.FuncOf(name)
|
fn := pkg.FuncOf(name)
|
||||||
if fn != nil && fn.HasBody() {
|
if fn != nil && fn.HasBody() {
|
||||||
return fn
|
return fn, nil, goFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
var sig = f.Signature
|
var sig = f.Signature
|
||||||
@@ -229,7 +238,7 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) llssa.Func
|
|||||||
sig = llssa.FuncAddCtx(ctx, sig)
|
sig = llssa.FuncAddCtx(ctx, sig)
|
||||||
} else {
|
} else {
|
||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig)
|
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig, "ftype:", ftype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fn == nil {
|
if fn == nil {
|
||||||
@@ -262,21 +271,34 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) llssa.Func
|
|||||||
off[i] = p.compilePhis(b, block)
|
off[i] = p.compilePhis(b, block)
|
||||||
}
|
}
|
||||||
for i, block := range f.Blocks {
|
for i, block := range f.Blocks {
|
||||||
p.compileBlock(b, block, off[i], i == 0 && name == "main")
|
doMainInit := (i == 0 && name == "main")
|
||||||
|
doModInit := (i == 1 && f.Name() == "init" && sig.Recv() == nil)
|
||||||
|
p.compileBlock(b, block, off[i], doMainInit, doModInit)
|
||||||
}
|
}
|
||||||
for _, phi := range p.phis {
|
for _, phi := range p.phis {
|
||||||
phi()
|
phi()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return fn
|
return fn, nil, goFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// funcOf returns a function by name and set ftype = goFunc, cFunc, etc.
|
// funcOf returns a function by name and set ftype = goFunc, cFunc, etc.
|
||||||
// or returns nil and set ftype = llgoCstr, llgoAlloca, llgoUnreachable, etc.
|
// or returns nil and set ftype = llgoCstr, llgoAlloca, llgoUnreachable, etc.
|
||||||
func (p *context) funcOf(fn *ssa.Function) (ret llssa.Function, ftype int) {
|
func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObjRef, ftype int) {
|
||||||
_, name, ftype := p.funcName(fn, false)
|
pkgTypes, name, ftype := p.funcName(fn, false)
|
||||||
if ftype == llgoInstr {
|
switch ftype {
|
||||||
|
case pyFunc:
|
||||||
|
if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule {
|
||||||
|
pkg := p.pkg
|
||||||
|
fnName := pysymPrefix + mod + "." + name
|
||||||
|
if pyFn = pkg.PyObjOf(fnName); pyFn == nil {
|
||||||
|
pyFn = pkg.PyNewFunc(fnName, fn.Signature, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ftype = ignoredFunc
|
||||||
|
case llgoInstr:
|
||||||
switch name {
|
switch name {
|
||||||
case "cstr":
|
case "cstr":
|
||||||
ftype = llgoCstr
|
ftype = llgoCstr
|
||||||
@@ -288,31 +310,73 @@ func (p *context) funcOf(fn *ssa.Function) (ret llssa.Function, ftype int) {
|
|||||||
ftype = llgoAlloca
|
ftype = llgoAlloca
|
||||||
case "allocaCStr":
|
case "allocaCStr":
|
||||||
ftype = llgoAllocaCStr
|
ftype = llgoAllocaCStr
|
||||||
|
case "stringData":
|
||||||
|
ftype = llgoStringData
|
||||||
|
case "pyList":
|
||||||
|
ftype = llgoPyList
|
||||||
case "unreachable":
|
case "unreachable":
|
||||||
ftype = llgoUnreachable
|
ftype = llgoUnreachable
|
||||||
case "bitCastTo64F":
|
|
||||||
ftype = llgoBitCastTo64F
|
|
||||||
case "bitCastTo32F":
|
|
||||||
ftype = llgoBitCastTo32F
|
|
||||||
default:
|
default:
|
||||||
panic("unknown llgo instruction: " + name)
|
panic("unknown llgo instruction: " + name)
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
pkg := p.pkg
|
pkg := p.pkg
|
||||||
if ret = pkg.FuncOf(name); ret == nil && len(fn.FreeVars) == 0 {
|
if aFn = pkg.FuncOf(name); aFn == nil {
|
||||||
|
if len(fn.FreeVars) > 0 {
|
||||||
|
return nil, nil, ignoredFunc
|
||||||
|
}
|
||||||
sig := fn.Signature
|
sig := fn.Signature
|
||||||
ret = pkg.NewFuncEx(name, sig, llssa.Background(ftype), false)
|
aFn = pkg.NewFuncEx(name, sig, llssa.Background(ftype), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doInit bool) llssa.BasicBlock {
|
func modOf(name string) string {
|
||||||
ret := p.fn.Block(block.Index)
|
if pos := strings.LastIndexByte(name, '.'); pos > 0 {
|
||||||
|
return name[:pos]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doMainInit, doModInit bool) llssa.BasicBlock {
|
||||||
|
var last int
|
||||||
|
var pyModInit bool
|
||||||
|
var prog = p.prog
|
||||||
|
var pkg = p.pkg
|
||||||
|
var instrs = block.Instrs[n:]
|
||||||
|
var ret = p.fn.Block(block.Index)
|
||||||
b.SetBlock(ret)
|
b.SetBlock(ret)
|
||||||
if doInit {
|
if doModInit {
|
||||||
prog := p.prog
|
if pyModInit = p.pyMod != ""; pyModInit {
|
||||||
pkg := p.pkg
|
last = len(instrs) - 1
|
||||||
|
instrs = instrs[:last]
|
||||||
|
} else {
|
||||||
|
// TODO(xsw): confirm pyMod don't need to call LoadPyModSyms
|
||||||
|
p.inits = append(p.inits, func() {
|
||||||
|
if objs := pkg.PyObjs(); len(objs) > 0 {
|
||||||
|
mods := make(map[string][]llssa.PyObjRef)
|
||||||
|
for name, obj := range objs {
|
||||||
|
modName := modOf(name)
|
||||||
|
mods[modName] = append(mods[modName], obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort by module name
|
||||||
|
modNames := make([]string, 0, len(mods))
|
||||||
|
for modName := range mods {
|
||||||
|
modNames = append(modNames, modName)
|
||||||
|
}
|
||||||
|
sort.Strings(modNames)
|
||||||
|
|
||||||
|
b.SetBlockEx(ret, llssa.AfterInit)
|
||||||
|
for _, modName := range modNames {
|
||||||
|
objs := mods[modName]
|
||||||
|
b.PyLoadModSyms(modName, objs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if doMainInit {
|
||||||
fn := p.fn
|
fn := p.fn
|
||||||
argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC)
|
argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC)
|
||||||
argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC)
|
argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC)
|
||||||
@@ -323,9 +387,23 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
|
|||||||
callRuntimeInit(b, pkg)
|
callRuntimeInit(b, pkg)
|
||||||
b.Call(pkg.FuncOf("main.init").Expr)
|
b.Call(pkg.FuncOf("main.init").Expr)
|
||||||
}
|
}
|
||||||
for _, instr := range block.Instrs[n:] {
|
for _, instr := range instrs {
|
||||||
p.compileInstr(b, instr)
|
p.compileInstr(b, instr)
|
||||||
}
|
}
|
||||||
|
if pyModInit {
|
||||||
|
jump := block.Instrs[n+last].(*ssa.Jump)
|
||||||
|
jumpTo := p.jumpTo(jump)
|
||||||
|
modPath := p.pyMod
|
||||||
|
modName := pysymPrefix + modPath
|
||||||
|
modPtr := pkg.PyNewModVar(modName, true).Expr
|
||||||
|
mod := b.Load(modPtr)
|
||||||
|
cond := b.BinOp(token.NEQ, mod, prog.Null(mod.Type))
|
||||||
|
newBlk := p.fn.MakeBlock()
|
||||||
|
b.If(cond, jumpTo, newBlk)
|
||||||
|
b.SetBlock(newBlk)
|
||||||
|
b.Store(modPtr, b.PyImportMod(modPath))
|
||||||
|
b.Jump(jumpTo)
|
||||||
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,8 +412,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func callRuntimeInit(b llssa.Builder, pkg llssa.Package) {
|
func callRuntimeInit(b llssa.Builder, pkg llssa.Package) {
|
||||||
sig := types.NewSignatureType(nil, nil, nil, nil, nil, false)
|
fn := pkg.NewFunc(RuntimeInit, llssa.NoArgsNoRet, llssa.InC) // don't need to convert runtime.init
|
||||||
fn := pkg.NewFunc(RuntimeInit, sig, llssa.InC) // don't need to convert runtime.init
|
|
||||||
b.Call(fn.Expr)
|
b.Call(fn.Expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,6 +511,15 @@ func (p *context) allocaCStr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr)
|
|||||||
panic("allocaCStr(s string): invalid arguments")
|
panic("allocaCStr(s string): invalid arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func stringData(s string) *int8
|
||||||
|
func (p *context) stringData(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
|
||||||
|
if len(args) == 1 {
|
||||||
|
s := p.compileValue(b, args[0])
|
||||||
|
return b.StringData(s)
|
||||||
|
}
|
||||||
|
panic("stringData(s string): invalid arguments")
|
||||||
|
}
|
||||||
|
|
||||||
func isPhi(i ssa.Instruction) bool {
|
func isPhi(i ssa.Instruction) bool {
|
||||||
_, ok := i.(*ssa.Phi)
|
_, ok := i.(*ssa.Phi)
|
||||||
return ok
|
return ok
|
||||||
@@ -441,7 +527,7 @@ func isPhi(i ssa.Instruction) bool {
|
|||||||
|
|
||||||
func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
|
func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
|
||||||
ret := p.fn.Block(block.Index)
|
ret := p.fn.Block(block.Index)
|
||||||
b.SetBlock(ret)
|
b.SetBlockEx(ret, llssa.AtEnd)
|
||||||
if ninstr := len(block.Instrs); ninstr > 0 {
|
if ninstr := len(block.Instrs); ninstr > 0 {
|
||||||
if isPhi(block.Instrs[0]) {
|
if isPhi(block.Instrs[0]) {
|
||||||
n := 1
|
n := 1
|
||||||
@@ -510,11 +596,17 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
|
|||||||
ret = b.BuiltinCall(fn, args...)
|
ret = b.BuiltinCall(fn, args...)
|
||||||
}
|
}
|
||||||
case *ssa.Function:
|
case *ssa.Function:
|
||||||
fn, ftype := p.compileFunction(cv)
|
aFn, pyFn, ftype := p.compileFunction(cv)
|
||||||
switch ftype {
|
switch ftype {
|
||||||
case goFunc, cFunc:
|
case goFunc, cFunc:
|
||||||
args := p.compileValues(b, args, kind)
|
args := p.compileValues(b, args, kind)
|
||||||
ret = b.Call(fn.Expr, args...)
|
ret = b.Call(aFn.Expr, args...)
|
||||||
|
case pyFunc:
|
||||||
|
args := p.compileValues(b, args, kind)
|
||||||
|
ret = b.Call(pyFn.Expr, args...)
|
||||||
|
case llgoPyList:
|
||||||
|
args := p.compileValues(b, args, fnHasVArg)
|
||||||
|
ret = b.PyList(args...)
|
||||||
case llgoCstr:
|
case llgoCstr:
|
||||||
ret = cstr(b, args)
|
ret = cstr(b, args)
|
||||||
case llgoAdvance:
|
case llgoAdvance:
|
||||||
@@ -525,12 +617,10 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
|
|||||||
ret = p.alloca(b, args)
|
ret = p.alloca(b, args)
|
||||||
case llgoAllocaCStr:
|
case llgoAllocaCStr:
|
||||||
ret = p.allocaCStr(b, args)
|
ret = p.allocaCStr(b, args)
|
||||||
|
case llgoStringData:
|
||||||
|
ret = p.stringData(b, args)
|
||||||
case llgoUnreachable: // func unreachable()
|
case llgoUnreachable: // func unreachable()
|
||||||
b.Unreachable()
|
b.Unreachable()
|
||||||
case llgoBitCastTo32F:
|
|
||||||
ret = b.BitCast(p.compileValue(b, args[0]), b.Prog.Type(types.Typ[types.Float32], llssa.InGo))
|
|
||||||
case llgoBitCastTo64F:
|
|
||||||
ret = b.BitCast(p.compileValue(b, args[0]), b.Prog.Float64())
|
|
||||||
default:
|
default:
|
||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
@@ -650,6 +740,12 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *context) jumpTo(v *ssa.Jump) llssa.BasicBlock {
|
||||||
|
fn := p.fn
|
||||||
|
succs := v.Block().Succs
|
||||||
|
return fn.Block(succs[0].Index)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
||||||
if iv, ok := instr.(instrOrValue); ok {
|
if iv, ok := instr.(instrOrValue); ok {
|
||||||
p.compileInstrOrValue(b, iv, false)
|
p.compileInstrOrValue(b, iv, false)
|
||||||
@@ -673,9 +769,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
|||||||
val := p.compileValue(b, v.Val)
|
val := p.compileValue(b, v.Val)
|
||||||
b.Store(ptr, val)
|
b.Store(ptr, val)
|
||||||
case *ssa.Jump:
|
case *ssa.Jump:
|
||||||
fn := p.fn
|
jmpb := p.jumpTo(v)
|
||||||
succs := v.Block().Succs
|
|
||||||
jmpb := fn.Block(succs[0].Index)
|
|
||||||
b.Jump(jmpb)
|
b.Jump(jmpb)
|
||||||
case *ssa.Return:
|
case *ssa.Return:
|
||||||
var results []llssa.Expr
|
var results []llssa.Expr
|
||||||
@@ -706,12 +800,13 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) compileFunction(v *ssa.Function) (llssa.Function, int) {
|
func (p *context) compileFunction(v *ssa.Function) (goFn llssa.Function, pyFn llssa.PyObjRef, kind int) {
|
||||||
// v.Pkg == nil: means auto generated function?
|
// v.Pkg == nil: means auto generated function?
|
||||||
if v.Pkg == p.goPkg || v.Pkg == nil {
|
if v.Pkg == p.goPkg || v.Pkg == nil {
|
||||||
// function in this package
|
// function in this package
|
||||||
if fn := p.compileFuncDecl(p.pkg, v); fn != nil {
|
goFn, pyFn, kind = p.compileFuncDecl(p.pkg, v)
|
||||||
return fn, goFunc
|
if kind != ignoredFunc {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p.funcOf(v)
|
return p.funcOf(v)
|
||||||
@@ -730,11 +825,13 @@ func (p *context) compileValue(b llssa.Builder, v ssa.Value) llssa.Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *ssa.Function:
|
case *ssa.Function:
|
||||||
fn, _ := p.compileFunction(v)
|
aFn, pyFn, _ := p.compileFunction(v)
|
||||||
return fn.Expr
|
if aFn != nil {
|
||||||
|
return aFn.Expr
|
||||||
|
}
|
||||||
|
return pyFn.Expr
|
||||||
case *ssa.Global:
|
case *ssa.Global:
|
||||||
g := p.varOf(v)
|
return p.varOf(b, v)
|
||||||
return g.Expr
|
|
||||||
case *ssa.Const:
|
case *ssa.Const:
|
||||||
t := types.Default(v.Type())
|
t := types.Default(v.Type())
|
||||||
return b.Const(v.Value, p.prog.Type(t, llssa.InGo))
|
return b.Const(v.Value, p.prog.Type(t, llssa.InGo))
|
||||||
@@ -814,6 +911,7 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
|
|||||||
types.Unsafe: {kind: PkgDeclOnly}, // TODO(xsw): PkgNoInit or PkgDeclOnly?
|
types.Unsafe: {kind: PkgDeclOnly}, // TODO(xsw): PkgNoInit or PkgDeclOnly?
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
ctx.initPyModule()
|
||||||
ctx.initFiles(pkgPath, files)
|
ctx.initFiles(pkgPath, files)
|
||||||
for _, m := range members {
|
for _, m := range members {
|
||||||
member := m.val
|
member := m.val
|
||||||
|
|||||||
@@ -28,8 +28,12 @@ func testCompile(t *testing.T, src, expected string) {
|
|||||||
cltest.TestCompileEx(t, src, "foo.go", expected)
|
cltest.TestCompileEx(t, src, "foo.go", expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFromTestpy(t *testing.T) {
|
||||||
|
cltest.FromDir(t, "", "./_testpy", false)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFromTestlibc(t *testing.T) {
|
func TestFromTestlibc(t *testing.T) {
|
||||||
cltest.FromDir(t, "", "./_testlibc", false)
|
cltest.FromDir(t, "", "./_testlibc", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromTestrt(t *testing.T) {
|
func TestFromTestrt(t *testing.T) {
|
||||||
@@ -41,7 +45,15 @@ func TestFromTestdata(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSqlite(t *testing.T) {
|
func TestSqlite(t *testing.T) {
|
||||||
cltest.Pkg(t, "github.com/goplus/llgo/x/sqlite", "../x/sqlite/sqlite.ll")
|
cltest.Pkg(t, "github.com/goplus/llgo/x/sqlite", "../x/sqlite/llgo_autogen.ll")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFromTestpymath(t *testing.T) {
|
||||||
|
cltest.Pkg(t, ssa.PkgPython+"/math", "../py/math/llgo_autogen.ll")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPython(t *testing.T) {
|
||||||
|
cltest.Pkg(t, ssa.PkgPython, "../py/llgo_autogen.ll")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRuntime(t *testing.T) {
|
func TestRuntime(t *testing.T) {
|
||||||
|
|||||||
45
cl/import.go
45
cl/import.go
@@ -30,6 +30,8 @@ import (
|
|||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type symInfo struct {
|
type symInfo struct {
|
||||||
file string
|
file string
|
||||||
fullName string
|
fullName string
|
||||||
@@ -101,6 +103,8 @@ func pkgKind(v string) (int, string) {
|
|||||||
// return PkgLinkBitCode
|
// return PkgLinkBitCode
|
||||||
if strings.HasPrefix(v, "link:") { // "link: <libpath>"
|
if strings.HasPrefix(v, "link:") { // "link: <libpath>"
|
||||||
return PkgLinkExtern, v[5:]
|
return PkgLinkExtern, v[5:]
|
||||||
|
} else if strings.HasPrefix(v, "py.") { // "py.<module>"
|
||||||
|
return PkgPyModule, v[3:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PkgLLGo, ""
|
return PkgLLGo, ""
|
||||||
@@ -210,7 +214,7 @@ func (p *context) initLink(line string, prefix int, f func(inPkgName string) (fu
|
|||||||
} else {
|
} else {
|
||||||
panic(line + ": no specified call convention. eg. //go:linkname Printf C.printf")
|
panic(line + ": no specified call convention. eg. //go:linkname Printf C.printf")
|
||||||
}
|
}
|
||||||
} else {
|
} else if c := inPkgName[0]; c >= 'A' && c <= 'Z' {
|
||||||
fmt.Fprintln(os.Stderr, "==>", line)
|
fmt.Fprintln(os.Stderr, "==>", line)
|
||||||
fmt.Fprintf(os.Stderr, "llgo: linkname %s not found and ignored\n", inPkgName)
|
fmt.Fprintf(os.Stderr, "llgo: linkname %s not found and ignored\n", inPkgName)
|
||||||
}
|
}
|
||||||
@@ -303,6 +307,7 @@ const (
|
|||||||
ignoredFunc = iota
|
ignoredFunc = iota
|
||||||
goFunc = int(llssa.InGo)
|
goFunc = int(llssa.InGo)
|
||||||
cFunc = int(llssa.InC)
|
cFunc = int(llssa.InC)
|
||||||
|
pyFunc = int(llssa.InPython)
|
||||||
llgoInstr = -1
|
llgoInstr = -1
|
||||||
|
|
||||||
llgoInstrBase = 0x80
|
llgoInstrBase = 0x80
|
||||||
@@ -312,8 +317,8 @@ const (
|
|||||||
llgoAllocaCStr = llgoInstrBase + 3
|
llgoAllocaCStr = llgoInstrBase + 3
|
||||||
llgoAdvance = llgoInstrBase + 4
|
llgoAdvance = llgoInstrBase + 4
|
||||||
llgoIndex = llgoInstrBase + 5
|
llgoIndex = llgoInstrBase + 5
|
||||||
llgoBitCastTo32F = llgoInstrBase + 6
|
llgoStringData = llgoInstrBase + 6
|
||||||
llgoBitCastTo64F = llgoInstrBase + 7
|
llgoPyList = llgoInstrBase + 7
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) {
|
func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) {
|
||||||
@@ -339,6 +344,9 @@ func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, strin
|
|||||||
if strings.HasPrefix(v, "C.") {
|
if strings.HasPrefix(v, "C.") {
|
||||||
return nil, v[2:], cFunc
|
return nil, v[2:], cFunc
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(v, "py.") {
|
||||||
|
return pkg, v[3:], pyFunc
|
||||||
|
}
|
||||||
if strings.HasPrefix(v, "llgo.") {
|
if strings.HasPrefix(v, "llgo.") {
|
||||||
return nil, v[5:], llgoInstr
|
return nil, v[5:], llgoInstr
|
||||||
}
|
}
|
||||||
@@ -351,24 +359,35 @@ const (
|
|||||||
ignoredVar = iota
|
ignoredVar = iota
|
||||||
goVar = int(llssa.InGo)
|
goVar = int(llssa.InGo)
|
||||||
cVar = int(llssa.InC)
|
cVar = int(llssa.InC)
|
||||||
|
pyVar = int(llssa.InPython)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, vtype int) {
|
func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, vtype int) {
|
||||||
name := llssa.FullName(pkg, v.Name())
|
name := llssa.FullName(pkg, v.Name())
|
||||||
if v, ok := p.link[name]; ok {
|
if v, ok := p.link[name]; ok {
|
||||||
|
if strings.HasPrefix(v, "py.") {
|
||||||
|
return v[3:], pyVar
|
||||||
|
}
|
||||||
return v, cVar
|
return v, cVar
|
||||||
}
|
}
|
||||||
return name, goVar
|
return name, goVar
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) varOf(v *ssa.Global) (ret llssa.Global) {
|
func (p *context) varOf(b llssa.Builder, v *ssa.Global) llssa.Expr {
|
||||||
pkgTypes := p.ensureLoaded(v.Pkg.Pkg)
|
pkgTypes := p.ensureLoaded(v.Pkg.Pkg)
|
||||||
pkg := p.pkg
|
pkg := p.pkg
|
||||||
name, vtype := p.varName(pkgTypes, v)
|
name, vtype := p.varName(pkgTypes, v)
|
||||||
if ret = pkg.VarOf(name); ret == nil {
|
if vtype == pyVar {
|
||||||
|
if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule {
|
||||||
|
return b.PyNewVar(pysymPrefix+mod, name).Expr
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
ret := pkg.VarOf(name)
|
||||||
|
if ret == nil {
|
||||||
ret = pkg.NewVar(name, v.Type(), llssa.Background(vtype))
|
ret = pkg.NewVar(name, v.Type(), llssa.Background(vtype))
|
||||||
}
|
}
|
||||||
return
|
return ret.Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) ensureLoaded(pkgTypes *types.Package) *types.Package {
|
func (p *context) ensureLoaded(pkgTypes *types.Package) *types.Package {
|
||||||
@@ -391,3 +410,17 @@ func pkgKindByPath(pkgPath string) int {
|
|||||||
}
|
}
|
||||||
return PkgNormal
|
return PkgNormal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const (
|
||||||
|
pysymPrefix = "__llgo_py."
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *context) initPyModule() {
|
||||||
|
if kind, mod := pkgKindByScope(p.goTyps.Scope()); kind == PkgPyModule {
|
||||||
|
p.pyMod = mod
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -18,3 +18,5 @@ require (
|
|||||||
golang.org/x/mod v0.17.0 // indirect
|
golang.org/x/mod v0.17.0 // indirect
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
retract v0.8.0
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
wasm "github.com/aykevl/go-wasm"
|
wasm "github.com/aykevl/go-wasm"
|
||||||
"github.com/goplus/llgo/x/ar"
|
"github.com/goplus/llgo/xtool/ar"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create creates an arcive for static linking from a list of object files
|
// Create creates an arcive for static linking from a list of object files
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import (
|
|||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
|
|
||||||
"github.com/goplus/llgo/cl"
|
"github.com/goplus/llgo/cl"
|
||||||
"github.com/goplus/llgo/x/clang"
|
"github.com/goplus/llgo/xtool/clang"
|
||||||
|
|
||||||
llssa "github.com/goplus/llgo/ssa"
|
llssa "github.com/goplus/llgo/ssa"
|
||||||
)
|
)
|
||||||
@@ -120,18 +120,31 @@ func Do(args []string, conf *Config) {
|
|||||||
cl.SetDebug(cl.DbgFlagAll)
|
cl.SetDebug(cl.DbgFlagAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var needRt bool
|
||||||
var rt []*packages.Package
|
var rt []*packages.Package
|
||||||
prog := llssa.NewProgram(nil)
|
prog := llssa.NewProgram(nil)
|
||||||
prog.SetRuntime(func() *types.Package {
|
load := func() []*packages.Package {
|
||||||
rt, err = packages.Load(cfg, llssa.PkgRuntime)
|
if rt == nil {
|
||||||
|
var err error
|
||||||
|
rt, err = packages.Load(cfg, llssa.PkgRuntime, llssa.PkgPython)
|
||||||
check(err)
|
check(err)
|
||||||
|
}
|
||||||
|
return rt
|
||||||
|
}
|
||||||
|
prog.SetRuntime(func() *types.Package {
|
||||||
|
needRt = true
|
||||||
|
rt := load()
|
||||||
return rt[0].Types
|
return rt[0].Types
|
||||||
})
|
})
|
||||||
|
prog.SetPython(func() *types.Package {
|
||||||
|
rt := load()
|
||||||
|
return rt[1].Types
|
||||||
|
})
|
||||||
|
|
||||||
pkgs := buildAllPkgs(prog, initial, mode, verbose)
|
pkgs := buildAllPkgs(prog, initial, mode, verbose)
|
||||||
|
|
||||||
var runtimeFiles []string
|
var runtimeFiles []string
|
||||||
if rt != nil {
|
if needRt {
|
||||||
runtimeFiles = allLinkFiles(rt)
|
runtimeFiles = allLinkFiles(rt)
|
||||||
}
|
}
|
||||||
if mode != ModeBuild {
|
if mode != ModeBuild {
|
||||||
@@ -147,12 +160,22 @@ func Do(args []string, conf *Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNeedRuntime(pkg *packages.Package) {
|
func setNeedRuntimeOrPyInit(pkg *packages.Package, needRuntime, needPyInit bool) {
|
||||||
pkg.ID = "" // just use pkg.Module to mark it needs runtime
|
v := []byte{'0', '0'}
|
||||||
|
if needRuntime {
|
||||||
|
v[0] = '1'
|
||||||
|
}
|
||||||
|
if needPyInit {
|
||||||
|
v[1] = '1'
|
||||||
|
}
|
||||||
|
pkg.ID = string(v) // just use pkg.ID to mark it needs runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
func isNeedRuntime(pkg *packages.Package) bool {
|
func isNeedRuntimeOrPyInit(pkg *packages.Package) (needRuntime, needPyInit bool) {
|
||||||
return pkg.ID == ""
|
if len(pkg.ID) == 2 {
|
||||||
|
return pkg.ID[0] == '1', pkg.ID[1] == '1'
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, verbose bool) (pkgs []*aPackage) {
|
func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, verbose bool) (pkgs []*aPackage) {
|
||||||
@@ -172,28 +195,31 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
|
|||||||
// skip packages that only contain declarations
|
// skip packages that only contain declarations
|
||||||
// and set no export file
|
// and set no export file
|
||||||
pkg.ExportFile = ""
|
pkg.ExportFile = ""
|
||||||
case cl.PkgLinkIR:
|
case cl.PkgLinkIR, cl.PkgLinkExtern, cl.PkgPyModule:
|
||||||
// skip packages that don't need to be compiled but need to be linked
|
|
||||||
pkgPath := pkg.PkgPath
|
pkgPath := pkg.PkgPath
|
||||||
if isPkgInLLGo(pkgPath) {
|
if isPkgInLLGo(pkgPath) {
|
||||||
pkg.ExportFile = concatPkgLinkFiles(pkgPath)
|
pkg.ExportFile = concatPkgLinkFiles(pkgPath)
|
||||||
} else {
|
} else {
|
||||||
panic("todo")
|
// panic("todo")
|
||||||
|
// TODO(xsw): support packages out of llgo
|
||||||
|
pkg.ExportFile = ""
|
||||||
}
|
}
|
||||||
case cl.PkgLinkExtern:
|
if kind == cl.PkgLinkExtern { // need to be linked with external library
|
||||||
// skip packages that don't need to be compiled but need to be linked with external library
|
|
||||||
linkFile := os.ExpandEnv(strings.TrimSpace(param))
|
linkFile := os.ExpandEnv(strings.TrimSpace(param))
|
||||||
dir, lib := filepath.Split(linkFile)
|
dir, lib := filepath.Split(linkFile)
|
||||||
command := " -l " + lib
|
command := " -l " + lib
|
||||||
if dir != "" {
|
if dir != "" {
|
||||||
command += " -L " + dir
|
command += " -L " + dir
|
||||||
}
|
}
|
||||||
pkg.ExportFile = command
|
if isSingleLinkFile(pkg.ExportFile) {
|
||||||
|
pkg.ExportFile = command + " " + pkg.ExportFile
|
||||||
|
} else {
|
||||||
|
pkg.ExportFile = command + pkg.ExportFile
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
buildPkg(prog, aPkg, mode, verbose)
|
buildPkg(prog, aPkg, mode, verbose)
|
||||||
if prog.NeedRuntime() {
|
setNeedRuntimeOrPyInit(pkg, prog.NeedRuntime, prog.NeedPyInit)
|
||||||
setNeedRuntime(pkg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -212,27 +238,43 @@ func linkMainPkg(pkg *packages.Package, pkgs []*aPackage, runtimeFiles []string,
|
|||||||
args[1] = app
|
args[1] = app
|
||||||
args[2] = "-Wno-override-module"
|
args[2] = "-Wno-override-module"
|
||||||
needRuntime := false
|
needRuntime := false
|
||||||
|
needPyInit := false
|
||||||
packages.Visit([]*packages.Package{pkg}, nil, func(p *packages.Package) {
|
packages.Visit([]*packages.Package{pkg}, nil, func(p *packages.Package) {
|
||||||
if p.ExportFile != "" && !isRuntimePkg(p.PkgPath) { // skip packages that only contain declarations
|
if p.ExportFile != "" && !isRuntimePkg(p.PkgPath) { // skip packages that only contain declarations
|
||||||
args = appendLinkFiles(args, p.ExportFile)
|
args = appendLinkFiles(args, p.ExportFile)
|
||||||
|
need1, need2 := isNeedRuntimeOrPyInit(p)
|
||||||
if !needRuntime {
|
if !needRuntime {
|
||||||
needRuntime = isNeedRuntime(p)
|
needRuntime = need1
|
||||||
|
}
|
||||||
|
if !needPyInit {
|
||||||
|
needPyInit = need2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if needRuntime && runtimeFiles != nil {
|
|
||||||
args = append(args, runtimeFiles...)
|
var aPkg *aPackage
|
||||||
} else {
|
for _, v := range pkgs {
|
||||||
for _, aPkg := range pkgs {
|
if v.Package == pkg { // found this package
|
||||||
if aPkg.Package == pkg { // make empty runtime.init if no runtime needed
|
aPkg = v
|
||||||
lpkg := aPkg.LPkg
|
|
||||||
lpkg.FuncOf(cl.RuntimeInit).MakeBody(1).Return()
|
|
||||||
if needLLFile(mode) {
|
|
||||||
os.WriteFile(pkg.ExportFile, []byte(lpkg.String()), 0644)
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dirty := false
|
||||||
|
if needRuntime && runtimeFiles != nil {
|
||||||
|
args = append(args, runtimeFiles...)
|
||||||
|
} else {
|
||||||
|
dirty = true
|
||||||
|
fn := aPkg.LPkg.FuncOf(cl.RuntimeInit)
|
||||||
|
fn.MakeBody(1).Return()
|
||||||
|
}
|
||||||
|
if needPyInit {
|
||||||
|
dirty = aPkg.LPkg.PyInit()
|
||||||
|
}
|
||||||
|
|
||||||
|
if dirty && needLLFile(mode) {
|
||||||
|
lpkg := aPkg.LPkg
|
||||||
|
os.WriteFile(pkg.ExportFile, []byte(lpkg.String()), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
if verbose || mode != ModeRun {
|
if verbose || mode != ModeRun {
|
||||||
@@ -414,14 +456,14 @@ func llgoRoot() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendLinkFiles(args []string, file string) []string {
|
func appendLinkFiles(args []string, file string) []string {
|
||||||
if isMultiLinkFiles(file) {
|
if isSingleLinkFile(file) {
|
||||||
return append(args, strings.Split(file[1:], " ")...)
|
|
||||||
}
|
|
||||||
return append(args, file)
|
return append(args, file)
|
||||||
|
}
|
||||||
|
return append(args, strings.Split(file[1:], " ")...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isMultiLinkFiles(ret string) bool {
|
func isSingleLinkFile(ret string) bool {
|
||||||
return len(ret) > 0 && ret[0] == ' '
|
return len(ret) > 0 && ret[0] != ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
func concatPkgLinkFiles(pkgPath string) string {
|
func concatPkgLinkFiles(pkgPath string) string {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import (
|
|||||||
"golang.org/x/tools/go/ssa/ssautil"
|
"golang.org/x/tools/go/ssa/ssautil"
|
||||||
|
|
||||||
llssa "github.com/goplus/llgo/ssa"
|
llssa "github.com/goplus/llgo/ssa"
|
||||||
|
cpackages "golang.org/x/tools/go/packages"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -71,14 +72,17 @@ func Gen(pkgPath, inFile string, src any) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prog := llssa.NewProgram(nil)
|
prog := llssa.NewProgram(nil)
|
||||||
prog.SetRuntime(func() *types.Package {
|
initRtAndPy(prog, &cpackages.Config{
|
||||||
rt, err := imp.Import(llssa.PkgRuntime)
|
Mode: loadSyntax | cpackages.NeedDeps,
|
||||||
check(err)
|
|
||||||
return rt
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ret, err := cl.NewPackage(prog, ssaPkg, files)
|
ret, err := cl.NewPackage(prog, ssaPkg, files)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
|
if prog.NeedPyInit { // call PyInit if needed
|
||||||
|
ret.PyInit()
|
||||||
|
}
|
||||||
|
|
||||||
return ret.String()
|
return ret.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,27 @@ const (
|
|||||||
loadSyntax = loadTypes | packages.NeedSyntax | packages.NeedTypesInfo
|
loadSyntax = loadTypes | packages.NeedSyntax | packages.NeedTypesInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func initRtAndPy(prog llssa.Program, cfg *packages.Config) {
|
||||||
|
var pkgRtAndPy []*packages.Package
|
||||||
|
load := func() []*packages.Package {
|
||||||
|
if pkgRtAndPy == nil {
|
||||||
|
var err error
|
||||||
|
pkgRtAndPy, err = packages.Load(cfg, llssa.PkgRuntime, llssa.PkgPython)
|
||||||
|
check(err)
|
||||||
|
}
|
||||||
|
return pkgRtAndPy
|
||||||
|
}
|
||||||
|
|
||||||
|
prog.SetRuntime(func() *types.Package {
|
||||||
|
rt := load()
|
||||||
|
return rt[0].Types
|
||||||
|
})
|
||||||
|
prog.SetPython(func() *types.Package {
|
||||||
|
rt := load()
|
||||||
|
return rt[1].Types
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func GenFrom(fileOrPkg string) string {
|
func GenFrom(fileOrPkg string) string {
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: loadSyntax | packages.NeedDeps,
|
Mode: loadSyntax | packages.NeedDeps,
|
||||||
@@ -52,11 +73,7 @@ func GenFrom(fileOrPkg string) string {
|
|||||||
ssaPkg.Build()
|
ssaPkg.Build()
|
||||||
|
|
||||||
prog := llssa.NewProgram(nil)
|
prog := llssa.NewProgram(nil)
|
||||||
prog.SetRuntime(func() *types.Package {
|
initRtAndPy(prog, cfg)
|
||||||
rt, err := packages.Load(cfg, llssa.PkgRuntime)
|
|
||||||
check(err)
|
|
||||||
return rt[0].Types
|
|
||||||
})
|
|
||||||
|
|
||||||
if Verbose {
|
if Verbose {
|
||||||
ssaPkg.WriteTo(os.Stderr)
|
ssaPkg.WriteTo(os.Stderr)
|
||||||
@@ -65,6 +82,10 @@ func GenFrom(fileOrPkg string) string {
|
|||||||
ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax)
|
ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
|
if prog.NeedPyInit { // call PyInit if needed
|
||||||
|
ret.PyInit()
|
||||||
|
}
|
||||||
|
|
||||||
return ret.String()
|
return ret.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,8 +103,6 @@ func SmartDoFile(inFile string, pkgPath ...string) {
|
|||||||
fname := autgenFile
|
fname := autgenFile
|
||||||
if inCompilerDir(absDir) {
|
if inCompilerDir(absDir) {
|
||||||
fname = "out.ll"
|
fname = "out.ll"
|
||||||
} else if inSqlite(absDir) {
|
|
||||||
fname = "sqlite.ll"
|
|
||||||
}
|
}
|
||||||
outFile := dir + fname
|
outFile := dir + fname
|
||||||
|
|
||||||
@@ -108,7 +127,3 @@ func genZip(dir string, outFile, inFile string) {
|
|||||||
func inCompilerDir(dir string) bool {
|
func inCompilerDir(dir string) bool {
|
||||||
return strings.Contains(dir, "/llgo/cl/")
|
return strings.Contains(dir, "/llgo/cl/")
|
||||||
}
|
}
|
||||||
|
|
||||||
func inSqlite(dir string) bool {
|
|
||||||
return strings.HasSuffix(dir, "/llgo/x/sqlite")
|
|
||||||
}
|
|
||||||
|
|||||||
Binary file not shown.
40
internal/runtime/slice.go
Normal file
40
internal/runtime/slice.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
// nextslicecap computes the next appropriate slice length.
|
||||||
|
func nextslicecap(newLen, oldCap int) int {
|
||||||
|
newcap := oldCap
|
||||||
|
doublecap := newcap + newcap
|
||||||
|
if newLen > doublecap {
|
||||||
|
return newLen
|
||||||
|
}
|
||||||
|
|
||||||
|
const threshold = 256
|
||||||
|
if oldCap < threshold {
|
||||||
|
return doublecap
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
// Transition from growing 2x for small slices
|
||||||
|
// to growing 1.25x for large slices. This formula
|
||||||
|
// gives a smooth-ish transition between the two.
|
||||||
|
newcap += (newcap + 3*threshold) >> 2
|
||||||
|
|
||||||
|
// We need to check `newcap >= newLen` and whether `newcap` overflowed.
|
||||||
|
// newLen is guaranteed to be larger than zero, hence
|
||||||
|
// when newcap overflows then `uint(newcap) > uint(newLen)`.
|
||||||
|
// This allows to check for both with the same comparison.
|
||||||
|
if uint(newcap) >= uint(newLen) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set newcap to the requested cap when
|
||||||
|
// the newcap calculation overflowed.
|
||||||
|
if newcap <= 0 {
|
||||||
|
return newLen
|
||||||
|
}
|
||||||
|
return newcap
|
||||||
|
}
|
||||||
@@ -77,38 +77,18 @@ func CheckI2Int(v Interface, t *Type) (uintptr, bool) {
|
|||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func I2Float64(v Interface, t *Type) float64 {
|
func I2String(v Interface, t *Type) string {
|
||||||
if v.tab._type == t {
|
if v.tab._type == t {
|
||||||
return bitCastTo64F(uint64(uintptr(v.data)))
|
return *(*string)(v.data)
|
||||||
}
|
}
|
||||||
panic("I2Float64: type mismatch")
|
panic("I2String: type mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckI2Float64(v Interface, t *Type) (float64, bool) {
|
func CheckI2String(v Interface, t *Type) (string, bool) {
|
||||||
if v.tab._type == t {
|
if v.tab._type == t {
|
||||||
return bitCastTo64F(uint64(uintptr(v.data))), true
|
return *(*string)(v.data), true
|
||||||
}
|
}
|
||||||
return 0, false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
func I2Float32(v Interface, t *Type) float32 {
|
|
||||||
if v.tab._type == t {
|
|
||||||
return bitCastTo32F(uint32(uintptr(v.data)))
|
|
||||||
}
|
|
||||||
panic("I2Float32: type mismatch")
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckI2Float32(v Interface, t *Type) (float32, bool) {
|
|
||||||
if v.tab._type == t {
|
|
||||||
return bitCastTo32F(uint32(uintptr(v.data))), true
|
|
||||||
}
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:linkname bitCastTo64F llgo.bitCastTo64F
|
|
||||||
func bitCastTo64F(uint64) float64
|
|
||||||
|
|
||||||
//go:linkname bitCastTo32F llgo.bitCastTo32F
|
|
||||||
func bitCastTo32F(uint32) float32
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -70,4 +70,25 @@ func SliceData(s Slice) unsafe.Pointer {
|
|||||||
return s.data
|
return s.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SliceAppend append elem data and returns a slice.
|
||||||
|
func SliceAppend(src Slice, data unsafe.Pointer, num, etSize int) Slice {
|
||||||
|
if etSize == 0 {
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
oldLen := src.len
|
||||||
|
newLen := src.len + num
|
||||||
|
if newLen > src.cap {
|
||||||
|
newCap := nextslicecap(newLen, src.cap)
|
||||||
|
p := AllocZ(uintptr(newCap * etSize))
|
||||||
|
if oldLen != 0 {
|
||||||
|
c.Memcpy(p, src.data, uintptr(oldLen*etSize))
|
||||||
|
}
|
||||||
|
src.data = p
|
||||||
|
src.cap = newCap
|
||||||
|
}
|
||||||
|
src.len = newLen
|
||||||
|
c.Memcpy(c.Advance(src.data, oldLen*etSize), data, uintptr(num*etSize))
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -45,16 +45,6 @@ func NewString(data unsafe.Pointer, len int) String {
|
|||||||
return String{data, len}
|
return String{data, len}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringLen returns the length of a string.
|
|
||||||
func StringLen(s String) int {
|
|
||||||
return s.len
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringData returns the data pointer of a string.
|
|
||||||
func StringData(s String) unsafe.Pointer {
|
|
||||||
return s.data
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringCat concatenates two strings.
|
// StringCat concatenates two strings.
|
||||||
func StringCat(a, b String) String {
|
func StringCat(a, b String) String {
|
||||||
n := a.len + b.len
|
n := a.len + b.len
|
||||||
|
|||||||
33
py/README.md
Normal file
33
py/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
Linking Python to Go
|
||||||
|
=====
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Demo
|
||||||
|
|
||||||
|
The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it):
|
||||||
|
|
||||||
|
* [hellopy](_demo/hellopy/hello.go): link Python to Go and say `Hello world`
|
||||||
|
* [clpy](_demo/clpy/cleval.go): compile Python code and eval.
|
||||||
|
* [callpy](_demo/callpy/call.go): call Python standard library function `math.sqrt`.
|
||||||
|
|
||||||
|
### How to run demos
|
||||||
|
|
||||||
|
To run the demos in directory `_demo`, you need to set the `LLGO_LIB_PYTHON` environment variable first. Assuming you use Python 3.12, and the `libpython3.12.so` (or `libpython3.12.dylib` or `python3.12.lib`) file is in the /foo/bar directory, then you need to set `LLGO_LIB_PYTHON` to:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export LLGO_LIB_PYTHON=/foo/bar/python3.12
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python lib location under macOS. So we should set it like this:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can run the demos in directory `_demo`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd <demo-directory> # eg. cd _demo/hellopy
|
||||||
|
llgo run .
|
||||||
|
```
|
||||||
19
py/_demo/callpy/call.go
Normal file
19
py/_demo/callpy/call.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
py.Initialize()
|
||||||
|
py.SetProgramName(*c.Argv)
|
||||||
|
math := py.ImportModule(c.Str("math"))
|
||||||
|
sqrt := math.GetAttrString(c.Str("sqrt"))
|
||||||
|
sqrt2 := sqrt.CallOneArg(py.Float(2))
|
||||||
|
c.Printf(c.Str("sqrt(2) = %f\n"), sqrt2.Float64())
|
||||||
|
sqrt2.DecRef()
|
||||||
|
sqrt.DecRef()
|
||||||
|
math.DecRef()
|
||||||
|
py.Finalize()
|
||||||
|
}
|
||||||
23
py/_demo/clpy/cleval.go
Normal file
23
py/_demo/clpy/cleval.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
py.Initialize()
|
||||||
|
py.SetProgramName(*c.Argv)
|
||||||
|
code := py.CompileString(c.Str(`print('Hello, World!')`), c.Str(`hello.py`), py.EvalInput)
|
||||||
|
if code != nil {
|
||||||
|
mod := py.ImportModule(c.Str("__main__"))
|
||||||
|
gbl := mod.ModuleGetDict()
|
||||||
|
|
||||||
|
result := py.EvalCode(code, gbl, nil)
|
||||||
|
|
||||||
|
result.DecRef()
|
||||||
|
mod.DecRef()
|
||||||
|
code.DecRef()
|
||||||
|
}
|
||||||
|
py.Finalize()
|
||||||
|
}
|
||||||
13
py/_demo/hellopy/hello.go
Normal file
13
py/_demo/hellopy/hello.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
py.Initialize()
|
||||||
|
py.SetProgramName(*c.Argv)
|
||||||
|
py.RunSimpleString(c.Str(`print('Hello, World!')`))
|
||||||
|
py.Finalize()
|
||||||
|
}
|
||||||
49
py/_pyg/llpyg/llpyg.c
Normal file
49
py/_pyg/llpyg/llpyg.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef struct PyObject PyObject;
|
||||||
|
|
||||||
|
void Py_Initialize();
|
||||||
|
|
||||||
|
PyObject* PyImport_ImportModule(const char* modName);
|
||||||
|
PyObject* PyModule_GetDict(PyObject* mod);
|
||||||
|
PyObject* PyObject_Str(PyObject* obj);
|
||||||
|
PyObject* PyDict_Keys(PyObject* dict);
|
||||||
|
PyObject* PyList_GetItem(PyObject* list, size_t index);
|
||||||
|
PyObject* PyTuple_GetItem(PyObject* tuple, size_t index);
|
||||||
|
PyObject* PyObject_GetAttr(PyObject* mod, PyObject* attrName);
|
||||||
|
PyObject* PyObject_GetAttrString(PyObject* mod, const char* attrName);
|
||||||
|
PyObject* PyObject_CallOneArg(PyObject* fn, PyObject* arg);
|
||||||
|
|
||||||
|
const char* PyUnicode_AsUTF8(PyObject* str);
|
||||||
|
|
||||||
|
size_t PyList_Size(PyObject* list);
|
||||||
|
|
||||||
|
int PyCallable_Check(PyObject*);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Py_Initialize();
|
||||||
|
PyObject* inspect = PyImport_ImportModule("inspect");
|
||||||
|
PyObject* signature = PyObject_GetAttrString(inspect, "signature");
|
||||||
|
PyObject* mod = PyImport_ImportModule("numpy");
|
||||||
|
PyObject* dict = PyModule_GetDict(mod);
|
||||||
|
PyObject* keys = PyDict_Keys(dict);
|
||||||
|
size_t i, n;
|
||||||
|
n = PyList_Size(keys);
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
PyObject* key = PyList_GetItem(keys, i);
|
||||||
|
PyObject* val = PyObject_GetAttr(mod, key);
|
||||||
|
if (PyCallable_Check(val) != 0) {
|
||||||
|
PyObject* doc = PyObject_GetAttrString(val, "__doc__");
|
||||||
|
PyObject* sig = PyObject_CallOneArg(signature, val);
|
||||||
|
printf("-----------------------------------\n");
|
||||||
|
printf("sig: %p\n", sig);
|
||||||
|
printf("%s: %s\n", PyUnicode_AsUTF8(key), PyUnicode_AsUTF8(PyObject_Str(sig)));
|
||||||
|
printf("%s\n", PyUnicode_AsUTF8(key));
|
||||||
|
if (doc != NULL) {
|
||||||
|
printf("%s\n", PyUnicode_AsUTF8(doc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
53
py/_pyg/module.c
Normal file
53
py/_pyg/module.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// example:
|
||||||
|
// llgoLoadPyModSyms(mod, "name1", &func1, "name2", &func2, NULL)
|
||||||
|
|
||||||
|
typedef struct PyObject PyObject;
|
||||||
|
|
||||||
|
PyObject* PyObject_GetAttrString(PyObject* mod, const char* attrName);
|
||||||
|
|
||||||
|
void llgoLoadPyModSyms(PyObject* mod, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, mod);
|
||||||
|
for (;;) {
|
||||||
|
const char* name = va_arg(ap, const char*);
|
||||||
|
if (name == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
PyObject** pfunc = va_arg(ap, PyObject**);
|
||||||
|
if (*pfunc == NULL) {
|
||||||
|
*pfunc = PyObject_GetAttrString(mod, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
wchar_t* toWcs(const char* str) {
|
||||||
|
size_t len = mbstowcs(NULL, str, 0);
|
||||||
|
wchar_t* wstr = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
|
||||||
|
mbstowcs(wstr, str, len + 1);
|
||||||
|
return wstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* toMbs(const wchar_t* str) {
|
||||||
|
size_t len = wcstombs(NULL, str, 0);
|
||||||
|
char* mstr = (char*)malloc(len + 1);
|
||||||
|
wcstombs(mstr, str, len + 1);
|
||||||
|
return mstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t *Py_GetPath();
|
||||||
|
|
||||||
|
void Py_SetPath(const wchar_t* path);
|
||||||
|
void Py_Initialize();
|
||||||
|
|
||||||
|
void llgoPyInitialize() {
|
||||||
|
setenv("PYTHONPATH", "/opt/homebrew/lib/python3.12/site-packages", 1);
|
||||||
|
Py_Initialize();
|
||||||
|
printf("sys.path = %s\n", toMbs(Py_GetPath()));
|
||||||
|
}
|
||||||
|
*/
|
||||||
33
py/arg.go
Normal file
33
py/arg.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/arg.html
|
||||||
|
|
||||||
|
// Create a new value based on a format string similar to those accepted by the
|
||||||
|
// PyArg_Parse* family of functions and a sequence of values. Returns the value or
|
||||||
|
// nil in the case of an error; an exception will be raised if nil is returned.
|
||||||
|
// See https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
|
||||||
|
//
|
||||||
|
//go:linkname BuildValue C.Py_BuildValue
|
||||||
|
func BuildValue(format *c.Char, __llgo_va_list ...any) *Object
|
||||||
61
py/builtins/builtins.go
Normal file
61
py/builtins/builtins.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package builtins
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "py.inspect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/library/functions.html
|
||||||
|
// https://docs.python.org/3/library/constants.html
|
||||||
|
|
||||||
|
// print(*objects, sep=' ', end='\n', file=None, flush=False)
|
||||||
|
//
|
||||||
|
// Print objects to the text stream file, separated by sep and followed by
|
||||||
|
// end. sep, end, file, and flush, if present, must be given as keyword
|
||||||
|
// arguments.
|
||||||
|
//
|
||||||
|
// All non-keyword arguments are converted to strings like str() does and
|
||||||
|
// written to the stream, separated by sep and followed by end. Both sep
|
||||||
|
// and end must be strings; they can also be None, which means to use the
|
||||||
|
// default values. If no objects are given, print() will just write end.
|
||||||
|
//
|
||||||
|
//go:linkname Print py.print
|
||||||
|
func Print(objects ...*py.Object)
|
||||||
|
|
||||||
|
//go:linkname PrintEx py.print
|
||||||
|
func PrintEx(__llgo_kwargs *py.Object, objects ...*py.Object)
|
||||||
|
|
||||||
|
// Invoke the built-in help system. (This function is intended for interactive
|
||||||
|
// use.) If no argument is given, the interactive help system starts on the
|
||||||
|
// interpreter console. If the argument is a string, then the string is looked
|
||||||
|
// up as the name of a module, function, class, method, keyword, or documentation
|
||||||
|
// topic, and a help page is printed on the console. If the argument is any other
|
||||||
|
// kind of object, a help page on the object is generated.
|
||||||
|
//
|
||||||
|
// Note that if a slash(/) appears in the parameter list of a function when invoking
|
||||||
|
// help(), it means that the parameters prior to the slash are positional-only. For
|
||||||
|
// more info, see the FAQ entry on positional-only parameters.
|
||||||
|
//
|
||||||
|
//go:linkname Help py.help
|
||||||
|
func Help(object *py.Object)
|
||||||
BIN
py/builtins/llgo_autogen.lla
Normal file
BIN
py/builtins/llgo_autogen.lla
Normal file
Binary file not shown.
50
py/bytes.go
Normal file
50
py/bytes.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/bytes.html
|
||||||
|
|
||||||
|
// String returns a new bytes object from a C string.
|
||||||
|
//
|
||||||
|
//go:linkname FromCStr C.PyBytes_FromString
|
||||||
|
func FromCStr(s *c.Char) *Object
|
||||||
|
|
||||||
|
// FromString returns a new bytes object from a Go string.
|
||||||
|
func FromString(s string) *Object {
|
||||||
|
return stringFromStringAndSize(c.GoStringData(s), uintptr(len(s)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname stringFromStringAndSize C.PyBytes_FromStringAndSize
|
||||||
|
func stringFromStringAndSize(s *c.Char, size uintptr) *Object
|
||||||
|
|
||||||
|
// CStr returns the content of a bytes object as a C string.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CStr C.PyBytes_AsString
|
||||||
|
func (o *Object) CStr() *c.Char { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*Object).Strlen C.PyBytes_Size
|
||||||
|
func (o *Object) Strlen() uintptr { return 0 }
|
||||||
|
|
||||||
|
*/
|
||||||
131
py/call.go
Normal file
131
py/call.go
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/call.html
|
||||||
|
|
||||||
|
// Determine if the object o is callable. Return 1 if the object is callable and
|
||||||
|
// 0 otherwise. This function always succeeds.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).Callable C.PyCallable_Check
|
||||||
|
func (o *Object) Callable() c.Int { return 0 }
|
||||||
|
|
||||||
|
// Call a callable Python object o, with arguments given by the tuple args, and
|
||||||
|
// named arguments given by the dictionary kwargs.
|
||||||
|
//
|
||||||
|
// args must not be nil; use an empty tuple if no arguments are needed. If no named
|
||||||
|
// arguments are needed, kwargs can be nil.
|
||||||
|
//
|
||||||
|
// Return the result of the call on success, or raise an exception and return nil
|
||||||
|
// on failure.
|
||||||
|
//
|
||||||
|
// This is the equivalent of the Python expression: o(*args, **kwargs).
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).Call C.PyObject_Call
|
||||||
|
func (o *Object) Call(args, kwargs *Object) *Object { return nil }
|
||||||
|
|
||||||
|
// Call a callable Python object callable without any arguments. It is the most
|
||||||
|
// efficient way to call a callable Python object without any argument.
|
||||||
|
//
|
||||||
|
// Return the result of the call on success, or raise an exception and return nil
|
||||||
|
// on failure.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CallNoArgs C.PyObject_CallNoArgs
|
||||||
|
func (o *Object) CallNoArgs() *Object { return nil }
|
||||||
|
|
||||||
|
// Call a callable Python object callable with exactly 1 positional argument arg
|
||||||
|
// and no keyword arguments.
|
||||||
|
//
|
||||||
|
// Return the result of the call on success, or raise an exception and return nil
|
||||||
|
// on failure.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CallOneArg C.PyObject_CallOneArg
|
||||||
|
func (o *Object) CallOneArg(arg *Object) *Object { return nil }
|
||||||
|
|
||||||
|
// Call a callable Python object o, with arguments given by the tuple args. If no
|
||||||
|
// arguments are needed, then args can be nil.
|
||||||
|
//
|
||||||
|
// Return the result of the call on success, or raise an exception and return nil
|
||||||
|
// on failure.
|
||||||
|
//
|
||||||
|
// This is the equivalent of the Python expression: o(*args).
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CallObject C.PyObject_CallObject
|
||||||
|
func (o *Object) CallObject(args *Object) *Object { return nil }
|
||||||
|
|
||||||
|
// Call a callable Python object o, with a variable number of C arguments. The C
|
||||||
|
// arguments are described using a py.BuildValue style format string. The format
|
||||||
|
// can be nil, indicating that no arguments are provided.
|
||||||
|
//
|
||||||
|
// Return the result of the call on success, or raise an exception and return nil
|
||||||
|
// on failure.
|
||||||
|
//
|
||||||
|
// This is the equivalent of the Python expression: o(*args).
|
||||||
|
//
|
||||||
|
// Note that if you only pass PyObject* args, (*Object).CallFunctionObjArgs is a
|
||||||
|
// faster alternative.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CallFunction C.PyObject_CallFunction
|
||||||
|
func (o *Object) CallFunction(format *c.Char, __llgo_va_list ...any) *Object { return nil }
|
||||||
|
|
||||||
|
// Call a callable Python object o, with a variable number of PyObject* arguments.
|
||||||
|
// The arguments are provided as a variable number of parameters followed by nil.
|
||||||
|
//
|
||||||
|
// Return the result of the call on success, or raise an exception and return nil
|
||||||
|
// on failure.
|
||||||
|
//
|
||||||
|
// This is the equivalent of the Python expression: o(arg1, arg2, ...).
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CallFunctionObjArgs C.PyObject_CallFunctionObjArgs
|
||||||
|
func (o *Object) CallFunctionObjArgs(__llgo_va_list ...any) *Object { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*Object).CallMethod C.PyObject_CallMethod
|
||||||
|
func (o *Object) CallMethod(name *c.Char, format *c.Char, __llgo_va_list ...any) *Object {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Object).CallMethodObjArgs C.PyObject_CallMethodObjArgs
|
||||||
|
func (o *Object) CallMethodObjArgs(name *Object, __llgo_va_list ...any) *Object { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*Object).CallMethodNoArgs C.PyObject_CallMethodNoArgs
|
||||||
|
func (o *Object) CallMethodNoArgs(name *Object) *Object { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*Object).CallMethodOneArg C.PyObject_CallMethodOneArg
|
||||||
|
func (o *Object) CallMethodOneArg(name, arg *Object) *Object { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*Object).Vectorcall C.PyObject_Vectorcall
|
||||||
|
func (o *Object) Vectorcall(args **Object, nargs uintptr, kwnames *Object) *Object {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Object).VectorcallDict C.PyObject_VectorcallDict
|
||||||
|
func (o *Object) VectorcallDict(args **Object, nargs uintptr, kwdict *Object) *Object {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Object).VectorcallMethod C.PyObject_VectorcallMethod
|
||||||
|
func (o *Object) VectorcallMethod(name *Object, args **Object, nargs uintptr, kwnames *Object) *Object {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
41
py/code.go
Normal file
41
py/code.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/code.html
|
||||||
|
|
||||||
|
// Equivalent to the Python code getattr(co, 'co_code'). Returns a strong
|
||||||
|
// reference to a BytesObject representing the bytecode in a code object.
|
||||||
|
// On error, nil is returned and an exception is raised.
|
||||||
|
//
|
||||||
|
// This BytesObject may be created on-demand by the interpreter and does
|
||||||
|
// not necessarily represent the bytecode actually executed by CPython.
|
||||||
|
// The primary use case for this function is debuggers and profilers.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CodeBytes C.PyCode_GetCode
|
||||||
|
func (o *Object) CodeBytes() *Object { return nil }
|
||||||
|
|
||||||
|
// Equivalent to the Python code getattr(co, 'co_varnames'). Returns a new
|
||||||
|
// reference to a TupleObject containing the names of the local variables.
|
||||||
|
// On error, nil is returned and an exception is raised.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).CodeVarnames C.PyCode_GetVarnames
|
||||||
|
func (o *Object) CodeVarnames() *Object { return nil }
|
||||||
45
py/dict.go
Normal file
45
py/dict.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/dict.html
|
||||||
|
|
||||||
|
// Return a new empty dictionary, or nil on failure.
|
||||||
|
//
|
||||||
|
//go:linkname NewDict C.PyDict_New
|
||||||
|
func NewDict() *Object
|
||||||
|
|
||||||
|
// Return a ListObject containing all the keys from the dictionary.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).DictKeys C.PyDict_Keys
|
||||||
|
func (d *Object) DictKeys() *Object { return nil }
|
||||||
|
|
||||||
|
// Return a ListObject containing all the values from the dictionary.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).DictValues C.PyDict_Values
|
||||||
|
func (d *Object) DictValues() *Object { return nil }
|
||||||
|
|
||||||
|
// Return a ListObject containing all the items from the dictionary.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).DictItems C.PyDict_Items
|
||||||
|
func (d *Object) DictItems() *Object { return nil }
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
32
py/exceptions.go
Normal file
32
py/exceptions.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/exceptions.html
|
||||||
|
|
||||||
|
// Clear the error indicator. If the error indicator is not set, there is
|
||||||
|
// no effect.
|
||||||
|
//
|
||||||
|
//go:linkname ErrClear C.PyErr_Clear
|
||||||
|
func ErrClear()
|
||||||
|
|
||||||
|
//go:linkname ErrPrint C.PyErr_Print
|
||||||
|
func ErrPrint()
|
||||||
32
py/float.go
Normal file
32
py/float.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/float.html
|
||||||
|
|
||||||
|
//go:linkname Float C.PyFloat_FromDouble
|
||||||
|
func Float(v float64) *Object
|
||||||
|
|
||||||
|
//go:linkname FloatFromSring C.PyFloat_FromString
|
||||||
|
func FloatFromSring(v *Object) *Object
|
||||||
|
|
||||||
|
// llgo:link (*Object).Float64 C.PyFloat_AsDouble
|
||||||
|
func (o *Object) Float64() float64 { return 0 }
|
||||||
56
py/func.go
Normal file
56
py/func.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/function.html
|
||||||
|
|
||||||
|
// Return a new function object associated with the code object code.
|
||||||
|
// globals must be a dictionary with the global variables accessible
|
||||||
|
// to the function.
|
||||||
|
//
|
||||||
|
// The function’s docstring and name are retrieved from the code object.
|
||||||
|
// __module__ is retrieved from globals. The argument defaults, annotations
|
||||||
|
// and closure are set to nil. __qualname__ is set to the same value as
|
||||||
|
// the code object’s co_qualname field.
|
||||||
|
//
|
||||||
|
//go:linkname NewFunc C.PyFunction_New
|
||||||
|
func NewFunc(code, globals *Object) *Object
|
||||||
|
|
||||||
|
// As NewFunc, but also allows setting the function object’s __qualname__
|
||||||
|
// attribute. qualname should be a unicode object or nil; if nil, the
|
||||||
|
// __qualname__ attribute is set to the same value as the code object’s
|
||||||
|
// co_qualname field.
|
||||||
|
//
|
||||||
|
//go:linkname NewFuncWithQualName C.PyFunction_NewWithQualName
|
||||||
|
func NewFuncWithQualName(code, globals, qualname *Object) *Object
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Return true if o is a function object (has type PyFunction_Type). The
|
||||||
|
// parameter must not be nil. This function always succeeds.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).FuncCheck C.PyFunction_Check
|
||||||
|
func (o *Object) FuncCheck() c.Int { return 0 }
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Return the code object associated with the function object op.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).FuncCode C.PyFunction_GetCode
|
||||||
|
func (f *Object) FuncCode() *Object { return nil }
|
||||||
14
py/inspect/doc.txt
Normal file
14
py/inspect/doc.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// https://docs.python.org/3/library/inspect.html
|
||||||
|
|
||||||
|
// Return a signature object for the given callable.
|
||||||
|
//
|
||||||
|
//go:linkname Signature py.signature
|
||||||
|
func Signature(callable *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the names and default values of a Python function’s parameters. A named
|
||||||
|
// tuple is returned:
|
||||||
|
//
|
||||||
|
// FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)
|
||||||
|
//
|
||||||
|
//go:linkname Getfullargspec py.getfullargspec
|
||||||
|
func Getfullargspec(f *py.Object) *py.Object
|
||||||
617
py/inspect/gen.go
Normal file
617
py/inspect/gen.go
Normal file
@@ -0,0 +1,617 @@
|
|||||||
|
package inspect
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LLGoPackage = "py.inspect"
|
||||||
|
|
||||||
|
// Compute the annotations dict for an object.
|
||||||
|
//
|
||||||
|
// obj may be a callable, class, or module.
|
||||||
|
// Passing in an object of any other type raises TypeError.
|
||||||
|
//
|
||||||
|
// Returns a dict. get_annotations() returns a new dict every time
|
||||||
|
// it's called; calling it twice on the same object will return two
|
||||||
|
// different but equivalent dicts.
|
||||||
|
//
|
||||||
|
// This function handles several details for you:
|
||||||
|
//
|
||||||
|
// * If eval_str is true, values of type str will
|
||||||
|
// be un-stringized using eval(). This is intended
|
||||||
|
// for use with stringized annotations
|
||||||
|
// ("from __future__ import annotations").
|
||||||
|
// * If obj doesn't have an annotations dict, returns an
|
||||||
|
// empty dict. (Functions and methods always have an
|
||||||
|
// annotations dict; classes, modules, and other types of
|
||||||
|
// callables may not.)
|
||||||
|
// * Ignores inherited annotations on classes. If a class
|
||||||
|
// doesn't have its own annotations dict, returns an empty dict.
|
||||||
|
// * All accesses to object members and dict values are done
|
||||||
|
// using getattr() and dict.get() for safety.
|
||||||
|
// * Always, always, always returns a freshly-created dict.
|
||||||
|
//
|
||||||
|
// eval_str controls whether or not values of type str are replaced
|
||||||
|
// with the result of calling eval() on those values:
|
||||||
|
//
|
||||||
|
// * If eval_str is true, eval() is called on values of type str.
|
||||||
|
// * If eval_str is false (the default), values of type str are unchanged.
|
||||||
|
//
|
||||||
|
// globals and locals are passed in to eval(); see the documentation
|
||||||
|
// for eval() for more information. If either globals or locals is
|
||||||
|
// None, this function may replace that value with a context-specific
|
||||||
|
// default, contingent on type(obj):
|
||||||
|
//
|
||||||
|
// * If obj is a module, globals defaults to obj.__dict__.
|
||||||
|
// * If obj is a class, globals defaults to
|
||||||
|
// sys.modules[obj.__module__].__dict__ and locals
|
||||||
|
// defaults to the obj class namespace.
|
||||||
|
// * If obj is a callable, globals defaults to obj.__globals__,
|
||||||
|
// although if obj is a wrapped function (using
|
||||||
|
// functools.update_wrapper()) it is first unwrapped.
|
||||||
|
//
|
||||||
|
//go:linkname GetAnnotations py.get_annotations
|
||||||
|
func GetAnnotations(obj *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a module.
|
||||||
|
//
|
||||||
|
//go:linkname Ismodule py.ismodule
|
||||||
|
func Ismodule(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a class.
|
||||||
|
//
|
||||||
|
//go:linkname Isclass py.isclass
|
||||||
|
func Isclass(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is an instance method.
|
||||||
|
//
|
||||||
|
//go:linkname Ismethod py.ismethod
|
||||||
|
func Ismethod(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a method descriptor.
|
||||||
|
//
|
||||||
|
// But not if ismethod() or isclass() or isfunction() are true.
|
||||||
|
//
|
||||||
|
// This is new in Python 2.2, and, for example, is true of int.__add__.
|
||||||
|
// An object passing this test has a __get__ attribute but not a __set__
|
||||||
|
// attribute, but beyond that the set of attributes varies. __name__ is
|
||||||
|
// usually sensible, and __doc__ often is.
|
||||||
|
//
|
||||||
|
// Methods implemented via descriptors that also pass one of the other
|
||||||
|
// tests return false from the ismethoddescriptor() test, simply because
|
||||||
|
// the other tests promise more -- you can, e.g., count on having the
|
||||||
|
// __func__ attribute (etc) when an object passes ismethod().
|
||||||
|
//
|
||||||
|
//go:linkname Ismethoddescriptor py.ismethoddescriptor
|
||||||
|
func Ismethoddescriptor(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a data descriptor.
|
||||||
|
//
|
||||||
|
// Data descriptors have a __set__ or a __delete__ attribute. Examples are
|
||||||
|
// properties (defined in Python) and getsets and members (defined in C).
|
||||||
|
// Typically, data descriptors will also have __name__ and __doc__ attributes
|
||||||
|
// (properties, getsets, and members have both of these attributes), but this
|
||||||
|
// is not guaranteed.
|
||||||
|
//
|
||||||
|
//go:linkname Isdatadescriptor py.isdatadescriptor
|
||||||
|
func Isdatadescriptor(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a member descriptor.
|
||||||
|
//
|
||||||
|
// Member descriptors are specialized descriptors defined in extension
|
||||||
|
// modules.
|
||||||
|
//
|
||||||
|
//go:linkname Ismemberdescriptor py.ismemberdescriptor
|
||||||
|
func Ismemberdescriptor(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a getset descriptor.
|
||||||
|
//
|
||||||
|
// getset descriptors are specialized descriptors defined in extension
|
||||||
|
// modules.
|
||||||
|
//
|
||||||
|
//go:linkname Isgetsetdescriptor py.isgetsetdescriptor
|
||||||
|
func Isgetsetdescriptor(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a user-defined function.
|
||||||
|
//
|
||||||
|
// Function objects provide these attributes:
|
||||||
|
// __doc__ documentation string
|
||||||
|
// __name__ name with which this function was defined
|
||||||
|
// __code__ code object containing compiled function bytecode
|
||||||
|
// __defaults__ tuple of any default values for arguments
|
||||||
|
// __globals__ global namespace in which this function was defined
|
||||||
|
// __annotations__ dict of parameter annotations
|
||||||
|
// __kwdefaults__ dict of keyword only parameters with defaults
|
||||||
|
//
|
||||||
|
//go:linkname Isfunction py.isfunction
|
||||||
|
func Isfunction(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a user-defined generator function.
|
||||||
|
//
|
||||||
|
// Generator function objects provide the same attributes as functions.
|
||||||
|
// See help(isfunction) for a list of attributes.
|
||||||
|
//
|
||||||
|
//go:linkname Isgeneratorfunction py.isgeneratorfunction
|
||||||
|
func Isgeneratorfunction(obj *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Decorator to ensure callable is recognised as a coroutine function.
|
||||||
|
//
|
||||||
|
//go:linkname Markcoroutinefunction py.markcoroutinefunction
|
||||||
|
func Markcoroutinefunction(func_ *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a coroutine function.
|
||||||
|
//
|
||||||
|
// Coroutine functions are normally defined with "async def" syntax, but may
|
||||||
|
// be marked via markcoroutinefunction.
|
||||||
|
//
|
||||||
|
//go:linkname Iscoroutinefunction py.iscoroutinefunction
|
||||||
|
func Iscoroutinefunction(obj *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is an asynchronous generator function.
|
||||||
|
//
|
||||||
|
// Asynchronous generator functions are defined with "async def"
|
||||||
|
// syntax and have "yield" expressions in their body.
|
||||||
|
//
|
||||||
|
//go:linkname Isasyncgenfunction py.isasyncgenfunction
|
||||||
|
func Isasyncgenfunction(obj *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is an asynchronous generator.
|
||||||
|
//
|
||||||
|
//go:linkname Isasyncgen py.isasyncgen
|
||||||
|
func Isasyncgen(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a generator.
|
||||||
|
//
|
||||||
|
// Generator objects provide these attributes:
|
||||||
|
// __iter__ defined to support iteration over container
|
||||||
|
// close raises a new GeneratorExit exception inside the
|
||||||
|
// generator to terminate the iteration
|
||||||
|
// gi_code code object
|
||||||
|
// gi_frame frame object or possibly None once the generator has
|
||||||
|
// been exhausted
|
||||||
|
// gi_running set to 1 when generator is executing, 0 otherwise
|
||||||
|
// next return the next item from the container
|
||||||
|
// send resumes the generator and "sends" a value that becomes
|
||||||
|
// the result of the current yield-expression
|
||||||
|
// throw used to raise an exception inside the generator
|
||||||
|
//
|
||||||
|
//go:linkname Isgenerator py.isgenerator
|
||||||
|
func Isgenerator(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a coroutine.
|
||||||
|
//
|
||||||
|
//go:linkname Iscoroutine py.iscoroutine
|
||||||
|
func Iscoroutine(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if object can be passed to an “await“ expression.
|
||||||
|
//
|
||||||
|
//go:linkname Isawaitable py.isawaitable
|
||||||
|
func Isawaitable(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a traceback.
|
||||||
|
//
|
||||||
|
// Traceback objects provide these attributes:
|
||||||
|
// tb_frame frame object at this level
|
||||||
|
// tb_lasti index of last attempted instruction in bytecode
|
||||||
|
// tb_lineno current line number in Python source code
|
||||||
|
// tb_next next inner traceback object (called by this level)
|
||||||
|
//
|
||||||
|
//go:linkname Istraceback py.istraceback
|
||||||
|
func Istraceback(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a frame object.
|
||||||
|
//
|
||||||
|
// Frame objects provide these attributes:
|
||||||
|
// f_back next outer frame object (this frame's caller)
|
||||||
|
// f_builtins built-in namespace seen by this frame
|
||||||
|
// f_code code object being executed in this frame
|
||||||
|
// f_globals global namespace seen by this frame
|
||||||
|
// f_lasti index of last attempted instruction in bytecode
|
||||||
|
// f_lineno current line number in Python source code
|
||||||
|
// f_locals local namespace seen by this frame
|
||||||
|
// f_trace tracing function for this frame, or None
|
||||||
|
//
|
||||||
|
//go:linkname Isframe py.isframe
|
||||||
|
func Isframe(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a code object.
|
||||||
|
//
|
||||||
|
// Code objects provide these attributes:
|
||||||
|
// co_argcount number of arguments (not including *, ** args
|
||||||
|
// or keyword only arguments)
|
||||||
|
// co_code string of raw compiled bytecode
|
||||||
|
// co_cellvars tuple of names of cell variables
|
||||||
|
// co_consts tuple of constants used in the bytecode
|
||||||
|
// co_filename name of file in which this code object was created
|
||||||
|
// co_firstlineno number of first line in Python source code
|
||||||
|
// co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
|
||||||
|
// | 16=nested | 32=generator | 64=nofree | 128=coroutine
|
||||||
|
// | 256=iterable_coroutine | 512=async_generator
|
||||||
|
// co_freevars tuple of names of free variables
|
||||||
|
// co_posonlyargcount number of positional only arguments
|
||||||
|
// co_kwonlyargcount number of keyword only arguments (not including ** arg)
|
||||||
|
// co_lnotab encoded mapping of line numbers to bytecode indices
|
||||||
|
// co_name name with which this code object was defined
|
||||||
|
// co_names tuple of names other than arguments and function locals
|
||||||
|
// co_nlocals number of local variables
|
||||||
|
// co_stacksize virtual machine stack space required
|
||||||
|
// co_varnames tuple of names of arguments and local variables
|
||||||
|
//
|
||||||
|
//go:linkname Iscode py.iscode
|
||||||
|
func Iscode(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a built-in function or method.
|
||||||
|
//
|
||||||
|
// Built-in functions and methods provide these attributes:
|
||||||
|
// __doc__ documentation string
|
||||||
|
// __name__ original name of this function or method
|
||||||
|
// __self__ instance to which a method is bound, or None
|
||||||
|
//
|
||||||
|
//go:linkname Isbuiltin py.isbuiltin
|
||||||
|
func Isbuiltin(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is a method wrapper.
|
||||||
|
//
|
||||||
|
//go:linkname Ismethodwrapper py.ismethodwrapper
|
||||||
|
func Ismethodwrapper(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is any kind of function or method.
|
||||||
|
//
|
||||||
|
//go:linkname Isroutine py.isroutine
|
||||||
|
func Isroutine(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return true if the object is an abstract base class (ABC).
|
||||||
|
//
|
||||||
|
//go:linkname Isabstract py.isabstract
|
||||||
|
func Isabstract(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return all members of an object as (name, value) pairs sorted by name.
|
||||||
|
//
|
||||||
|
// Optionally, only return members that satisfy a given predicate.
|
||||||
|
//
|
||||||
|
//go:linkname Getmembers py.getmembers
|
||||||
|
func Getmembers(object *py.Object, predicate *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return all members of an object as (name, value) pairs sorted by name
|
||||||
|
//
|
||||||
|
// without triggering dynamic lookup via the descriptor protocol,
|
||||||
|
// __getattr__ or __getattribute__. Optionally, only return members that
|
||||||
|
// satisfy a given predicate.
|
||||||
|
//
|
||||||
|
// Note: this function may not be able to retrieve all members
|
||||||
|
// that getmembers can fetch (like dynamically created attributes)
|
||||||
|
// and may find members that getmembers can't (like descriptors
|
||||||
|
// that raise AttributeError). It can also return descriptor objects
|
||||||
|
// instead of instance members in some cases.
|
||||||
|
//
|
||||||
|
//go:linkname GetmembersStatic py.getmembers_static
|
||||||
|
func GetmembersStatic(object *py.Object, predicate *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return list of attribute-descriptor tuples.
|
||||||
|
//
|
||||||
|
// For each name in dir(cls), the return list contains a 4-tuple
|
||||||
|
// with these elements:
|
||||||
|
//
|
||||||
|
// 0. The name (a string).
|
||||||
|
//
|
||||||
|
// 1. The kind of attribute this is, one of these strings:
|
||||||
|
// 'class method' created via classmethod()
|
||||||
|
// 'static method' created via staticmethod()
|
||||||
|
// 'property' created via property()
|
||||||
|
// 'method' any other flavor of method or descriptor
|
||||||
|
// 'data' not a method
|
||||||
|
//
|
||||||
|
// 2. The class which defined this attribute (a class).
|
||||||
|
//
|
||||||
|
// 3. The object as obtained by calling getattr; if this fails, or if the
|
||||||
|
// resulting object does not live anywhere in the class' mro (including
|
||||||
|
// metaclasses) then the object is looked up in the defining class's
|
||||||
|
// dict (found by walking the mro).
|
||||||
|
//
|
||||||
|
// If one of the items in dir(cls) is stored in the metaclass it will now
|
||||||
|
// be discovered and not have None be listed as the class in which it was
|
||||||
|
// defined. Any items whose home class cannot be discovered are skipped.
|
||||||
|
//
|
||||||
|
//go:linkname ClassifyClassAttrs py.classify_class_attrs
|
||||||
|
func ClassifyClassAttrs(cls *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return tuple of base classes (including cls) in method resolution order.
|
||||||
|
//
|
||||||
|
//go:linkname Getmro py.getmro
|
||||||
|
func Getmro(cls *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the object wrapped by *func*.
|
||||||
|
//
|
||||||
|
// Follows the chain of :attr:`__wrapped__` attributes returning the last
|
||||||
|
// object in the chain.
|
||||||
|
//
|
||||||
|
// *stop* is an optional callback accepting an object in the wrapper chain
|
||||||
|
// as its sole argument that allows the unwrapping to be terminated early if
|
||||||
|
// the callback returns a true value. If the callback never returns a true
|
||||||
|
// value, the last object in the chain is returned as usual. For example,
|
||||||
|
// :func:`signature` uses this to stop unwrapping if any object in the
|
||||||
|
// chain has a ``__signature__`` attribute defined.
|
||||||
|
//
|
||||||
|
// :exc:`ValueError` is raised if a cycle is encountered.
|
||||||
|
//
|
||||||
|
//go:linkname Unwrap py.unwrap
|
||||||
|
func Unwrap(func_ *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the indent size, in spaces, at the start of a line of text.
|
||||||
|
//
|
||||||
|
//go:linkname Indentsize py.indentsize
|
||||||
|
func Indentsize(line *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the documentation string for an object.
|
||||||
|
//
|
||||||
|
// All tabs are expanded to spaces. To clean up docstrings that are
|
||||||
|
// indented to line up with blocks of code, any whitespace than can be
|
||||||
|
// uniformly removed from the second line onwards is removed.
|
||||||
|
//
|
||||||
|
//go:linkname Getdoc py.getdoc
|
||||||
|
func Getdoc(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Clean up indentation from docstrings.
|
||||||
|
//
|
||||||
|
// Any whitespace that can be uniformly removed from the second line
|
||||||
|
// onwards is removed.
|
||||||
|
//
|
||||||
|
//go:linkname Cleandoc py.cleandoc
|
||||||
|
func Cleandoc(doc *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Work out which source or compiled file an object was defined in.
|
||||||
|
//
|
||||||
|
//go:linkname Getfile py.getfile
|
||||||
|
func Getfile(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the module name for a given file, or None.
|
||||||
|
//
|
||||||
|
//go:linkname Getmodulename py.getmodulename
|
||||||
|
func Getmodulename(path *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the filename that can be used to locate an object's source.
|
||||||
|
//
|
||||||
|
// Return None if no way can be identified to get the source.
|
||||||
|
//
|
||||||
|
//go:linkname Getsourcefile py.getsourcefile
|
||||||
|
func Getsourcefile(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return an absolute path to the source or compiled file for an object.
|
||||||
|
//
|
||||||
|
// The idea is for each object to have a unique origin, so this routine
|
||||||
|
// normalizes the result as much as possible.
|
||||||
|
//
|
||||||
|
//go:linkname Getabsfile py.getabsfile
|
||||||
|
func Getabsfile(object *py.Object, Filename *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the module an object was defined in, or None if not found.
|
||||||
|
//
|
||||||
|
//go:linkname Getmodule py.getmodule
|
||||||
|
func Getmodule(object *py.Object, Filename *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the entire source file and starting line number for an object.
|
||||||
|
//
|
||||||
|
// The argument may be a module, class, method, function, traceback, frame,
|
||||||
|
// or code object. The source code is returned as a list of all the lines
|
||||||
|
// in the file and the line number indexes a line in that list. An OSError
|
||||||
|
// is raised if the source code cannot be retrieved.
|
||||||
|
//
|
||||||
|
//go:linkname Findsource py.findsource
|
||||||
|
func Findsource(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get lines of comments immediately preceding an object's source code.
|
||||||
|
//
|
||||||
|
// Returns None when source can't be found.
|
||||||
|
//
|
||||||
|
//go:linkname Getcomments py.getcomments
|
||||||
|
func Getcomments(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Extract the block of code at the top of the given list of lines.
|
||||||
|
//
|
||||||
|
//go:linkname Getblock py.getblock
|
||||||
|
func Getblock(lines *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return a list of source lines and starting line number for an object.
|
||||||
|
//
|
||||||
|
// The argument may be a module, class, method, function, traceback, frame,
|
||||||
|
// or code object. The source code is returned as a list of the lines
|
||||||
|
// corresponding to the object and the line number indicates where in the
|
||||||
|
// original source file the first line of code was found. An OSError is
|
||||||
|
// raised if the source code cannot be retrieved.
|
||||||
|
//
|
||||||
|
//go:linkname Getsourcelines py.getsourcelines
|
||||||
|
func Getsourcelines(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the text of the source code for an object.
|
||||||
|
//
|
||||||
|
// The argument may be a module, class, method, function, traceback, frame,
|
||||||
|
// or code object. The source code is returned as a single string. An
|
||||||
|
// OSError is raised if the source code cannot be retrieved.
|
||||||
|
//
|
||||||
|
//go:linkname Getsource py.getsource
|
||||||
|
func Getsource(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Recursive helper function for getclasstree().
|
||||||
|
//
|
||||||
|
//go:linkname Walktree py.walktree
|
||||||
|
func Walktree(classes *py.Object, children *py.Object, parent *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Arrange the given list of classes into a hierarchy of nested lists.
|
||||||
|
//
|
||||||
|
// Where a nested list appears, it contains classes derived from the class
|
||||||
|
// whose entry immediately precedes the list. Each entry is a 2-tuple
|
||||||
|
// containing a class and a tuple of its base classes. If the 'unique'
|
||||||
|
// argument is true, exactly one entry appears in the returned structure
|
||||||
|
// for each class in the given list. Otherwise, classes using multiple
|
||||||
|
// inheritance and their descendants will appear multiple times.
|
||||||
|
//
|
||||||
|
//go:linkname Getclasstree py.getclasstree
|
||||||
|
func Getclasstree(classes *py.Object, unique *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get information about the arguments accepted by a code object.
|
||||||
|
//
|
||||||
|
// Three things are returned: (args, varargs, varkw), where
|
||||||
|
// 'args' is the list of argument names. Keyword-only arguments are
|
||||||
|
// appended. 'varargs' and 'varkw' are the names of the * and **
|
||||||
|
// arguments or None.
|
||||||
|
//
|
||||||
|
//go:linkname Getargs py.getargs
|
||||||
|
func Getargs(co *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the names and default values of a callable object's parameters.
|
||||||
|
//
|
||||||
|
// A tuple of seven things is returned:
|
||||||
|
// (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
|
||||||
|
// 'args' is a list of the parameter names.
|
||||||
|
// 'varargs' and 'varkw' are the names of the * and ** parameters or None.
|
||||||
|
// 'defaults' is an n-tuple of the default values of the last n parameters.
|
||||||
|
// 'kwonlyargs' is a list of keyword-only parameter names.
|
||||||
|
// 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
|
||||||
|
// 'annotations' is a dictionary mapping parameter names to annotations.
|
||||||
|
//
|
||||||
|
// Notable differences from inspect.signature():
|
||||||
|
// - the "self" parameter is always reported, even for bound methods
|
||||||
|
// - wrapper chains defined by __wrapped__ *not* unwrapped automatically
|
||||||
|
//
|
||||||
|
//go:linkname Getfullargspec py.getfullargspec
|
||||||
|
func Getfullargspec(func_ *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get information about arguments passed into a particular frame.
|
||||||
|
//
|
||||||
|
// A tuple of four things is returned: (args, varargs, varkw, locals).
|
||||||
|
// 'args' is a list of the argument names.
|
||||||
|
// 'varargs' and 'varkw' are the names of the * and ** arguments or None.
|
||||||
|
// 'locals' is the locals dictionary of the given frame.
|
||||||
|
//
|
||||||
|
//go:linkname Getargvalues py.getargvalues
|
||||||
|
func Getargvalues(frame *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the mapping of arguments to values.
|
||||||
|
//
|
||||||
|
// A dict is returned, with keys the function argument names (including the
|
||||||
|
// names of the * and ** arguments, if any), and values the respective bound
|
||||||
|
// values from 'positional' and 'named'.
|
||||||
|
//
|
||||||
|
//go:linkname Getcallargs py.getcallargs
|
||||||
|
func Getcallargs(func_ *py.Object, __llgo_va_list ...interface{}) *py.Object
|
||||||
|
|
||||||
|
// Get the mapping of free variables to their current values.
|
||||||
|
//
|
||||||
|
// Returns a named tuple of dicts mapping the current nonlocal, global
|
||||||
|
// and builtin references as seen by the body of the function. A final
|
||||||
|
// set of unbound names that could not be resolved is also provided.
|
||||||
|
//
|
||||||
|
//go:linkname Getclosurevars py.getclosurevars
|
||||||
|
func Getclosurevars(func_ *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get information about a frame or traceback object.
|
||||||
|
//
|
||||||
|
// A tuple of five things is returned: the filename, the line number of
|
||||||
|
// the current line, the function name, a list of lines of context from
|
||||||
|
// the source code, and the index of the current line within that list.
|
||||||
|
// The optional second argument specifies the number of lines of context
|
||||||
|
// to return, which are centered around the current line.
|
||||||
|
//
|
||||||
|
//go:linkname Getframeinfo py.getframeinfo
|
||||||
|
func Getframeinfo(frame *py.Object, context *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the line number from a frame object, allowing for optimization.
|
||||||
|
//
|
||||||
|
//go:linkname Getlineno py.getlineno
|
||||||
|
func Getlineno(frame *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get a list of records for a frame and all higher (calling) frames.
|
||||||
|
//
|
||||||
|
// Each record contains a frame object, filename, line number, function
|
||||||
|
// name, a list of lines of context, and index within the context.
|
||||||
|
//
|
||||||
|
//go:linkname Getouterframes py.getouterframes
|
||||||
|
func Getouterframes(frame *py.Object, context *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get a list of records for a traceback's frame and all lower frames.
|
||||||
|
//
|
||||||
|
// Each record contains a frame object, filename, line number, function
|
||||||
|
// name, a list of lines of context, and index within the context.
|
||||||
|
//
|
||||||
|
//go:linkname Getinnerframes py.getinnerframes
|
||||||
|
func Getinnerframes(tb *py.Object, context *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the frame of the caller or None if this is not possible.
|
||||||
|
//
|
||||||
|
//go:linkname Currentframe py.currentframe
|
||||||
|
func Currentframe() *py.Object
|
||||||
|
|
||||||
|
// Return a list of records for the stack above the caller's frame.
|
||||||
|
//
|
||||||
|
//go:linkname Stack py.stack
|
||||||
|
func Stack(context *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return a list of records for the stack below the current exception.
|
||||||
|
//
|
||||||
|
//go:linkname Trace py.trace
|
||||||
|
func Trace(context *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get current state of a generator-iterator.
|
||||||
|
//
|
||||||
|
// Possible states are:
|
||||||
|
// GEN_CREATED: Waiting to start execution.
|
||||||
|
// GEN_RUNNING: Currently being executed by the interpreter.
|
||||||
|
// GEN_SUSPENDED: Currently suspended at a yield expression.
|
||||||
|
// GEN_CLOSED: Execution has completed.
|
||||||
|
//
|
||||||
|
//go:linkname Getgeneratorstate py.getgeneratorstate
|
||||||
|
func Getgeneratorstate(generator *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the mapping of generator local variables to their current values.
|
||||||
|
//
|
||||||
|
// A dict is returned, with the keys the local variable names and values the
|
||||||
|
// bound values.
|
||||||
|
//
|
||||||
|
//go:linkname Getgeneratorlocals py.getgeneratorlocals
|
||||||
|
func Getgeneratorlocals(generator *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get current state of a coroutine object.
|
||||||
|
//
|
||||||
|
// Possible states are:
|
||||||
|
// CORO_CREATED: Waiting to start execution.
|
||||||
|
// CORO_RUNNING: Currently being executed by the interpreter.
|
||||||
|
// CORO_SUSPENDED: Currently suspended at an await expression.
|
||||||
|
// CORO_CLOSED: Execution has completed.
|
||||||
|
//
|
||||||
|
//go:linkname Getcoroutinestate py.getcoroutinestate
|
||||||
|
func Getcoroutinestate(coroutine *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the mapping of coroutine local variables to their current values.
|
||||||
|
//
|
||||||
|
// A dict is returned, with the keys the local variable names and values the
|
||||||
|
// bound values.
|
||||||
|
//
|
||||||
|
//go:linkname Getcoroutinelocals py.getcoroutinelocals
|
||||||
|
func Getcoroutinelocals(coroutine *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get current state of an asynchronous generator object.
|
||||||
|
//
|
||||||
|
// Possible states are:
|
||||||
|
// AGEN_CREATED: Waiting to start execution.
|
||||||
|
// AGEN_RUNNING: Currently being executed by the interpreter.
|
||||||
|
// AGEN_SUSPENDED: Currently suspended at a yield expression.
|
||||||
|
// AGEN_CLOSED: Execution has completed.
|
||||||
|
//
|
||||||
|
//go:linkname Getasyncgenstate py.getasyncgenstate
|
||||||
|
func Getasyncgenstate(agen *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get the mapping of asynchronous generator local variables to their current
|
||||||
|
// values.
|
||||||
|
//
|
||||||
|
// A dict is returned, with the keys the local variable names and values the
|
||||||
|
// bound values.
|
||||||
|
//
|
||||||
|
//go:linkname Getasyncgenlocals py.getasyncgenlocals
|
||||||
|
func Getasyncgenlocals(agen *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Get a signature object for the passed callable.
|
||||||
|
//
|
||||||
|
//go:linkname Signature py.signature
|
||||||
|
func Signature(obj *py.Object) *py.Object
|
||||||
BIN
py/inspect/llgo_autogen.lla
Normal file
BIN
py/inspect/llgo_autogen.lla
Normal file
Binary file not shown.
152
py/json/gen.go
Normal file
152
py/json/gen.go
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
package json
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LLGoPackage = "py.json"
|
||||||
|
|
||||||
|
// Serialize “obj“ as a JSON formatted stream to “fp“ (a
|
||||||
|
//
|
||||||
|
// ``.write()``-supporting file-like object).
|
||||||
|
//
|
||||||
|
// If ``skipkeys`` is true then ``dict`` keys that are not basic types
|
||||||
|
// (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
|
||||||
|
// instead of raising a ``TypeError``.
|
||||||
|
//
|
||||||
|
// If ``ensure_ascii`` is false, then the strings written to ``fp`` can
|
||||||
|
// contain non-ASCII characters if they appear in strings contained in
|
||||||
|
// ``obj``. Otherwise, all such characters are escaped in JSON strings.
|
||||||
|
//
|
||||||
|
// If ``check_circular`` is false, then the circular reference check
|
||||||
|
// for container types will be skipped and a circular reference will
|
||||||
|
// result in an ``RecursionError`` (or worse).
|
||||||
|
//
|
||||||
|
// If ``allow_nan`` is false, then it will be a ``ValueError`` to
|
||||||
|
// serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
|
||||||
|
// in strict compliance of the JSON specification, instead of using the
|
||||||
|
// JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
|
||||||
|
//
|
||||||
|
// If ``indent`` is a non-negative integer, then JSON array elements and
|
||||||
|
// object members will be pretty-printed with that indent level. An indent
|
||||||
|
// level of 0 will only insert newlines. ``None`` is the most compact
|
||||||
|
// representation.
|
||||||
|
//
|
||||||
|
// If specified, ``separators`` should be an ``(item_separator, key_separator)``
|
||||||
|
// tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and
|
||||||
|
// ``(',', ': ')`` otherwise. To get the most compact JSON representation,
|
||||||
|
// you should specify ``(',', ':')`` to eliminate whitespace.
|
||||||
|
//
|
||||||
|
// ``default(obj)`` is a function that should return a serializable version
|
||||||
|
// of obj or raise TypeError. The default simply raises TypeError.
|
||||||
|
//
|
||||||
|
// If *sort_keys* is true (default: ``False``), then the output of
|
||||||
|
// dictionaries will be sorted by key.
|
||||||
|
//
|
||||||
|
// To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
|
||||||
|
// ``.default()`` method to serialize additional types), specify it with
|
||||||
|
// the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.
|
||||||
|
//
|
||||||
|
//go:linkname Dump py.dump
|
||||||
|
func Dump(obj *py.Object, fp *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Serialize “obj“ to a JSON formatted “str“.
|
||||||
|
//
|
||||||
|
// If ``skipkeys`` is true then ``dict`` keys that are not basic types
|
||||||
|
// (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
|
||||||
|
// instead of raising a ``TypeError``.
|
||||||
|
//
|
||||||
|
// If ``ensure_ascii`` is false, then the return value can contain non-ASCII
|
||||||
|
// characters if they appear in strings contained in ``obj``. Otherwise, all
|
||||||
|
// such characters are escaped in JSON strings.
|
||||||
|
//
|
||||||
|
// If ``check_circular`` is false, then the circular reference check
|
||||||
|
// for container types will be skipped and a circular reference will
|
||||||
|
// result in an ``RecursionError`` (or worse).
|
||||||
|
//
|
||||||
|
// If ``allow_nan`` is false, then it will be a ``ValueError`` to
|
||||||
|
// serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
|
||||||
|
// strict compliance of the JSON specification, instead of using the
|
||||||
|
// JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
|
||||||
|
//
|
||||||
|
// If ``indent`` is a non-negative integer, then JSON array elements and
|
||||||
|
// object members will be pretty-printed with that indent level. An indent
|
||||||
|
// level of 0 will only insert newlines. ``None`` is the most compact
|
||||||
|
// representation.
|
||||||
|
//
|
||||||
|
// If specified, ``separators`` should be an ``(item_separator, key_separator)``
|
||||||
|
// tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and
|
||||||
|
// ``(',', ': ')`` otherwise. To get the most compact JSON representation,
|
||||||
|
// you should specify ``(',', ':')`` to eliminate whitespace.
|
||||||
|
//
|
||||||
|
// ``default(obj)`` is a function that should return a serializable version
|
||||||
|
// of obj or raise TypeError. The default simply raises TypeError.
|
||||||
|
//
|
||||||
|
// If *sort_keys* is true (default: ``False``), then the output of
|
||||||
|
// dictionaries will be sorted by key.
|
||||||
|
//
|
||||||
|
// To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
|
||||||
|
// ``.default()`` method to serialize additional types), specify it with
|
||||||
|
// the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.
|
||||||
|
//
|
||||||
|
//go:linkname Dumps py.dumps
|
||||||
|
func Dumps(obj *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Deserialize “fp“ (a “.read()“-supporting file-like object containing
|
||||||
|
//
|
||||||
|
// a JSON document) to a Python object.
|
||||||
|
//
|
||||||
|
// ``object_hook`` is an optional function that will be called with the
|
||||||
|
// result of any object literal decode (a ``dict``). The return value of
|
||||||
|
// ``object_hook`` will be used instead of the ``dict``. This feature
|
||||||
|
// can be used to implement custom decoders (e.g. JSON-RPC class hinting).
|
||||||
|
//
|
||||||
|
// ``object_pairs_hook`` is an optional function that will be called with the
|
||||||
|
// result of any object literal decoded with an ordered list of pairs. The
|
||||||
|
// return value of ``object_pairs_hook`` will be used instead of the ``dict``.
|
||||||
|
// This feature can be used to implement custom decoders. If ``object_hook``
|
||||||
|
// is also defined, the ``object_pairs_hook`` takes priority.
|
||||||
|
//
|
||||||
|
// To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
|
||||||
|
// kwarg; otherwise ``JSONDecoder`` is used.
|
||||||
|
//
|
||||||
|
//go:linkname Load py.load
|
||||||
|
func Load(fp *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Deserialize “s“ (a “str“, “bytes“ or “bytearray“ instance
|
||||||
|
//
|
||||||
|
// containing a JSON document) to a Python object.
|
||||||
|
//
|
||||||
|
// ``object_hook`` is an optional function that will be called with the
|
||||||
|
// result of any object literal decode (a ``dict``). The return value of
|
||||||
|
// ``object_hook`` will be used instead of the ``dict``. This feature
|
||||||
|
// can be used to implement custom decoders (e.g. JSON-RPC class hinting).
|
||||||
|
//
|
||||||
|
// ``object_pairs_hook`` is an optional function that will be called with the
|
||||||
|
// result of any object literal decoded with an ordered list of pairs. The
|
||||||
|
// return value of ``object_pairs_hook`` will be used instead of the ``dict``.
|
||||||
|
// This feature can be used to implement custom decoders. If ``object_hook``
|
||||||
|
// is also defined, the ``object_pairs_hook`` takes priority.
|
||||||
|
//
|
||||||
|
// ``parse_float``, if specified, will be called with the string
|
||||||
|
// of every JSON float to be decoded. By default this is equivalent to
|
||||||
|
// float(num_str). This can be used to use another datatype or parser
|
||||||
|
// for JSON floats (e.g. decimal.Decimal).
|
||||||
|
//
|
||||||
|
// ``parse_int``, if specified, will be called with the string
|
||||||
|
// of every JSON int to be decoded. By default this is equivalent to
|
||||||
|
// int(num_str). This can be used to use another datatype or parser
|
||||||
|
// for JSON integers (e.g. float).
|
||||||
|
//
|
||||||
|
// ``parse_constant``, if specified, will be called with one of the
|
||||||
|
// following strings: -Infinity, Infinity, NaN.
|
||||||
|
// This can be used to raise an exception if invalid JSON numbers
|
||||||
|
// are encountered.
|
||||||
|
//
|
||||||
|
// To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
|
||||||
|
// kwarg; otherwise ``JSONDecoder`` is used.
|
||||||
|
//
|
||||||
|
//go:linkname Loads py.loads
|
||||||
|
func Loads(s *py.Object) *py.Object
|
||||||
BIN
py/json/llgo_autogen.lla
Normal file
BIN
py/json/llgo_autogen.lla
Normal file
Binary file not shown.
96
py/list.go
Normal file
96
py/list.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/list.html
|
||||||
|
|
||||||
|
//go:linkname List llgo.pyList
|
||||||
|
func List(__llgo_va_list ...any) *Object
|
||||||
|
|
||||||
|
// Return a new list of length len on success, or nil on failure.
|
||||||
|
//
|
||||||
|
//go:linkname NewList C.PyList_New
|
||||||
|
func NewList(len uintptr) *Object
|
||||||
|
|
||||||
|
// Return the length of the list object in list; this is equivalent to len(list)
|
||||||
|
// on a list object.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListLen C.PyList_Size
|
||||||
|
func (l *Object) ListLen() uintptr { return 0 }
|
||||||
|
|
||||||
|
// Return the object at position index in the list pointed to by list. The position
|
||||||
|
// must be non-negative; indexing from the end of the list is not supported. If index
|
||||||
|
// is out of bounds (<0 or >=len(list)), return nil and set an IndexError exception.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListItem C.PyList_GetItem
|
||||||
|
func (l *Object) ListItem(index uintptr) *Object { return nil }
|
||||||
|
|
||||||
|
// Set the item at index index in list to item. Return 0 on success. If index is out
|
||||||
|
// of bounds, return -1 and set an IndexError exception.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListSetItem C.PyList_SetItem
|
||||||
|
func (l *Object) ListSetItem(index uintptr, item *Object) c.Int { return 0 }
|
||||||
|
|
||||||
|
// Insert the item item into list list in front of index index. Return 0 if successful;
|
||||||
|
// return -1 and set an exception if unsuccessful. Analogous to list.insert(index, item).
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListInsert C.PyList_Insert
|
||||||
|
func (l *Object) ListInsert(index uintptr, item *Object) c.Int { return 0 }
|
||||||
|
|
||||||
|
// Append the object item at the end of list list. Return 0 if successful; return -1
|
||||||
|
// and set an exception if unsuccessful. Analogous to list.append(item).
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListAppend C.PyList_Append
|
||||||
|
func (l *Object) ListAppend(item *Object) c.Int { return 0 }
|
||||||
|
|
||||||
|
// Return a list of the objects in list containing the objects between low and high.
|
||||||
|
// Return nil and set an exception if unsuccessful. Analogous to list[low:high].
|
||||||
|
// Indexing from the end of the list is not supported.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListSlice C.PyList_GetSlice
|
||||||
|
func (l *Object) ListSlice(low, high uintptr) *Object { return nil }
|
||||||
|
|
||||||
|
// Set the slice of list between low and high to the contents of itemlist. Analogous
|
||||||
|
// to list[low:high] = itemlist. The itemlist may be NULL, indicating the assignment
|
||||||
|
// of an empty list (slice deletion). Return 0 on success, -1 on failure. Indexing
|
||||||
|
// from the end of the list is not supported.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListSetSlice C.PyList_SetSlice
|
||||||
|
func (l *Object) ListSetSlice(low, high uintptr, itemlist *Object) c.Int { return 0 }
|
||||||
|
|
||||||
|
// Sort the items of list in place. Return 0 on success, -1 on failure. This is equivalent
|
||||||
|
// to list.sort().
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListSort C.PyList_Sort
|
||||||
|
func (l *Object) ListSort() c.Int { return 0 }
|
||||||
|
|
||||||
|
// Reverse the items of list in place. Return 0 on success, -1 on failure. This is the
|
||||||
|
// equivalent of list.reverse().
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListReverse C.PyList_Reverse
|
||||||
|
func (l *Object) ListReverse() c.Int { return 0 }
|
||||||
|
|
||||||
|
// Return a new tuple object containing the contents of list; equivalent to tuple(list).
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ListAsTuple C.PyList_AsTuple
|
||||||
|
func (l *Object) ListAsTuple() *Object { return nil }
|
||||||
7
py/llgo.cfg
Normal file
7
py/llgo.cfg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"cl": [
|
||||||
|
"clang -emit-llvm -S -o module.ll -c _pyg/module.c",
|
||||||
|
"llgen .",
|
||||||
|
"rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll module.ll",
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
py/llgo_autogen.lla
Normal file
BIN
py/llgo_autogen.lla
Normal file
Binary file not shown.
73
py/long.go
Normal file
73
py/long.go
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/long.html
|
||||||
|
|
||||||
|
//go:linkname Long C.PyLong_FromLong
|
||||||
|
func Long(v c.Long) *Object
|
||||||
|
|
||||||
|
//go:linkname LongLong C.PyLong_FromLongLong
|
||||||
|
func LongLong(v c.LongLong) *Object
|
||||||
|
|
||||||
|
//go:linkname Ulong C.PyLong_FromUnsignedLong
|
||||||
|
func Ulong(v c.Ulong) *Object
|
||||||
|
|
||||||
|
//go:linkname UlongLong C.PyLong_FromUnsignedLongLong
|
||||||
|
func UlongLong(v c.UlongLong) *Object
|
||||||
|
|
||||||
|
//go:linkname Uintptr C.PyLong_FromSize_t
|
||||||
|
func Uintptr(v uintptr) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromFloat64 C.PyLong_FromDouble
|
||||||
|
func LongFromFloat64(v float64) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromVoidPtr C.PyLong_FromVoidPtr
|
||||||
|
func LongFromVoidPtr(v c.Pointer) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromCStr C.PyLong_FromString
|
||||||
|
func LongFromCStr(v *c.Char, pend **c.Char, base c.Int) *Object
|
||||||
|
|
||||||
|
//go:linkname LongFromUnicode C.PyLong_FromUnicodeObject
|
||||||
|
func LongFromUnicode(v *Object, base c.Int) *Object
|
||||||
|
|
||||||
|
// llgo:link (*Object).Long C.PyLong_AsLong
|
||||||
|
func (l *Object) Long() c.Long { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).LongLong C.PyLong_AsLongLong
|
||||||
|
func (l *Object) LongLong() c.LongLong { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).Ulong C.PyLong_AsUnsignedLong
|
||||||
|
func (l *Object) Ulong() c.Ulong { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).UlongLong C.PyLong_AsUnsignedLongLong
|
||||||
|
func (l *Object) UlongLong() c.UlongLong { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).Uintptr C.PyLong_AsSize_t
|
||||||
|
func (l *Object) Uintptr() uintptr { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).LongAsFloat64 C.PyLong_AsDouble
|
||||||
|
func (l *Object) LongAsFloat64() float64 { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Object).LongAsVoidPtr C.PyLong_AsVoidPtr
|
||||||
|
func (l *Object) LongAsVoidPtr() c.Pointer { return nil }
|
||||||
31
py/math/doc.txt
Normal file
31
py/math/doc.txt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Unlike the built-in ** operator, math.pow() converts both its arguments to type
|
||||||
|
// float. Use ** or the built-in pow() function for computing exact integer powers.
|
||||||
|
//
|
||||||
|
//go:linkname Pow py.pow
|
||||||
|
func Pow(x, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the sine of x radians.
|
||||||
|
//
|
||||||
|
//go:linkname Sin py.sin
|
||||||
|
func Sin(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the hyperbolic sine of x.
|
||||||
|
//
|
||||||
|
//go:linkname Sinh py.sinh
|
||||||
|
func Sinh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base-2 logarithm of x. This is usually more accurate than log(x, 2).
|
||||||
|
//
|
||||||
|
//go:linkname Log2 py.log2
|
||||||
|
func Log2(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base-10 logarithm of x. This is usually more accurate than log(x, 10).
|
||||||
|
//
|
||||||
|
//go:linkname Log10 py.log10
|
||||||
|
func Log10(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the fractional and integer parts of x. Both results carry the sign of
|
||||||
|
// x and are floats.
|
||||||
|
//
|
||||||
|
//go:linkname Modf py.modf
|
||||||
|
func Modf(x *py.Object) *py.Object
|
||||||
349
py/math/gen.go
Normal file
349
py/math/gen.go
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
package math
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LLGoPackage = "py.math"
|
||||||
|
|
||||||
|
// Return the arc cosine (measured in radians) of x.
|
||||||
|
//
|
||||||
|
// The result is between 0 and pi.
|
||||||
|
//
|
||||||
|
//go:linkname Acos py.acos
|
||||||
|
func Acos(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the inverse hyperbolic cosine of x.
|
||||||
|
//
|
||||||
|
//go:linkname Acosh py.acosh
|
||||||
|
func Acosh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the arc sine (measured in radians) of x.
|
||||||
|
//
|
||||||
|
// The result is between -pi/2 and pi/2.
|
||||||
|
//
|
||||||
|
//go:linkname Asin py.asin
|
||||||
|
func Asin(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the inverse hyperbolic sine of x.
|
||||||
|
//
|
||||||
|
//go:linkname Asinh py.asinh
|
||||||
|
func Asinh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the arc tangent (measured in radians) of x.
|
||||||
|
//
|
||||||
|
// The result is between -pi/2 and pi/2.
|
||||||
|
//
|
||||||
|
//go:linkname Atan py.atan
|
||||||
|
func Atan(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the arc tangent (measured in radians) of y/x.
|
||||||
|
//
|
||||||
|
// Unlike atan(y/x), the signs of both x and y are considered.
|
||||||
|
//
|
||||||
|
//go:linkname Atan2 py.atan2
|
||||||
|
func Atan2(y *py.Object, x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the inverse hyperbolic tangent of x.
|
||||||
|
//
|
||||||
|
//go:linkname Atanh py.atanh
|
||||||
|
func Atanh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the cube root of x.
|
||||||
|
//
|
||||||
|
//go:linkname Cbrt py.cbrt
|
||||||
|
func Cbrt(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the ceiling of x as an Integral.
|
||||||
|
//
|
||||||
|
// This is the smallest integer >= x.
|
||||||
|
//
|
||||||
|
//go:linkname Ceil py.ceil
|
||||||
|
func Ceil(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return a float with the magnitude (absolute value) of x but the sign of y.
|
||||||
|
//
|
||||||
|
// On platforms that support signed zeros, copysign(1.0, -0.0)
|
||||||
|
// returns -1.0.
|
||||||
|
//
|
||||||
|
//go:linkname Copysign py.copysign
|
||||||
|
func Copysign(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the cosine of x (measured in radians).
|
||||||
|
//
|
||||||
|
//go:linkname Cos py.cos
|
||||||
|
func Cos(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the hyperbolic cosine of x.
|
||||||
|
//
|
||||||
|
//go:linkname Cosh py.cosh
|
||||||
|
func Cosh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Convert angle x from radians to degrees.
|
||||||
|
//
|
||||||
|
//go:linkname Degrees py.degrees
|
||||||
|
func Degrees(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the Euclidean distance between two points p and q.
|
||||||
|
//
|
||||||
|
// The points should be specified as sequences (or iterables) of
|
||||||
|
// coordinates. Both inputs must have the same dimension.
|
||||||
|
//
|
||||||
|
// Roughly equivalent to:
|
||||||
|
//
|
||||||
|
// sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
|
||||||
|
//
|
||||||
|
//go:linkname Dist py.dist
|
||||||
|
func Dist(p *py.Object, q *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Error function at x.
|
||||||
|
//
|
||||||
|
//go:linkname Erf py.erf
|
||||||
|
func Erf(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Complementary error function at x.
|
||||||
|
//
|
||||||
|
//go:linkname Erfc py.erfc
|
||||||
|
func Erfc(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return e raised to the power of x.
|
||||||
|
//
|
||||||
|
//go:linkname Exp py.exp
|
||||||
|
func Exp(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return 2 raised to the power of x.
|
||||||
|
//
|
||||||
|
//go:linkname Exp2 py.exp2
|
||||||
|
func Exp2(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return exp(x)-1.
|
||||||
|
//
|
||||||
|
// This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x.
|
||||||
|
//
|
||||||
|
//go:linkname Expm1 py.expm1
|
||||||
|
func Expm1(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the absolute value of the float x.
|
||||||
|
//
|
||||||
|
//go:linkname Fabs py.fabs
|
||||||
|
func Fabs(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Find n!.
|
||||||
|
//
|
||||||
|
// Raise a ValueError if x is negative or non-integral.
|
||||||
|
//
|
||||||
|
//go:linkname Factorial py.factorial
|
||||||
|
func Factorial(n *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the floor of x as an Integral.
|
||||||
|
//
|
||||||
|
// This is the largest integer <= x.
|
||||||
|
//
|
||||||
|
//go:linkname Floor py.floor
|
||||||
|
func Floor(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return fmod(x, y), according to platform C.
|
||||||
|
//
|
||||||
|
// x % y may differ.
|
||||||
|
//
|
||||||
|
//go:linkname Fmod py.fmod
|
||||||
|
func Fmod(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the mantissa and exponent of x, as pair (m, e).
|
||||||
|
//
|
||||||
|
// m is a float and e is an int, such that x = m * 2.**e.
|
||||||
|
// If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.
|
||||||
|
//
|
||||||
|
//go:linkname Frexp py.frexp
|
||||||
|
func Frexp(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return an accurate floating point sum of values in the iterable seq.
|
||||||
|
//
|
||||||
|
// Assumes IEEE-754 floating point arithmetic.
|
||||||
|
//
|
||||||
|
//go:linkname Fsum py.fsum
|
||||||
|
func Fsum(seq *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Gamma function at x.
|
||||||
|
//
|
||||||
|
//go:linkname Gamma py.gamma
|
||||||
|
func Gamma(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Greatest Common Divisor.
|
||||||
|
//
|
||||||
|
//go:linkname Gcd py.gcd
|
||||||
|
func Gcd(__llgo_va_list ...interface{}) *py.Object
|
||||||
|
|
||||||
|
// Return True if x is neither an infinity nor a NaN, and False otherwise.
|
||||||
|
//
|
||||||
|
//go:linkname Isfinite py.isfinite
|
||||||
|
func Isfinite(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return True if x is a positive or negative infinity, and False otherwise.
|
||||||
|
//
|
||||||
|
//go:linkname Isinf py.isinf
|
||||||
|
func Isinf(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return True if x is a NaN (not a number), and False otherwise.
|
||||||
|
//
|
||||||
|
//go:linkname Isnan py.isnan
|
||||||
|
func Isnan(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the integer part of the square root of the input.
|
||||||
|
//
|
||||||
|
//go:linkname Isqrt py.isqrt
|
||||||
|
func Isqrt(n *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Least Common Multiple.
|
||||||
|
//
|
||||||
|
//go:linkname Lcm py.lcm
|
||||||
|
func Lcm(__llgo_va_list ...interface{}) *py.Object
|
||||||
|
|
||||||
|
// Return x * (2**i).
|
||||||
|
//
|
||||||
|
// This is essentially the inverse of frexp().
|
||||||
|
//
|
||||||
|
//go:linkname Ldexp py.ldexp
|
||||||
|
func Ldexp(x *py.Object, i *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Natural logarithm of absolute value of Gamma function at x.
|
||||||
|
//
|
||||||
|
//go:linkname Lgamma py.lgamma
|
||||||
|
func Lgamma(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base 10 logarithm of x.
|
||||||
|
//
|
||||||
|
//go:linkname Log10 py.log10
|
||||||
|
func Log10(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the base 2 logarithm of x.
|
||||||
|
//
|
||||||
|
//go:linkname Log2 py.log2
|
||||||
|
func Log2(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the fractional and integer parts of x.
|
||||||
|
//
|
||||||
|
// Both results carry the sign of x and are floats.
|
||||||
|
//
|
||||||
|
//go:linkname Modf py.modf
|
||||||
|
func Modf(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return x**y (x to the power of y).
|
||||||
|
//
|
||||||
|
//go:linkname Pow py.pow
|
||||||
|
func Pow(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Convert angle x from degrees to radians.
|
||||||
|
//
|
||||||
|
//go:linkname Radians py.radians
|
||||||
|
func Radians(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Difference between x and the closest integer multiple of y.
|
||||||
|
//
|
||||||
|
// Return x - n*y where n*y is the closest integer multiple of y.
|
||||||
|
// In the case where x is exactly halfway between two multiples of
|
||||||
|
// y, the nearest even value of n is used. The result is always exact.
|
||||||
|
//
|
||||||
|
//go:linkname Remainder py.remainder
|
||||||
|
func Remainder(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the sine of x (measured in radians).
|
||||||
|
//
|
||||||
|
//go:linkname Sin py.sin
|
||||||
|
func Sin(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the hyperbolic sine of x.
|
||||||
|
//
|
||||||
|
//go:linkname Sinh py.sinh
|
||||||
|
func Sinh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the square root of x.
|
||||||
|
//
|
||||||
|
//go:linkname Sqrt py.sqrt
|
||||||
|
func Sqrt(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the tangent of x (measured in radians).
|
||||||
|
//
|
||||||
|
//go:linkname Tan py.tan
|
||||||
|
func Tan(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the hyperbolic tangent of x.
|
||||||
|
//
|
||||||
|
//go:linkname Tanh py.tanh
|
||||||
|
func Tanh(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the sum of products of values from two iterables p and q.
|
||||||
|
//
|
||||||
|
// Roughly equivalent to:
|
||||||
|
//
|
||||||
|
// sum(itertools.starmap(operator.mul, zip(p, q, strict=True)))
|
||||||
|
//
|
||||||
|
// For float and mixed int/float inputs, the intermediate products
|
||||||
|
// and sums are computed with extended precision.
|
||||||
|
//
|
||||||
|
//go:linkname Sumprod py.sumprod
|
||||||
|
func Sumprod(p *py.Object, q *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Truncates the Real x to the nearest Integral toward 0.
|
||||||
|
//
|
||||||
|
// Uses the __trunc__ magic method.
|
||||||
|
//
|
||||||
|
//go:linkname Trunc py.trunc
|
||||||
|
func Trunc(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Calculate the product of all the elements in the input iterable.
|
||||||
|
//
|
||||||
|
// The default start value for the product is 1.
|
||||||
|
//
|
||||||
|
// When the iterable is empty, return the start value. This function is
|
||||||
|
// intended specifically for use with numeric values and may reject
|
||||||
|
// non-numeric types.
|
||||||
|
//
|
||||||
|
//go:linkname Prod py.prod
|
||||||
|
func Prod(iterable *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Number of ways to choose k items from n items without repetition and with order.
|
||||||
|
//
|
||||||
|
// Evaluates to n! / (n - k)! when k <= n and evaluates
|
||||||
|
// to zero when k > n.
|
||||||
|
//
|
||||||
|
// If k is not specified or is None, then k defaults to n
|
||||||
|
// and the function returns n!.
|
||||||
|
//
|
||||||
|
// Raises TypeError if either of the arguments are not integers.
|
||||||
|
// Raises ValueError if either of the arguments are negative.
|
||||||
|
//
|
||||||
|
//go:linkname Perm py.perm
|
||||||
|
func Perm(n *py.Object, k *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Number of ways to choose k items from n items without repetition and without order.
|
||||||
|
//
|
||||||
|
// Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates
|
||||||
|
// to zero when k > n.
|
||||||
|
//
|
||||||
|
// Also called the binomial coefficient because it is equivalent
|
||||||
|
// to the coefficient of k-th term in polynomial expansion of the
|
||||||
|
// expression (1 + x)**n.
|
||||||
|
//
|
||||||
|
// Raises TypeError if either of the arguments are not integers.
|
||||||
|
// Raises ValueError if either of the arguments are negative.
|
||||||
|
//
|
||||||
|
//go:linkname Comb py.comb
|
||||||
|
func Comb(n *py.Object, k *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the floating-point value the given number of steps after x towards y.
|
||||||
|
//
|
||||||
|
// If steps is not specified or is None, it defaults to 1.
|
||||||
|
//
|
||||||
|
// Raises a TypeError, if x or y is not a double, or if steps is not an integer.
|
||||||
|
// Raises ValueError if steps is negative.
|
||||||
|
//
|
||||||
|
//go:linkname Nextafter py.nextafter
|
||||||
|
func Nextafter(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the value of the least significant bit of the float x.
|
||||||
|
//
|
||||||
|
//go:linkname Ulp py.ulp
|
||||||
|
func Ulp(x *py.Object) *py.Object
|
||||||
BIN
py/math/llgo_autogen.lla
Normal file
BIN
py/math/llgo_autogen.lla
Normal file
Binary file not shown.
51
py/math/math.go
Normal file
51
py/math/math.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package math
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/library/math.html
|
||||||
|
|
||||||
|
//go:linkname Pi py.pi
|
||||||
|
var Pi *py.Object
|
||||||
|
|
||||||
|
// With one argument, return the natural logarithm of x (to base e).
|
||||||
|
//
|
||||||
|
//go:linkname Log py.log
|
||||||
|
func Log(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// With two arguments, return the logarithm of x to the given base, calculated
|
||||||
|
// as log(x)/log(base).
|
||||||
|
//
|
||||||
|
//go:linkname LogOf py.log
|
||||||
|
func LogOf(x, base *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the natural logarithm of 1+x (base e). The result is calculated in
|
||||||
|
// a way which is accurate for x near zero.
|
||||||
|
//
|
||||||
|
//go:linkname Log1p py.log1p
|
||||||
|
func Log1p(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the Euclidean norm, sqrt(sum(x**2 for x in coordinates)). This is the
|
||||||
|
// length of the vector from the origin to the point given by the coordinates.
|
||||||
|
//
|
||||||
|
//go:linkname Hypot py.hypot
|
||||||
|
func Hypot(coordinates ...*py.Object) *py.Object
|
||||||
78
py/module.go
Normal file
78
py/module.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/import.html
|
||||||
|
// https://docs.python.org/3/c-api/module.html
|
||||||
|
|
||||||
|
/*
|
||||||
|
// llgo:type C
|
||||||
|
type ModuleDefBase struct {
|
||||||
|
Unused [8]byte // TODO(xsw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:type C
|
||||||
|
type ModuleDef struct {
|
||||||
|
Base ModuleDefBase
|
||||||
|
// TODO(xsw)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Return the module object corresponding to a module name. The name argument
|
||||||
|
// may be of the form package.module. First check the modules dictionary if
|
||||||
|
// there’s one there, and if not, create a new one and insert it in the modules
|
||||||
|
// dictionary. Return nil with an exception set on failure.
|
||||||
|
//
|
||||||
|
//go:linkname AddModule C.PyImport_AddModule
|
||||||
|
func AddModule(name *c.Char) *Object
|
||||||
|
|
||||||
|
// This is a wrapper around py.Import which takes a const char* as an argument
|
||||||
|
// instead of an Object.
|
||||||
|
//
|
||||||
|
//go:linkname ImportModule C.PyImport_ImportModule
|
||||||
|
func ImportModule(name *c.Char) *Object
|
||||||
|
|
||||||
|
// This is a higher-level interface that calls the current “import hook function” (with
|
||||||
|
// an explicit level of 0, meaning absolute import). It invokes the __import__() function
|
||||||
|
// from the __builtins__ of the current globals. This means that the import is done using
|
||||||
|
// whatever import hooks are installed in the current environment.
|
||||||
|
//
|
||||||
|
// This function always uses absolute imports.
|
||||||
|
//
|
||||||
|
//go:linkname Import C.PyImport_Import
|
||||||
|
func Import(name *Object) *Object
|
||||||
|
|
||||||
|
// Return the dictionary object that implements module’s namespace; this object is the same
|
||||||
|
// as the __dict__ attribute of the module object. If module is not a module object (or a
|
||||||
|
// subtype of a module object), SystemError is raised and nil is returned.
|
||||||
|
//
|
||||||
|
// It is recommended extensions use other Module and Object functions rather than directly
|
||||||
|
// manipulate a module’s __dict__.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).ModuleGetDict C.PyModule_GetDict
|
||||||
|
func (m *Object) ModuleGetDict() *Object { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*Object).ModuleLoadSyms C.llgoLoadPyModSyms
|
||||||
|
func (m *Object) ModuleLoadSyms(__llgo_va_list ...any) {}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
82
py/module.ll
Normal file
82
py/module.ll
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
; ModuleID = '_pyg/module.c'
|
||||||
|
source_filename = "_pyg/module.c"
|
||||||
|
|
||||||
|
%struct.PyObject = type opaque
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
|
||||||
|
define void @llgoLoadPyModSyms(%struct.PyObject* noundef %0, ...) #0 {
|
||||||
|
%2 = alloca %struct.PyObject*, align 8
|
||||||
|
%3 = alloca i8*, align 8
|
||||||
|
%4 = alloca i8*, align 8
|
||||||
|
%5 = alloca i8*, align 8
|
||||||
|
%6 = alloca %struct.PyObject**, align 8
|
||||||
|
%7 = alloca %struct.PyObject**, align 8
|
||||||
|
store %struct.PyObject* %0, %struct.PyObject** %2, align 8
|
||||||
|
%8 = bitcast i8** %3 to i8*
|
||||||
|
call void @llvm.va_start(i8* %8)
|
||||||
|
br label %9
|
||||||
|
|
||||||
|
9: ; preds = %26, %1
|
||||||
|
%10 = va_arg i8** %3, i8*
|
||||||
|
store i8* %10, i8** %5, align 8
|
||||||
|
%11 = load i8*, i8** %5, align 8
|
||||||
|
store i8* %11, i8** %4, align 8
|
||||||
|
%12 = load i8*, i8** %4, align 8
|
||||||
|
%13 = icmp eq i8* %12, null
|
||||||
|
br i1 %13, label %14, label %15
|
||||||
|
|
||||||
|
14: ; preds = %9
|
||||||
|
br label %27
|
||||||
|
|
||||||
|
15: ; preds = %9
|
||||||
|
%16 = va_arg i8** %3, %struct.PyObject**
|
||||||
|
store %struct.PyObject** %16, %struct.PyObject*** %7, align 8
|
||||||
|
%17 = load %struct.PyObject**, %struct.PyObject*** %7, align 8
|
||||||
|
store %struct.PyObject** %17, %struct.PyObject*** %6, align 8
|
||||||
|
%18 = load %struct.PyObject**, %struct.PyObject*** %6, align 8
|
||||||
|
%19 = load %struct.PyObject*, %struct.PyObject** %18, align 8
|
||||||
|
%20 = icmp eq %struct.PyObject* %19, null
|
||||||
|
br i1 %20, label %21, label %26
|
||||||
|
|
||||||
|
21: ; preds = %15
|
||||||
|
%22 = load %struct.PyObject*, %struct.PyObject** %2, align 8
|
||||||
|
%23 = load i8*, i8** %4, align 8
|
||||||
|
%24 = call %struct.PyObject* @PyObject_GetAttrString(%struct.PyObject* noundef %22, i8* noundef %23)
|
||||||
|
%25 = load %struct.PyObject**, %struct.PyObject*** %6, align 8
|
||||||
|
store %struct.PyObject* %24, %struct.PyObject** %25, align 8
|
||||||
|
br label %26
|
||||||
|
|
||||||
|
26: ; preds = %21, %15
|
||||||
|
br label %9
|
||||||
|
|
||||||
|
27: ; preds = %14
|
||||||
|
%28 = bitcast i8** %3 to i8*
|
||||||
|
call void @llvm.va_end(i8* %28)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nocallback nofree nosync nounwind willreturn
|
||||||
|
declare void @llvm.va_start(i8*) #1
|
||||||
|
|
||||||
|
declare %struct.PyObject* @PyObject_GetAttrString(%struct.PyObject* noundef, i8* noundef) #2
|
||||||
|
|
||||||
|
; Function Attrs: nocallback nofree nosync nounwind willreturn
|
||||||
|
declare void @llvm.va_end(i8*) #1
|
||||||
|
|
||||||
|
attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="__chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.5a,+zcm,+zcz" }
|
||||||
|
attributes #1 = { nocallback nofree nosync nounwind willreturn }
|
||||||
|
attributes #2 = { "frame-pointer"="non-leaf" "no-trapping-math"="true" "probe-stack"="__chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.5a,+zcm,+zcz" }
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
|
||||||
|
!llvm.ident = !{!9}
|
||||||
|
|
||||||
|
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 3]}
|
||||||
|
!1 = !{i32 1, !"wchar_size", i32 4}
|
||||||
|
!2 = !{i32 8, !"branch-target-enforcement", i32 0}
|
||||||
|
!3 = !{i32 8, !"sign-return-address", i32 0}
|
||||||
|
!4 = !{i32 8, !"sign-return-address-all", i32 0}
|
||||||
|
!5 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
|
||||||
|
!6 = !{i32 7, !"PIC Level", i32 2}
|
||||||
|
!7 = !{i32 7, !"uwtable", i32 1}
|
||||||
|
!8 = !{i32 7, !"frame-pointer", i32 1}
|
||||||
|
!9 = !{!"Apple clang version 14.0.3 (clang-1403.0.22.14.1)"}
|
||||||
10195
py/numpy/gen.go
Normal file
10195
py/numpy/gen.go
Normal file
File diff suppressed because it is too large
Load Diff
BIN
py/numpy/llgo_autogen.lla
Normal file
BIN
py/numpy/llgo_autogen.lla
Normal file
Binary file not shown.
79
py/numpy/numpy.go
Normal file
79
py/numpy/numpy.go
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package numpy
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://numpy.org/doc/stable/reference/index.html#reference
|
||||||
|
|
||||||
|
// Return evenly spaced values within a given interval.
|
||||||
|
//
|
||||||
|
// numpy.arange([start, ]stop, [step, ]dtype=None, *, like=None)
|
||||||
|
//
|
||||||
|
// See https://numpy.org/doc/stable/reference/generated/numpy.arange.html#numpy-arange
|
||||||
|
//
|
||||||
|
//go:linkname Arange py.arange
|
||||||
|
func Arange(start, stop, step, dtype *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return a new array of given shape and type, without initializing entries.
|
||||||
|
//
|
||||||
|
// numpy.empty(shape, dtype=float, order='C', *, like=None)
|
||||||
|
//
|
||||||
|
// See https://numpy.org/doc/stable/reference/generated/numpy.empty.html#numpy-empty
|
||||||
|
//
|
||||||
|
//go:linkname Empty py.empty
|
||||||
|
func Empty(shape, dtype, order *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return a 2-D array with ones on the diagonal and zeros elsewhere.
|
||||||
|
//
|
||||||
|
// numpy.eye(N, M=None, k=0, dtype=<class 'float'>, order='C', *, like=None)
|
||||||
|
//
|
||||||
|
// See https://numpy.org/doc/stable/reference/generated/numpy.eye.html#numpy-eye
|
||||||
|
//
|
||||||
|
//go:linkname Eye py.eye
|
||||||
|
func Eye(N, M, k, dtype, order *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return a new array of given shape and type, filled with zeros.
|
||||||
|
//
|
||||||
|
// numpy.zeros(shape, dtype=float, order='C', *, like=None)
|
||||||
|
//
|
||||||
|
// See https://numpy.org/doc/stable/reference/generated/numpy.zeros.html#numpy-zeros
|
||||||
|
//
|
||||||
|
//go:linkname Zeros py.zeros
|
||||||
|
func Zeros(shape, dtype, order *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Create an array.
|
||||||
|
//
|
||||||
|
// numpy.array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None)
|
||||||
|
//
|
||||||
|
// See https://numpy.org/doc/stable/reference/generated/numpy.array.html#numpy-array
|
||||||
|
//
|
||||||
|
//go:linkname Array py.array
|
||||||
|
func Array(object, dtype *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Convert the input to an array.
|
||||||
|
//
|
||||||
|
// numpy.asarray(a, dtype=None, order=None, *, like=None)
|
||||||
|
//
|
||||||
|
// See https://numpy.org/doc/stable/reference/generated/numpy.asarray.html#numpy-asarray
|
||||||
|
//
|
||||||
|
//go:linkname AsArray py.asarray
|
||||||
|
func AsArray(a, dtype, order *py.Object) *py.Object
|
||||||
68
py/object.go
Normal file
68
py/object.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/c-api/object.html
|
||||||
|
|
||||||
|
// Object represents a Python object.
|
||||||
|
type Object struct {
|
||||||
|
Unused [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Object).DecRef C.Py_DecRef
|
||||||
|
func (o *Object) DecRef() {}
|
||||||
|
|
||||||
|
// llgo:link (*Object).Type C.PyObject_Type
|
||||||
|
func (o *Object) Type() *Object { return nil }
|
||||||
|
|
||||||
|
// Compute a string representation of object o. Returns the string representation on
|
||||||
|
// success, nil on failure. This is the equivalent of the Python expression str(o).
|
||||||
|
// Called by the str() built-in function and, therefore, by the print() function.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).Str C.PyObject_Str
|
||||||
|
func (o *Object) Str() *Object { return nil }
|
||||||
|
|
||||||
|
// Returns 1 if the object o is considered to be true, and 0 otherwise. This is equivalent
|
||||||
|
// to the Python expression not not o. On failure, return -1.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).IsTrue C.PyObject_IsTrue
|
||||||
|
func (o *Object) IsTrue() c.Int { return -1 }
|
||||||
|
|
||||||
|
// Returns 0 if the object o is considered to be true, and 1 otherwise. This is equivalent
|
||||||
|
// to the Python expression not o. On failure, return -1.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).NotTrue C.PyObject_Not
|
||||||
|
func (o *Object) NotTrue() c.Int { return -1 }
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Retrieve an attribute named attrName from object o. Returns the attribute value on success,
|
||||||
|
// or nil on failure. This is the equivalent of the Python expression o.attrName.
|
||||||
|
//
|
||||||
|
// llgo:link (*Object).GetAttr C.PyObject_GetAttr
|
||||||
|
func (o *Object) GetAttr(attrName *Object) *Object { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*Object).GetAttrString C.PyObject_GetAttrString
|
||||||
|
func (o *Object) GetAttrString(attrName *c.Char) *Object { return nil }
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
1429
py/os/gen.go
Normal file
1429
py/os/gen.go
Normal file
File diff suppressed because it is too large
Load Diff
BIN
py/os/llgo_autogen.lla
Normal file
BIN
py/os/llgo_autogen.lla
Normal file
Binary file not shown.
42
py/os/os.go
Normal file
42
py/os/os.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package os
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.python.org/3/library/os.html
|
||||||
|
|
||||||
|
// Rename the file or directory src to dst. If dst exists, the operation will
|
||||||
|
// fail with an OSError subclass in a number of cases:
|
||||||
|
//
|
||||||
|
// On Windows, if dst exists a FileExistsError is always raised. The operation
|
||||||
|
// may fail if src and dst are on different filesystems. Use shutil.move() to
|
||||||
|
// support moves to a different filesystem.
|
||||||
|
//
|
||||||
|
// On Unix, if src is a file and dst is a directory or vice-versa, an IsADirectoryError
|
||||||
|
// or a NotADirectoryError will be raised respectively. If both are directories and dst
|
||||||
|
// is empty, dst will be silently replaced. If dst is a non-empty directory, an OSError
|
||||||
|
// is raised. If both are files, dst will be replaced silently if the user has permission.
|
||||||
|
// The operation may fail on some Unix flavors if src and dst are on different filesystems.
|
||||||
|
// If successful, the renaming will be an atomic operation (this is a POSIX requirement).
|
||||||
|
//
|
||||||
|
//go:linkname Rename py.rename
|
||||||
|
func Rename(src, dst *py.Object) *py.Object
|
||||||
120
py/python.go
Normal file
120
py/python.go
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package py
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link: $LLGO_LIB_PYTHON"
|
||||||
|
)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname SetProgramName C.Py_SetProgramName
|
||||||
|
func SetProgramName(name *c.Char)
|
||||||
|
|
||||||
|
//go:linkname Initialize C.Py_Initialize
|
||||||
|
func Initialize()
|
||||||
|
|
||||||
|
// This function works like Initialize() if initsigs is 1.
|
||||||
|
// If initsigs is 0, it skips initialization registration of signal handlers,
|
||||||
|
// which might be useful when Python is embedded.
|
||||||
|
//
|
||||||
|
//go:linkname InitializeEx C.Py_InitializeEx
|
||||||
|
func InitializeEx(initsigs c.Int)
|
||||||
|
|
||||||
|
//go:linkname Finalize C.Py_Finalize
|
||||||
|
func Finalize()
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname RunSimpleString C.PyRun_SimpleString
|
||||||
|
func RunSimpleString(command *c.Char) c.Int
|
||||||
|
|
||||||
|
//go:linkname RunSimpleStringFlags C.PyRun_SimpleStringFlags
|
||||||
|
func RunSimpleStringFlags(command *c.Char, flags *CompilerFlags) c.Int
|
||||||
|
|
||||||
|
//go:linkname RunSimpleFile C.PyRun_SimpleFile
|
||||||
|
func RunSimpleFile(fp c.FilePtr, filename *c.Char) c.Int
|
||||||
|
|
||||||
|
//go:linkname RunSimpleFileFlags C.PyRun_SimpleFileFlags
|
||||||
|
func RunSimpleFileFlags(fp c.FilePtr, filename *c.Char, flags *CompilerFlags) c.Int
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type InputType c.Int
|
||||||
|
|
||||||
|
const (
|
||||||
|
SingleInput InputType = 256 // read code from i/o
|
||||||
|
FileInput InputType = 257 // read code from filename
|
||||||
|
EvalInput InputType = 258 // read code from string
|
||||||
|
// FuncTypeInput InputType = 345
|
||||||
|
)
|
||||||
|
|
||||||
|
// llgo:type C
|
||||||
|
type CompilerFlags struct {
|
||||||
|
CfFlags c.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname CompileString C.Py_CompileString
|
||||||
|
func CompileString(str, filename *c.Char, start InputType) *Object
|
||||||
|
|
||||||
|
//go:linkname CompileStringFlags C.Py_CompileStringFlags
|
||||||
|
func CompileStringFlags(str, filename *c.Char, start InputType, flags *CompilerFlags) *Object
|
||||||
|
|
||||||
|
//go:linkname CompileStringExFlags C.Py_CompileStringExFlags
|
||||||
|
func CompileStringExFlags(str, filename *c.Char, start InputType, flags *CompilerFlags, optimize c.Int) *Object
|
||||||
|
|
||||||
|
// Parse and compile the Python source code in str, returning the resulting code object.
|
||||||
|
// The start token is given by start; this can be used to constrain the code which can be
|
||||||
|
// compiled and should be py.EvalInput, py.FileInput, or py.SingleInput. The filename
|
||||||
|
// specified by filename is used to construct the code object and may appear in tracebacks
|
||||||
|
// or SyntaxError exception messages. This returns NULL if the code cannot be parsed or
|
||||||
|
// compiled.
|
||||||
|
//
|
||||||
|
// The integer optimize specifies the optimization level of the compiler; a value of -1
|
||||||
|
// selects the optimization level of the interpreter as given by -O options. Explicit levels
|
||||||
|
// are 0 (no optimization; __debug__ is true), 1 (asserts are removed, __debug__ is false) or
|
||||||
|
// 2 (docstrings are removed too).
|
||||||
|
//
|
||||||
|
//go:linkname CompileStringObject C.Py_CompileStringObject
|
||||||
|
func CompileStringObject(str *c.Char, filename *Object, start InputType, flags *CompilerFlags, optimize c.Int) *Object
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// This is a simplified interface to EvalCodeEx, with just the code object, and global and
|
||||||
|
// local variables. The other arguments are set to nil.
|
||||||
|
//
|
||||||
|
//go:linkname EvalCode C.PyEval_EvalCode
|
||||||
|
func EvalCode(code, globals, locals *Object) *Object
|
||||||
|
|
||||||
|
// Evaluate a precompiled code object, given a particular environment for its evaluation.
|
||||||
|
// This environment consists of a dictionary of global variables, a mapping object of local
|
||||||
|
// variables, arrays of arguments, keywords and defaults, a dictionary of default values for
|
||||||
|
// keyword-only arguments and a closure tuple of cells.
|
||||||
|
//
|
||||||
|
//go:linkname EvalCodeEx C.PyEval_EvalCodeEx
|
||||||
|
func EvalCodeEx(
|
||||||
|
code, globals, locals *Object,
|
||||||
|
args *Object, argcount c.Int, kws *Object, kwcount c.Int,
|
||||||
|
defs *Object, defcount c.Int, kwdefs, closure *Object) *Object
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
401
py/statistics/gen.go
Normal file
401
py/statistics/gen.go
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
package statistics
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LLGoPackage = "py.statistics"
|
||||||
|
|
||||||
|
// Error function at x.
|
||||||
|
//
|
||||||
|
//go:linkname Erf py.erf
|
||||||
|
func Erf(x *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the sample arithmetic mean of data.
|
||||||
|
//
|
||||||
|
// >>> mean([1, 2, 3, 4, 4])
|
||||||
|
// 2.8
|
||||||
|
//
|
||||||
|
// >>> from fractions import Fraction as F
|
||||||
|
// >>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)])
|
||||||
|
// Fraction(13, 21)
|
||||||
|
//
|
||||||
|
// >>> from decimal import Decimal as D
|
||||||
|
// >>> mean([D("0.5"), D("0.75"), D("0.625"), D("0.375")])
|
||||||
|
// Decimal('0.5625')
|
||||||
|
//
|
||||||
|
// If ``data`` is empty, StatisticsError will be raised.
|
||||||
|
//
|
||||||
|
//go:linkname Mean py.mean
|
||||||
|
func Mean(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Convert data to floats and compute the arithmetic mean.
|
||||||
|
//
|
||||||
|
// This runs faster than the mean() function and it always returns a float.
|
||||||
|
// If the input dataset is empty, it raises a StatisticsError.
|
||||||
|
//
|
||||||
|
// >>> fmean([3.5, 4.0, 5.25])
|
||||||
|
// 4.25
|
||||||
|
//
|
||||||
|
//go:linkname Fmean py.fmean
|
||||||
|
func Fmean(data *py.Object, weights *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Convert data to floats and compute the geometric mean.
|
||||||
|
//
|
||||||
|
// Raises a StatisticsError if the input dataset is empty,
|
||||||
|
// if it contains a zero, or if it contains a negative value.
|
||||||
|
//
|
||||||
|
// No special efforts are made to achieve exact results.
|
||||||
|
// (However, this may change in the future.)
|
||||||
|
//
|
||||||
|
// >>> round(geometric_mean([54, 24, 36]), 9)
|
||||||
|
// 36.0
|
||||||
|
//
|
||||||
|
//go:linkname GeometricMean py.geometric_mean
|
||||||
|
func GeometricMean(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the harmonic mean of data.
|
||||||
|
//
|
||||||
|
// The harmonic mean is the reciprocal of the arithmetic mean of the
|
||||||
|
// reciprocals of the data. It can be used for averaging ratios or
|
||||||
|
// rates, for example speeds.
|
||||||
|
//
|
||||||
|
// Suppose a car travels 40 km/hr for 5 km and then speeds-up to
|
||||||
|
// 60 km/hr for another 5 km. What is the average speed?
|
||||||
|
//
|
||||||
|
// >>> harmonic_mean([40, 60])
|
||||||
|
// 48.0
|
||||||
|
//
|
||||||
|
// Suppose a car travels 40 km/hr for 5 km, and when traffic clears,
|
||||||
|
// speeds-up to 60 km/hr for the remaining 30 km of the journey. What
|
||||||
|
// is the average speed?
|
||||||
|
//
|
||||||
|
// >>> harmonic_mean([40, 60], weights=[5, 30])
|
||||||
|
// 56.0
|
||||||
|
//
|
||||||
|
// If ``data`` is empty, or any element is less than zero,
|
||||||
|
// ``harmonic_mean`` will raise ``StatisticsError``.
|
||||||
|
//
|
||||||
|
//go:linkname HarmonicMean py.harmonic_mean
|
||||||
|
func HarmonicMean(data *py.Object, weights *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the median (middle value) of numeric data.
|
||||||
|
//
|
||||||
|
// When the number of data points is odd, return the middle data point.
|
||||||
|
// When the number of data points is even, the median is interpolated by
|
||||||
|
// taking the average of the two middle values:
|
||||||
|
//
|
||||||
|
// >>> median([1, 3, 5])
|
||||||
|
// 3
|
||||||
|
// >>> median([1, 3, 5, 7])
|
||||||
|
// 4.0
|
||||||
|
//
|
||||||
|
//go:linkname Median py.median
|
||||||
|
func Median(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the low median of numeric data.
|
||||||
|
//
|
||||||
|
// When the number of data points is odd, the middle value is returned.
|
||||||
|
// When it is even, the smaller of the two middle values is returned.
|
||||||
|
//
|
||||||
|
// >>> median_low([1, 3, 5])
|
||||||
|
// 3
|
||||||
|
// >>> median_low([1, 3, 5, 7])
|
||||||
|
// 3
|
||||||
|
//
|
||||||
|
//go:linkname MedianLow py.median_low
|
||||||
|
func MedianLow(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the high median of data.
|
||||||
|
//
|
||||||
|
// When the number of data points is odd, the middle value is returned.
|
||||||
|
// When it is even, the larger of the two middle values is returned.
|
||||||
|
//
|
||||||
|
// >>> median_high([1, 3, 5])
|
||||||
|
// 3
|
||||||
|
// >>> median_high([1, 3, 5, 7])
|
||||||
|
// 5
|
||||||
|
//
|
||||||
|
//go:linkname MedianHigh py.median_high
|
||||||
|
func MedianHigh(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Estimates the median for numeric data binned around the midpoints
|
||||||
|
//
|
||||||
|
// of consecutive, fixed-width intervals.
|
||||||
|
//
|
||||||
|
// The *data* can be any iterable of numeric data with each value being
|
||||||
|
// exactly the midpoint of a bin. At least one value must be present.
|
||||||
|
//
|
||||||
|
// The *interval* is width of each bin.
|
||||||
|
//
|
||||||
|
// For example, demographic information may have been summarized into
|
||||||
|
// consecutive ten-year age groups with each group being represented
|
||||||
|
// by the 5-year midpoints of the intervals:
|
||||||
|
//
|
||||||
|
// >>> demographics = Counter({
|
||||||
|
// ... 25: 172, # 20 to 30 years old
|
||||||
|
// ... 35: 484, # 30 to 40 years old
|
||||||
|
// ... 45: 387, # 40 to 50 years old
|
||||||
|
// ... 55: 22, # 50 to 60 years old
|
||||||
|
// ... 65: 6, # 60 to 70 years old
|
||||||
|
// ... })
|
||||||
|
//
|
||||||
|
// The 50th percentile (median) is the 536th person out of the 1071
|
||||||
|
// member cohort. That person is in the 30 to 40 year old age group.
|
||||||
|
//
|
||||||
|
// The regular median() function would assume that everyone in the
|
||||||
|
// tricenarian age group was exactly 35 years old. A more tenable
|
||||||
|
// assumption is that the 484 members of that age group are evenly
|
||||||
|
// distributed between 30 and 40. For that, we use median_grouped().
|
||||||
|
//
|
||||||
|
// >>> data = list(demographics.elements())
|
||||||
|
// >>> median(data)
|
||||||
|
// 35
|
||||||
|
// >>> round(median_grouped(data, interval=10), 1)
|
||||||
|
// 37.5
|
||||||
|
//
|
||||||
|
// The caller is responsible for making sure the data points are separated
|
||||||
|
// by exact multiples of *interval*. This is essential for getting a
|
||||||
|
// correct result. The function does not check this precondition.
|
||||||
|
//
|
||||||
|
// Inputs may be any numeric type that can be coerced to a float during
|
||||||
|
// the interpolation step.
|
||||||
|
//
|
||||||
|
//go:linkname MedianGrouped py.median_grouped
|
||||||
|
func MedianGrouped(data *py.Object, interval *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the most common data point from discrete or nominal data.
|
||||||
|
//
|
||||||
|
// ``mode`` assumes discrete data, and returns a single value. This is the
|
||||||
|
// standard treatment of the mode as commonly taught in schools:
|
||||||
|
//
|
||||||
|
// >>> mode([1, 1, 2, 3, 3, 3, 3, 4])
|
||||||
|
// 3
|
||||||
|
//
|
||||||
|
// This also works with nominal (non-numeric) data:
|
||||||
|
//
|
||||||
|
// >>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
|
||||||
|
// 'red'
|
||||||
|
//
|
||||||
|
// If there are multiple modes with same frequency, return the first one
|
||||||
|
// encountered:
|
||||||
|
//
|
||||||
|
// >>> mode(['red', 'red', 'green', 'blue', 'blue'])
|
||||||
|
// 'red'
|
||||||
|
//
|
||||||
|
// If *data* is empty, ``mode``, raises StatisticsError.
|
||||||
|
//
|
||||||
|
//go:linkname Mode py.mode
|
||||||
|
func Mode(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return a list of the most frequently occurring values.
|
||||||
|
//
|
||||||
|
// Will return more than one result if there are multiple modes
|
||||||
|
// or an empty list if *data* is empty.
|
||||||
|
//
|
||||||
|
// >>> multimode('aabbbbbbbbcc')
|
||||||
|
// ['b']
|
||||||
|
// >>> multimode('aabbbbccddddeeffffgg')
|
||||||
|
// ['b', 'd', 'f']
|
||||||
|
// >>> multimode('')
|
||||||
|
// []
|
||||||
|
//
|
||||||
|
//go:linkname Multimode py.multimode
|
||||||
|
func Multimode(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Divide *data* into *n* continuous intervals with equal probability.
|
||||||
|
//
|
||||||
|
// Returns a list of (n - 1) cut points separating the intervals.
|
||||||
|
//
|
||||||
|
// Set *n* to 4 for quartiles (the default). Set *n* to 10 for deciles.
|
||||||
|
// Set *n* to 100 for percentiles which gives the 99 cuts points that
|
||||||
|
// separate *data* in to 100 equal sized groups.
|
||||||
|
//
|
||||||
|
// The *data* can be any iterable containing sample.
|
||||||
|
// The cut points are linearly interpolated between data points.
|
||||||
|
//
|
||||||
|
// If *method* is set to *inclusive*, *data* is treated as population
|
||||||
|
// data. The minimum value is treated as the 0th percentile and the
|
||||||
|
// maximum value is treated as the 100th percentile.
|
||||||
|
//
|
||||||
|
//go:linkname Quantiles py.quantiles
|
||||||
|
func Quantiles(data *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the sample variance of data.
|
||||||
|
//
|
||||||
|
// data should be an iterable of Real-valued numbers, with at least two
|
||||||
|
// values. The optional argument xbar, if given, should be the mean of
|
||||||
|
// the data. If it is missing or None, the mean is automatically calculated.
|
||||||
|
//
|
||||||
|
// Use this function when your data is a sample from a population. To
|
||||||
|
// calculate the variance from the entire population, see ``pvariance``.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// >>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5]
|
||||||
|
// >>> variance(data)
|
||||||
|
// 1.3720238095238095
|
||||||
|
//
|
||||||
|
// If you have already calculated the mean of your data, you can pass it as
|
||||||
|
// the optional second argument ``xbar`` to avoid recalculating it:
|
||||||
|
//
|
||||||
|
// >>> m = mean(data)
|
||||||
|
// >>> variance(data, m)
|
||||||
|
// 1.3720238095238095
|
||||||
|
//
|
||||||
|
// This function does not check that ``xbar`` is actually the mean of
|
||||||
|
// ``data``. Giving arbitrary values for ``xbar`` may lead to invalid or
|
||||||
|
// impossible results.
|
||||||
|
//
|
||||||
|
// Decimals and Fractions are supported:
|
||||||
|
//
|
||||||
|
// >>> from decimal import Decimal as D
|
||||||
|
// >>> variance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")])
|
||||||
|
// Decimal('31.01875')
|
||||||
|
//
|
||||||
|
// >>> from fractions import Fraction as F
|
||||||
|
// >>> variance([F(1, 6), F(1, 2), F(5, 3)])
|
||||||
|
// Fraction(67, 108)
|
||||||
|
//
|
||||||
|
//go:linkname Variance py.variance
|
||||||
|
func Variance(data *py.Object, xbar *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the population variance of “data“.
|
||||||
|
//
|
||||||
|
// data should be a sequence or iterable of Real-valued numbers, with at least one
|
||||||
|
// value. The optional argument mu, if given, should be the mean of
|
||||||
|
// the data. If it is missing or None, the mean is automatically calculated.
|
||||||
|
//
|
||||||
|
// Use this function to calculate the variance from the entire population.
|
||||||
|
// To estimate the variance from a sample, the ``variance`` function is
|
||||||
|
// usually a better choice.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// >>> data = [0.0, 0.25, 0.25, 1.25, 1.5, 1.75, 2.75, 3.25]
|
||||||
|
// >>> pvariance(data)
|
||||||
|
// 1.25
|
||||||
|
//
|
||||||
|
// If you have already calculated the mean of the data, you can pass it as
|
||||||
|
// the optional second argument to avoid recalculating it:
|
||||||
|
//
|
||||||
|
// >>> mu = mean(data)
|
||||||
|
// >>> pvariance(data, mu)
|
||||||
|
// 1.25
|
||||||
|
//
|
||||||
|
// Decimals and Fractions are supported:
|
||||||
|
//
|
||||||
|
// >>> from decimal import Decimal as D
|
||||||
|
// >>> pvariance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")])
|
||||||
|
// Decimal('24.815')
|
||||||
|
//
|
||||||
|
// >>> from fractions import Fraction as F
|
||||||
|
// >>> pvariance([F(1, 4), F(5, 4), F(1, 2)])
|
||||||
|
// Fraction(13, 72)
|
||||||
|
//
|
||||||
|
//go:linkname Pvariance py.pvariance
|
||||||
|
func Pvariance(data *py.Object, mu *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the square root of the sample variance.
|
||||||
|
//
|
||||||
|
// See ``variance`` for arguments and other details.
|
||||||
|
//
|
||||||
|
// >>> stdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75])
|
||||||
|
// 1.0810874155219827
|
||||||
|
//
|
||||||
|
//go:linkname Stdev py.stdev
|
||||||
|
func Stdev(data *py.Object, xbar *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the square root of the population variance.
|
||||||
|
//
|
||||||
|
// See ``pvariance`` for arguments and other details.
|
||||||
|
//
|
||||||
|
// >>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75])
|
||||||
|
// 0.986893273527251
|
||||||
|
//
|
||||||
|
//go:linkname Pstdev py.pstdev
|
||||||
|
func Pstdev(data *py.Object, mu *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Covariance
|
||||||
|
//
|
||||||
|
// Return the sample covariance of two inputs *x* and *y*. Covariance
|
||||||
|
// is a measure of the joint variability of two inputs.
|
||||||
|
//
|
||||||
|
// >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
// >>> y = [1, 2, 3, 1, 2, 3, 1, 2, 3]
|
||||||
|
// >>> covariance(x, y)
|
||||||
|
// 0.75
|
||||||
|
// >>> z = [9, 8, 7, 6, 5, 4, 3, 2, 1]
|
||||||
|
// >>> covariance(x, z)
|
||||||
|
// -7.5
|
||||||
|
// >>> covariance(z, x)
|
||||||
|
// -7.5
|
||||||
|
//
|
||||||
|
//go:linkname Covariance py.covariance
|
||||||
|
func Covariance(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Pearson's correlation coefficient
|
||||||
|
//
|
||||||
|
// Return the Pearson's correlation coefficient for two inputs. Pearson's
|
||||||
|
// correlation coefficient *r* takes values between -1 and +1. It measures
|
||||||
|
// the strength and direction of a linear relationship.
|
||||||
|
//
|
||||||
|
// >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
// >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1]
|
||||||
|
// >>> correlation(x, x)
|
||||||
|
// 1.0
|
||||||
|
// >>> correlation(x, y)
|
||||||
|
// -1.0
|
||||||
|
//
|
||||||
|
// If *method* is "ranked", computes Spearman's rank correlation coefficient
|
||||||
|
// for two inputs. The data is replaced by ranks. Ties are averaged
|
||||||
|
// so that equal values receive the same rank. The resulting coefficient
|
||||||
|
// measures the strength of a monotonic relationship.
|
||||||
|
//
|
||||||
|
// Spearman's rank correlation coefficient is appropriate for ordinal
|
||||||
|
// data or for continuous data that doesn't meet the linear proportion
|
||||||
|
// requirement for Pearson's correlation coefficient.
|
||||||
|
//
|
||||||
|
//go:linkname Correlation py.correlation
|
||||||
|
func Correlation(x *py.Object, y *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Slope and intercept for simple linear regression.
|
||||||
|
//
|
||||||
|
// Return the slope and intercept of simple linear regression
|
||||||
|
// parameters estimated using ordinary least squares. Simple linear
|
||||||
|
// regression describes relationship between an independent variable
|
||||||
|
// *x* and a dependent variable *y* in terms of a linear function:
|
||||||
|
//
|
||||||
|
// y = slope * x + intercept + noise
|
||||||
|
//
|
||||||
|
// where *slope* and *intercept* are the regression parameters that are
|
||||||
|
// estimated, and noise represents the variability of the data that was
|
||||||
|
// not explained by the linear regression (it is equal to the
|
||||||
|
// difference between predicted and actual values of the dependent
|
||||||
|
// variable).
|
||||||
|
//
|
||||||
|
// The parameters are returned as a named tuple.
|
||||||
|
//
|
||||||
|
// >>> x = [1, 2, 3, 4, 5]
|
||||||
|
// >>> noise = NormalDist().samples(5, seed=42)
|
||||||
|
// >>> y = [3 * x[i] + 2 + noise[i] for i in range(5)]
|
||||||
|
// >>> linear_regression(x, y) #doctest: +ELLIPSIS
|
||||||
|
// LinearRegression(slope=3.09078914170..., intercept=1.75684970486...)
|
||||||
|
//
|
||||||
|
// If *proportional* is true, the independent variable *x* and the
|
||||||
|
// dependent variable *y* are assumed to be directly proportional.
|
||||||
|
// The data is fit to a line passing through the origin.
|
||||||
|
//
|
||||||
|
// Since the *intercept* will always be 0.0, the underlying linear
|
||||||
|
// function simplifies to:
|
||||||
|
//
|
||||||
|
// y = slope * x + noise
|
||||||
|
//
|
||||||
|
// >>> y = [3 * x[i] + noise[i] for i in range(5)]
|
||||||
|
// >>> linear_regression(x, y, proportional=True) #doctest: +ELLIPSIS
|
||||||
|
// LinearRegression(slope=3.02447542484..., intercept=0.0)
|
||||||
|
//
|
||||||
|
//go:linkname LinearRegression py.linear_regression
|
||||||
|
func LinearRegression(x *py.Object, y *py.Object) *py.Object
|
||||||
BIN
py/statistics/llgo_autogen.lla
Normal file
BIN
py/statistics/llgo_autogen.lla
Normal file
Binary file not shown.
220
py/sys/gen.go
Normal file
220
py/sys/gen.go
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
package sys
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/py"
|
||||||
|
)
|
||||||
|
|
||||||
|
const LLGoPackage = "py.sys"
|
||||||
|
|
||||||
|
// Adds a new audit hook callback.
|
||||||
|
//
|
||||||
|
//go:linkname Addaudithook py.addaudithook
|
||||||
|
func Addaudithook(hook *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Print an object to sys.stdout and also save it in builtins._
|
||||||
|
//
|
||||||
|
//go:linkname Displayhook py.displayhook
|
||||||
|
func Displayhook(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the current exception.
|
||||||
|
//
|
||||||
|
// Return the most recent exception caught by an except clause
|
||||||
|
// in the current stack frame or in an older stack frame, or None
|
||||||
|
// if no such exception exists.
|
||||||
|
//
|
||||||
|
//go:linkname Exception py.exception
|
||||||
|
func Exception() *py.Object
|
||||||
|
|
||||||
|
// Return current exception information: (type, value, traceback).
|
||||||
|
//
|
||||||
|
// Return information about the most recent exception caught by an except
|
||||||
|
// clause in the current stack frame or in an older stack frame.
|
||||||
|
//
|
||||||
|
//go:linkname ExcInfo py.exc_info
|
||||||
|
func ExcInfo() *py.Object
|
||||||
|
|
||||||
|
// Handle an exception by displaying it with a traceback on sys.stderr.
|
||||||
|
//
|
||||||
|
//go:linkname Excepthook py.excepthook
|
||||||
|
func Excepthook(exctype *py.Object, value *py.Object, traceback *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Exit the interpreter by raising SystemExit(status).
|
||||||
|
//
|
||||||
|
// If the status is omitted or None, it defaults to zero (i.e., success).
|
||||||
|
// If the status is an integer, it will be used as the system exit status.
|
||||||
|
// If it is another kind of object, it will be printed and the system
|
||||||
|
// exit status will be one (i.e., failure).
|
||||||
|
//
|
||||||
|
//go:linkname Exit py.exit
|
||||||
|
func Exit(status *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the current default encoding used by the Unicode implementation.
|
||||||
|
//
|
||||||
|
//go:linkname Getdefaultencoding py.getdefaultencoding
|
||||||
|
func Getdefaultencoding() *py.Object
|
||||||
|
|
||||||
|
// Return the current value of the flags that are used for dlopen calls.
|
||||||
|
//
|
||||||
|
// The flag constants are defined in the os module.
|
||||||
|
//
|
||||||
|
//go:linkname Getdlopenflags py.getdlopenflags
|
||||||
|
func Getdlopenflags() *py.Object
|
||||||
|
|
||||||
|
// Return the number of memory blocks currently allocated.
|
||||||
|
//
|
||||||
|
//go:linkname Getallocatedblocks py.getallocatedblocks
|
||||||
|
func Getallocatedblocks() *py.Object
|
||||||
|
|
||||||
|
// Return the number of elements of the unicode interned dictionary
|
||||||
|
//
|
||||||
|
//go:linkname Getunicodeinternedsize py.getunicodeinternedsize
|
||||||
|
func Getunicodeinternedsize() *py.Object
|
||||||
|
|
||||||
|
// Return the encoding used to convert Unicode filenames to OS filenames.
|
||||||
|
//
|
||||||
|
//go:linkname Getfilesystemencoding py.getfilesystemencoding
|
||||||
|
func Getfilesystemencoding() *py.Object
|
||||||
|
|
||||||
|
// Return the error mode used Unicode to OS filename conversion.
|
||||||
|
//
|
||||||
|
//go:linkname Getfilesystemencodeerrors py.getfilesystemencodeerrors
|
||||||
|
func Getfilesystemencodeerrors() *py.Object
|
||||||
|
|
||||||
|
// Return the reference count of object.
|
||||||
|
//
|
||||||
|
// The count returned is generally one higher than you might expect,
|
||||||
|
// because it includes the (temporary) reference as an argument to
|
||||||
|
// getrefcount().
|
||||||
|
//
|
||||||
|
//go:linkname Getrefcount py.getrefcount
|
||||||
|
func Getrefcount(object *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the current value of the recursion limit.
|
||||||
|
//
|
||||||
|
// The recursion limit is the maximum depth of the Python interpreter
|
||||||
|
// stack. This limit prevents infinite recursion from causing an overflow
|
||||||
|
// of the C stack and crashing Python.
|
||||||
|
//
|
||||||
|
//go:linkname Getrecursionlimit py.getrecursionlimit
|
||||||
|
func Getrecursionlimit() *py.Object
|
||||||
|
|
||||||
|
// “Intern” the given string.
|
||||||
|
//
|
||||||
|
// This enters the string in the (global) table of interned strings whose
|
||||||
|
// purpose is to speed up dictionary lookups. Return the string itself or
|
||||||
|
// the previously interned string object with the same value.
|
||||||
|
//
|
||||||
|
//go:linkname Intern py.intern
|
||||||
|
func Intern(string *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return True if Python is exiting.
|
||||||
|
//
|
||||||
|
//go:linkname IsFinalizing py.is_finalizing
|
||||||
|
func IsFinalizing() *py.Object
|
||||||
|
|
||||||
|
// Set the ideal thread switching delay inside the Python interpreter.
|
||||||
|
//
|
||||||
|
// The actual frequency of switching threads can be lower if the
|
||||||
|
// interpreter executes long sequences of uninterruptible code
|
||||||
|
// (this is implementation-specific and workload-dependent).
|
||||||
|
//
|
||||||
|
// The parameter must represent the desired switching delay in seconds
|
||||||
|
// A typical value is 0.005 (5 milliseconds).
|
||||||
|
//
|
||||||
|
//go:linkname Setswitchinterval py.setswitchinterval
|
||||||
|
func Setswitchinterval(interval *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the current thread switch interval; see sys.setswitchinterval().
|
||||||
|
//
|
||||||
|
//go:linkname Getswitchinterval py.getswitchinterval
|
||||||
|
func Getswitchinterval() *py.Object
|
||||||
|
|
||||||
|
// Set the flags used by the interpreter for dlopen calls.
|
||||||
|
//
|
||||||
|
// This is used, for example, when the interpreter loads extension
|
||||||
|
// modules. Among other things, this will enable a lazy resolving of
|
||||||
|
// symbols when importing a module, if called as sys.setdlopenflags(0).
|
||||||
|
// To share symbols across extension modules, call as
|
||||||
|
// sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag
|
||||||
|
// modules can be found in the os module (RTLD_xxx constants, e.g.
|
||||||
|
// os.RTLD_LAZY).
|
||||||
|
//
|
||||||
|
//go:linkname Setdlopenflags py.setdlopenflags
|
||||||
|
func Setdlopenflags(flags *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Set the maximum depth of the Python interpreter stack to n.
|
||||||
|
//
|
||||||
|
// This limit prevents infinite recursion from causing an overflow of the C
|
||||||
|
// stack and crashing Python. The highest possible limit is platform-
|
||||||
|
// dependent.
|
||||||
|
//
|
||||||
|
//go:linkname Setrecursionlimit py.setrecursionlimit
|
||||||
|
func Setrecursionlimit(limit *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the global debug tracing function set with sys.settrace.
|
||||||
|
//
|
||||||
|
// See the debugger chapter in the library manual.
|
||||||
|
//
|
||||||
|
//go:linkname Gettrace py.gettrace
|
||||||
|
func Gettrace() *py.Object
|
||||||
|
|
||||||
|
// Call func(*args), while tracing is enabled.
|
||||||
|
//
|
||||||
|
// The tracing state is saved, and restored afterwards. This is intended
|
||||||
|
// to be called from a debugger from a checkpoint, to recursively debug
|
||||||
|
// some other code.
|
||||||
|
//
|
||||||
|
//go:linkname CallTracing py.call_tracing
|
||||||
|
func CallTracing(func_ *py.Object, args *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Enable or disable origin tracking for coroutine objects in this thread.
|
||||||
|
//
|
||||||
|
// Coroutine objects will track 'depth' frames of traceback information
|
||||||
|
// about where they came from, available in their cr_origin attribute.
|
||||||
|
//
|
||||||
|
// Set a depth of 0 to disable.
|
||||||
|
//
|
||||||
|
//go:linkname SetCoroutineOriginTrackingDepth py.set_coroutine_origin_tracking_depth
|
||||||
|
func SetCoroutineOriginTrackingDepth(depth *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Check status of origin tracking for coroutine objects in this thread.
|
||||||
|
//
|
||||||
|
//go:linkname GetCoroutineOriginTrackingDepth py.get_coroutine_origin_tracking_depth
|
||||||
|
func GetCoroutineOriginTrackingDepth() *py.Object
|
||||||
|
|
||||||
|
// Deactivate the current stack profiler trampoline backend.
|
||||||
|
//
|
||||||
|
// If no stack profiler is activated, this function has no effect.
|
||||||
|
//
|
||||||
|
//go:linkname DeactivateStackTrampoline py.deactivate_stack_trampoline
|
||||||
|
func DeactivateStackTrampoline() *py.Object
|
||||||
|
|
||||||
|
// Return *True* if a stack profiler trampoline is active.
|
||||||
|
//
|
||||||
|
//go:linkname IsStackTrampolineActive py.is_stack_trampoline_active
|
||||||
|
func IsStackTrampolineActive() *py.Object
|
||||||
|
|
||||||
|
// Handle an unraisable exception.
|
||||||
|
//
|
||||||
|
// The unraisable argument has the following attributes:
|
||||||
|
//
|
||||||
|
// * exc_type: Exception type.
|
||||||
|
// * exc_value: Exception value, can be None.
|
||||||
|
// * exc_traceback: Exception traceback, can be None.
|
||||||
|
// * err_msg: Error message, can be None.
|
||||||
|
// * object: Object causing the exception, can be None.
|
||||||
|
//
|
||||||
|
//go:linkname Unraisablehook py.unraisablehook
|
||||||
|
func Unraisablehook(unraisable *py.Object) *py.Object
|
||||||
|
|
||||||
|
// Return the maximum string digits limit for non-binary int<->str conversions.
|
||||||
|
//
|
||||||
|
//go:linkname GetIntMaxStrDigits py.get_int_max_str_digits
|
||||||
|
func GetIntMaxStrDigits() *py.Object
|
||||||
|
|
||||||
|
// Set the maximum string digits limit for non-binary int<->str conversions.
|
||||||
|
//
|
||||||
|
//go:linkname SetIntMaxStrDigits py.set_int_max_str_digits
|
||||||
|
func SetIntMaxStrDigits(maxdigits *py.Object) *py.Object
|
||||||
BIN
py/sys/llgo_autogen.lla
Normal file
BIN
py/sys/llgo_autogen.lla
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user