Merge branch 'main' into main_return_0

This commit is contained in:
xushiwei
2024-05-17 11:05:09 +08:00
committed by GitHub
22 changed files with 8773 additions and 152 deletions

View File

@@ -46,7 +46,7 @@ See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for
You can import a Python library in LLGo!
And you can import any Python library into `llgo` through a program called `llpyg` (See [Development tools](#development-tools)). The currently imported libraries include:
And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). 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)

View File

@@ -29,6 +29,7 @@ import (
"strings"
"github.com/goplus/gogen"
"github.com/goplus/llgo/chore/llpyg/pysig"
"github.com/goplus/llgo/ssa"
)
@@ -109,12 +110,12 @@ func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) {
if len(name) == 0 || name[0] == '_' {
return
}
params, variadic, skip := ctx.genParams(pkg, symSig)
if skip {
if symSig == "<NULL>" {
// TODO(xsw): don't skip any func
log.Println("skip func:", name, symSig)
return
}
params, variadic := ctx.genParams(pkg, symSig)
name = genName(name, -1)
sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic)
fn := pkg.NewFuncDecl(token.NoPos, name, sig)
@@ -125,43 +126,32 @@ func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) {
// fn.BodyStart(pkg).End()
}
func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool, bool) {
if sig == "<NULL>" {
return nil, false, true
func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool) {
args := pysig.Parse(sig)
if len(args) == 0 {
return nil, false
}
sig = strings.TrimSuffix(strings.TrimPrefix(sig, "("), ")")
if sig == "" { // empty params
return nil, false, false
}
parts := strings.Split(sig, ",")
n := len(parts)
n := len(args)
objPtr := ctx.objPtr
list := make([]*types.Var, 0, n)
for i := 0; i < n; i++ {
part := strings.TrimSpace(parts[i])
if part == "/" {
name := args[i].Name
if name == "/" {
continue
}
if part == "*" {
if name == "*" {
break
}
if strings.HasPrefix(part, "*") {
if part[1] != '*' {
if strings.HasPrefix(name, "*") {
if name[1] != '*' {
list = append(list, ssa.VArg())
return types.NewTuple(list...), true, false
return types.NewTuple(list...), true
}
return types.NewTuple(list...), false, false
return types.NewTuple(list...), 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))
list = append(list, pkg.NewParam(0, genName(name, 0), objPtr))
}
return types.NewTuple(list...), false, false
return types.NewTuple(list...), false
}
func genName(name string, idxDontTitle int) string {

100
chore/llpyg/pysig/parse.go Normal file
View File

@@ -0,0 +1,100 @@
/*
* 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 pysig
import (
"strings"
)
type Arg struct {
Name string
Type string
DefVal string
}
// Parse parses a Python function signature.
func Parse(sig string) (args []*Arg) {
sig = strings.TrimPrefix(sig, "(")
for {
pos := strings.IndexAny(sig, ",:=)")
if pos <= 0 {
return
}
arg := &Arg{Name: strings.TrimSpace(sig[:pos])}
args = append(args, arg)
c := sig[pos]
sig = sig[pos+1:]
switch c {
case ',':
continue
case ':':
arg.Type, sig = parseType(sig)
if strings.HasPrefix(sig, "=") {
arg.DefVal, sig = parseDefVal(sig[1:])
}
case '=':
arg.DefVal, sig = parseDefVal(sig)
case ')':
return
}
sig = strings.TrimPrefix(sig, ",")
}
}
const (
allSpecials = "([<'\""
)
var pairStops = map[byte]string{
'(': ")" + allSpecials,
'[': "]" + allSpecials,
'<': ">" + allSpecials,
'\'': "'" + allSpecials,
'"': "\"",
}
func parseText(sig string, stops string) (left string) {
for {
pos := strings.IndexAny(sig, stops)
if pos < 0 {
return sig
}
if c := sig[pos]; c != stops[0] {
if pstop, ok := pairStops[c]; ok {
sig = strings.TrimPrefix(parseText(sig[pos+1:], pstop), pstop[:1])
continue
}
}
return sig[pos:]
}
}
// stops: "=,)"
func parseType(sig string) (string, string) {
left := parseText(sig, "=,)"+allSpecials)
return resultOf(sig, left), left
}
// stops: ",)"
func parseDefVal(sig string) (string, string) {
left := parseText(sig, ",)"+allSpecials)
return resultOf(sig, left), left
}
func resultOf(sig, left string) string {
return strings.TrimSpace(sig[:len(sig)-len(left)])
}

View File

@@ -0,0 +1,52 @@
/*
* 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 pysig
import "testing"
func TestParse(t *testing.T) {
type testCase struct {
sig string
args []*Arg
}
cases := []testCase{
{"(start=None, *, unit: 'str | None' = None) -> 'TimedeltaIndex'", []*Arg{
{Name: "start", DefVal: "None"},
{Name: "*"},
{Name: "unit", Type: "'str | None'", DefVal: "None"},
}},
{"()", nil},
{"(a =", []*Arg{{Name: "a"}}},
{"(a) -> int", []*Arg{{Name: "a"}}},
{"(a: int)", []*Arg{{Name: "a", Type: "int"}}},
{"(a: int = 1, b: float)", []*Arg{{Name: "a", Type: "int", DefVal: "1"}, {Name: "b", Type: "float"}}},
{"(a = <1>, b = 2.0)", []*Arg{{Name: "a", DefVal: "<1>"}, {Name: "b", DefVal: "2.0"}}},
{"(a: 'Suffixes' = ('_x', '_y'))", []*Arg{{Name: "a", Type: "'Suffixes'", DefVal: "('_x', '_y')"}}},
}
for _, c := range cases {
args := Parse(c.sig)
if len(args) != len(c.args) {
t.Fatalf("%s: len(args) = %v, want %v", c.sig, len(args), len(c.args))
}
for i, arg := range args {
want := c.args[i]
if arg.Name != want.Name || arg.Type != want.Type || arg.DefVal != want.DefVal {
t.Fatalf("%s: args[%v] = %v, want %v", c.sig, i, arg, want)
}
}
}
}

View File

@@ -322,7 +322,7 @@ _llgo_15: ; preds = %_llgo_13
br i1 %40, label %_llgo_16, label %_llgo_17
_llgo_16: ; preds = %_llgo_15
%41 = sext i8 %39 to i64
%41 = zext i8 %39 to i64
call void @main.printuint(i64 %41)
br label %_llgo_1
@@ -335,7 +335,7 @@ _llgo_17: ; preds = %_llgo_15
br i1 %46, label %_llgo_18, label %_llgo_19
_llgo_18: ; preds = %_llgo_17
%47 = sext i16 %45 to i64
%47 = zext i16 %45 to i64
call void @main.printuint(i64 %47)
br label %_llgo_1
@@ -348,7 +348,7 @@ _llgo_19: ; preds = %_llgo_17
br i1 %52, label %_llgo_20, label %_llgo_21
_llgo_20: ; preds = %_llgo_19
%53 = sext i32 %51 to i64
%53 = zext i32 %51 to i64
call void @main.printuint(i64 %53)
br label %_llgo_1

View File

@@ -25,5 +25,5 @@ func main() {
data = append(data, "def"...)
println(data)
var i any = 100
println(true, 100, -100, uint(100), int32(-100), 100.5, i, &i, uintptr(unsafe.Pointer(&i)))
println(true, 100, -100, uint(255), int32(-100), 100.5, i, &i, uintptr(unsafe.Pointer(&i)))
}

View File

@@ -292,7 +292,7 @@ _llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 -100)
%129 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @37, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %129)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 100)
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 255)
%130 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @38, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %130)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 -100)

View File

@@ -199,7 +199,7 @@ _llgo_2: ; preds = %_llgo_0
define void @main.cvtUinptr(i32 %0, i64 %1) {
_llgo_0:
%2 = sext i32 %0 to i64
%2 = zext i32 %0 to i64
%3 = icmp ne i64 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2

View File

@@ -2,7 +2,41 @@ package main
func main() {
println(mask(1))
println(mask_shl(127, 5))
println(mask_shl8(127, 5))
println(mask_shl8u(127, 5))
println(mask_shl8(127, 16))
println(mask_shl8u(127, 16))
println(mask_shr(127, 5))
println(mask_shr8(127, 5))
println(mask_shr8u(127, 5))
println(mask_shr8(127, 16))
}
func mask(x int8) int32 {
return int32(x) << 31 >> 31
}
func mask_shl8(x int8, y int) int8 {
return x << y
}
func mask_shl8u(x uint8, y int) uint8 {
return x << y
}
func mask_shl(x int, y int) int {
return x << y
}
func mask_shr8(x int8, y int) int8 {
return x >> y
}
func mask_shr8u(x uint8, y int) uint8 {
return x >> y
}
func mask_shr(x int, y int) int {
return x >> y
}

View File

@@ -7,6 +7,21 @@ source_filename = "main"
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@0 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@2 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@3 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@4 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@5 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@6 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@7 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@8 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@9 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@10 = private unnamed_addr constant [22 x i8] c"negative shift amount\00", align 1
@11 = private unnamed_addr constant [22 x i8] c"negative shift amount\00", align 1
@12 = private unnamed_addr constant [22 x i8] c"negative shift amount\00", align 1
@13 = private unnamed_addr constant [22 x i8] c"negative shift amount\00", align 1
@14 = private unnamed_addr constant [22 x i8] c"negative shift amount\00", align 1
@15 = private unnamed_addr constant [22 x i8] c"negative shift amount\00", align 1
define void @main.init() {
_llgo_0:
@@ -32,6 +47,49 @@ _llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %3)
%4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4)
%5 = call i64 @main.mask_shl(i64 127, i64 5)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %5)
%6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %6)
%7 = call i8 @main.mask_shl8(i8 127, i64 5)
%8 = sext i8 %7 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %8)
%9 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %9)
%10 = call i8 @main.mask_shl8u(i8 127, i64 5)
%11 = zext i8 %10 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %11)
%12 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %12)
%13 = call i8 @main.mask_shl8(i8 127, i64 16)
%14 = sext i8 %13 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %14)
%15 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %15)
%16 = call i8 @main.mask_shl8u(i8 127, i64 16)
%17 = zext i8 %16 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %17)
%18 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %18)
%19 = call i64 @main.mask_shr(i64 127, i64 5)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %19)
%20 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %20)
%21 = call i8 @main.mask_shr8(i8 127, i64 5)
%22 = sext i8 %21 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %22)
%23 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %23)
%24 = call i8 @main.mask_shr8u(i8 127, i64 5)
%25 = zext i8 %24 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %25)
%26 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %26)
%27 = call i8 @main.mask_shr8(i8 127, i64 16)
%28 = sext i8 %27 to i64
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %28)
%29 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 1)
call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %29)
ret i32 0
}
@@ -39,8 +97,79 @@ define i32 @main.mask(i8 %0) {
_llgo_0:
%1 = sext i8 %0 to i32
%2 = shl i32 %1, 31
%3 = ashr i32 %2, 31
ret i32 %3
%3 = select i1 false, i32 0, i32 %2
%4 = ashr i32 %3, 31
ret i32 %4
}
define i64 @main.mask_shl(i64 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 21)
call void @"github.com/goplus/llgo/internal/runtime.CheckRuntimeError"(i1 %2, %"github.com/goplus/llgo/internal/runtime.String" %3)
%4 = icmp uge i64 %1, 64
%5 = shl i64 %0, %1
%6 = select i1 %4, i64 0, i64 %5
ret i64 %6
}
define i8 @main.mask_shl8(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @11, i64 21)
call void @"github.com/goplus/llgo/internal/runtime.CheckRuntimeError"(i1 %2, %"github.com/goplus/llgo/internal/runtime.String" %3)
%4 = trunc i64 %1 to i8
%5 = icmp uge i8 %4, 8
%6 = shl i8 %0, %4
%7 = select i1 %5, i8 0, i8 %6
ret i8 %7
}
define i8 @main.mask_shl8u(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @12, i64 21)
call void @"github.com/goplus/llgo/internal/runtime.CheckRuntimeError"(i1 %2, %"github.com/goplus/llgo/internal/runtime.String" %3)
%4 = trunc i64 %1 to i8
%5 = icmp uge i8 %4, 8
%6 = shl i8 %0, %4
%7 = select i1 %5, i8 0, i8 %6
ret i8 %7
}
define i64 @main.mask_shr(i64 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @13, i64 21)
call void @"github.com/goplus/llgo/internal/runtime.CheckRuntimeError"(i1 %2, %"github.com/goplus/llgo/internal/runtime.String" %3)
%4 = icmp uge i64 %1, 64
%5 = select i1 %4, i64 63, i64 %1
%6 = ashr i64 %0, %5
ret i64 %6
}
define i8 @main.mask_shr8(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @14, i64 21)
call void @"github.com/goplus/llgo/internal/runtime.CheckRuntimeError"(i1 %2, %"github.com/goplus/llgo/internal/runtime.String" %3)
%4 = trunc i64 %1 to i8
%5 = icmp uge i8 %4, 8
%6 = select i1 %5, i8 7, i8 %4
%7 = ashr i8 %0, %6
ret i8 %7
}
define i8 @main.mask_shr8u(i8 %0, i64 %1) {
_llgo_0:
%2 = icmp slt i64 %1, 0
%3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @15, i64 21)
call void @"github.com/goplus/llgo/internal/runtime.CheckRuntimeError"(i1 %2, %"github.com/goplus/llgo/internal/runtime.String" %3)
%4 = trunc i64 %1 to i8
%5 = icmp uge i8 %4, 8
%6 = lshr i8 %0, %4
%7 = select i1 %5, i8 0, i8 %6
ret i8 %7
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
@@ -50,3 +179,7 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"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 void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.CheckRuntimeError"(i1, %"github.com/goplus/llgo/internal/runtime.String")

Binary file not shown.

View File

@@ -209,7 +209,7 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
dir, lib := filepath.Split(linkFile)
command := " -l " + lib
if dir != "" {
command += " -L " + dir
command += " -L " + dir[:len(dir)-1]
}
if isSingleLinkFile(pkg.ExportFile) {
pkg.ExportFile = command + " " + pkg.ExportFile

15
internal/runtime/error.go Normal file
View File

@@ -0,0 +1,15 @@
package runtime
type errorString string
func (e errorString) RuntimeError() {}
func (e errorString) Error() string {
return "runtime error: " + string(e)
}
func CheckRuntimeError(b bool, s string) {
if b {
panic(errorString(s).Error())
}
}

Binary file not shown.

View File

@@ -111,6 +111,102 @@ func ShowConfig(mode *py.Object) *py.Object
//go:linkname Isfortran py.isfortran
func Isfortran(a *py.Object) *py.Object
// Return an array representing the indices of a grid.
//
// Compute an array where the subarrays contain index values 0, 1, ...
// varying only along the corresponding axis.
//
// Parameters
// ----------
// dimensions : sequence of ints
//
// The shape of the grid.
//
// dtype : dtype, optional
//
// Data type of the result.
//
// sparse : boolean, optional
//
// Return a sparse representation of the grid instead of a dense
// representation. Default is False.
//
// .. versionadded:: 1.17
//
// Returns
// -------
// grid : one ndarray or tuple of ndarrays
//
// If sparse is False:
// Returns one array of grid indices,
// ``grid.shape = (len(dimensions),) + tuple(dimensions)``.
// If sparse is True:
// Returns a tuple of arrays, with
// ``grid[i].shape = (1, ..., 1, dimensions[i], 1, ..., 1)`` with
// dimensions[i] in the ith place
//
// See Also
// --------
// mgrid, ogrid, meshgrid
//
// Notes
// -----
// The output shape in the dense case is obtained by prepending the number
// of dimensions in front of the tuple of dimensions, i.e. if `dimensions`
// is a tuple “(r0, ..., rN-1)“ of length “N“, the output shape is
// “(N, r0, ..., rN-1)“.
//
// The subarrays “grid[k]“ contains the N-D array of indices along the
// “k-th“ axis. Explicitly::
//
// grid[k, i0, i1, ..., iN-1] = ik
//
// Examples
// --------
// >>> grid = np.indices((2, 3))
// >>> grid.shape
// (2, 2, 3)
// >>> grid[0] # row indices
// array([[0, 0, 0],
//
// [1, 1, 1]])
//
// >>> grid[1] # column indices
// array([[0, 1, 2],
//
// [0, 1, 2]])
//
// The indices can be used as an index into an array.
//
// >>> x = np.arange(20).reshape(5, 4)
// >>> row, col = np.indices((2, 3))
// >>> x[row, col]
// array([[0, 1, 2],
//
// [4, 5, 6]])
//
// Note that it would be more straightforward in the above example to
// extract the required elements directly with “x[:2, :3]“.
//
// If sparse is set to true, the grid will be returned in a sparse
// representation.
//
// >>> i, j = np.indices((2, 3), sparse=True)
// >>> i.shape
// (2, 1)
// >>> j.shape
// (1, 3)
// >>> i # row indices
// array([[0],
//
// [1]])
//
// >>> j # column indices
// array([[0, 1, 2]])
//
//go:linkname Indices py.indices
func Indices(dimensions *py.Object, dtype *py.Object, sparse *py.Object) *py.Object
// Construct an array by executing a function over each coordinate.
//
// The resulting array therefore has a value “fn(x, y, z)“ at
@@ -3458,67 +3554,6 @@ func Frexp(__llgo_va_list ...interface{}) *py.Object
//go:linkname Gcd py.gcd
func Gcd(__llgo_va_list ...interface{}) *py.Object
// greater_equal(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
//
// Return the truth value of (x1 >= x2) element-wise.
//
// Parameters
// ----------
// x1, x2 : array_like
//
// Input arrays.
// If ``x1.shape != x2.shape``, they must be broadcastable to a common
// shape (which becomes the shape of the output).
//
// out : ndarray, None, or tuple of ndarray and None, optional
//
// A location into which the result is stored. If provided, it must have
// a shape that the inputs broadcast to. If not provided or None,
// a freshly-allocated array is returned. A tuple (possible only as a
// keyword argument) must have length equal to the number of outputs.
//
// where : array_like, optional
//
// This condition is broadcast over the input. At locations where the
// condition is True, the `out` array will be set to the ufunc result.
// Elsewhere, the `out` array will retain its original value.
// Note that if an uninitialized `out` array is created via the default
// ``out=None``, locations within it where the condition is False will
// remain uninitialized.
//
// **kwargs
//
// For other keyword-only arguments, see the
// :ref:`ufunc docs <ufuncs.kwargs>`.
//
// Returns
// -------
// out : bool or ndarray of bool
//
// Output array, element-wise comparison of `x1` and `x2`.
// Typically of type bool, unless ``dtype=object`` is passed.
// This is a scalar if both `x1` and `x2` are scalars.
//
// See Also
// --------
// greater, less, less_equal, equal, not_equal
//
// Examples
// --------
// >>> np.greater_equal([4, 2, 1], [2, 2, 2])
// array([ True, True, False])
//
// The “>=“ operator can be used as a shorthand for “np.greater_equal“
// on ndarrays.
//
// >>> a = np.array([4, 2, 1])
// >>> b = np.array([2, 2, 2])
// >>> a >= b
// array([ True, True, False])
//
//go:linkname GreaterEqual py.greater_equal
func GreaterEqual(__llgo_va_list ...interface{}) *py.Object
// heaviside(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
//
// Compute the Heaviside step function.
@@ -6204,6 +6239,70 @@ func RightShift(__llgo_va_list ...interface{}) *py.Object
//go:linkname Rint py.rint
func Rint(__llgo_va_list ...interface{}) *py.Object
// sign(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
//
// Returns an element-wise indication of the sign of a number.
//
// The `sign` function returns “-1 if x < 0, 0 if x==0, 1 if x > 0“. nan
// is returned for nan inputs.
//
// For complex inputs, the `sign` function returns
// “sign(x.real) + 0j if x.real != 0 else sign(x.imag) + 0j“.
//
// complex(nan, 0) is returned for complex nan inputs.
//
// Parameters
// ----------
// x : array_like
//
// Input values.
//
// out : ndarray, None, or tuple of ndarray and None, optional
//
// A location into which the result is stored. If provided, it must have
// a shape that the inputs broadcast to. If not provided or None,
// a freshly-allocated array is returned. A tuple (possible only as a
// keyword argument) must have length equal to the number of outputs.
//
// where : array_like, optional
//
// This condition is broadcast over the input. At locations where the
// condition is True, the `out` array will be set to the ufunc result.
// Elsewhere, the `out` array will retain its original value.
// Note that if an uninitialized `out` array is created via the default
// ``out=None``, locations within it where the condition is False will
// remain uninitialized.
//
// **kwargs
//
// For other keyword-only arguments, see the
// :ref:`ufunc docs <ufuncs.kwargs>`.
//
// Returns
// -------
// y : ndarray
//
// The sign of `x`.
// This is a scalar if `x` is a scalar.
//
// Notes
// -----
// There is more than one definition of sign in common use for complex
// numbers. The definition used here is equivalent to :math:`x/\sqrt{x*x}`
// which is different from a common alternative, :math:`x/|x|`.
//
// Examples
// --------
// >>> np.sign([-5., 4.5])
// array([-1., 1.])
// >>> np.sign(0)
// 0
// >>> np.sign(5-2j)
// (1+0j)
//
//go:linkname Sign py.sign
func Sign(__llgo_va_list ...interface{}) *py.Object
// signbit(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
//
// Returns element-wise True where signbit is set (less than zero).
@@ -9017,6 +9116,130 @@ func GetArrayWrap(__llgo_va_list ...interface{}) *py.Object
//go:linkname BroadcastShapes py.broadcast_shapes
func BroadcastShapes(__llgo_va_list ...interface{}) *py.Object
// Return a 2-D array with ones on the diagonal and zeros elsewhere.
//
// Parameters
// ----------
// N : int
//
// Number of rows in the output.
//
// M : int, optional
//
// Number of columns in the output. If None, defaults to `N`.
//
// k : int, optional
//
// Index of the diagonal: 0 (the default) refers to the main diagonal,
// a positive value refers to an upper diagonal, and a negative value
// to a lower diagonal.
//
// dtype : data-type, optional
//
// Data-type of the returned array.
//
// order : {'C', 'F'}, optional
//
// Whether the output should be stored in row-major (C-style) or
// column-major (Fortran-style) order in memory.
//
// .. versionadded:: 1.14.0
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// I : ndarray of shape (N,M)
//
// An array where all elements are equal to zero, except for the `k`-th
// diagonal, whose values are equal to one.
//
// See Also
// --------
// identity : (almost) equivalent function
// diag : diagonal 2-D array from a 1-D array specified by the user.
//
// Examples
// --------
// >>> np.eye(2, dtype=int)
// array([[1, 0],
//
// [0, 1]])
//
// >>> np.eye(3, k=1)
// array([[0., 1., 0.],
//
// [0., 0., 1.],
// [0., 0., 0.]])
//
//go:linkname Eye py.eye
func Eye(N *py.Object, M *py.Object, k *py.Object, dtype *py.Object, order *py.Object) *py.Object
// An array with ones at and below the given diagonal and zeros elsewhere.
//
// Parameters
// ----------
// N : int
//
// Number of rows in the array.
//
// M : int, optional
//
// Number of columns in the array.
// By default, `M` is taken equal to `N`.
//
// k : int, optional
//
// The sub-diagonal at and below which the array is filled.
// `k` = 0 is the main diagonal, while `k` < 0 is below it,
// and `k` > 0 is above. The default is 0.
//
// dtype : dtype, optional
//
// Data type of the returned array. The default is float.
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// tri : ndarray of shape (N, M)
//
// Array with its lower triangle filled with ones and zero elsewhere;
// in other words ``T[i,j] == 1`` for ``j <= i + k``, 0 otherwise.
//
// Examples
// --------
// >>> np.tri(3, 5, 2, dtype=int)
// array([[1, 1, 1, 0, 0],
//
// [1, 1, 1, 1, 0],
// [1, 1, 1, 1, 1]])
//
// >>> np.tri(3, 5, -1)
// array([[0., 0., 0., 0., 0.],
//
// [1., 0., 0., 0., 0.],
// [1., 1., 0., 0., 0.]])
//
//go:linkname Tri py.tri
func Tri(N *py.Object, M *py.Object, k *py.Object, dtype *py.Object) *py.Object
// Return the indices to access (n, n) arrays, given a masking function.
//
// Assume `mask_func` is a function that, for a square array a of size
@@ -9502,6 +9725,49 @@ func GetInclude() *py.Object
//go:linkname Info py.info
func Info(object *py.Object, maxwidth *py.Object, output *py.Object, toplevel *py.Object) *py.Object
// Print or write to a file the source code for a NumPy object.
//
// The source code is only returned for objects written in Python. Many
// functions and classes are defined in C and will therefore not return
// useful information.
//
// Parameters
// ----------
// object : numpy object
//
// Input object. This can be any object (function, class, module,
// ...).
//
// output : file object, optional
//
// If `output` not supplied then source code is printed to screen
// (sys.stdout). File object must be created with either write 'w' or
// append 'a' modes.
//
// See Also
// --------
// lookfor, info
//
// Examples
// --------
// >>> np.source(np.interp) #doctest: +SKIP
// In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py
// def interp(x, xp, fp, left=None, right=None):
//
// """.... (full docstring printed)"""
// if isinstance(x, (float, int, number)):
// return compiled_interp([x], xp, fp, left, right).item()
// else:
// return compiled_interp(x, xp, fp, left, right)
//
// The source code is only returned for objects written in Python.
//
// >>> np.source(np.array) #doctest: +SKIP
// Not available for this object.
//
//go:linkname Source py.source
func Source(object *py.Object, output *py.Object) *py.Object
// Print the NumPy arrays in the given dictionary.
//
// If there is no dictionary passed in or `vardict` is None then returns
@@ -9718,6 +9984,538 @@ func SafeEval(source *py.Object) *py.Object
//go:linkname ShowRuntime py.show_runtime
func ShowRuntime() *py.Object
// Load data from a text file.
//
// Parameters
// ----------
// fname : file, str, pathlib.Path, list of str, generator
//
// File, filename, list, or generator to read. If the filename
// extension is ``.gz`` or ``.bz2``, the file is first decompressed. Note
// that generators must return bytes or strings. The strings
// in a list or produced by a generator are treated as lines.
//
// dtype : data-type, optional
//
// Data-type of the resulting array; default: float. If this is a
// structured data-type, the resulting array will be 1-dimensional, and
// each row will be interpreted as an element of the array. In this
// case, the number of columns used must match the number of fields in
// the data-type.
//
// comments : str or sequence of str or None, optional
//
// The characters or list of characters used to indicate the start of a
// comment. None implies no comments. For backwards compatibility, byte
// strings will be decoded as 'latin1'. The default is '#'.
//
// delimiter : str, optional
//
// The character used to separate the values. For backwards compatibility,
// byte strings will be decoded as 'latin1'. The default is whitespace.
//
// .. versionchanged:: 1.23.0
// Only single character delimiters are supported. Newline characters
// cannot be used as the delimiter.
//
// converters : dict or callable, optional
//
// Converter functions to customize value parsing. If `converters` is
// callable, the function is applied to all columns, else it must be a
// dict that maps column number to a parser function.
// See examples for further details.
// Default: None.
//
// .. versionchanged:: 1.23.0
// The ability to pass a single callable to be applied to all columns
// was added.
//
// skiprows : int, optional
//
// Skip the first `skiprows` lines, including comments; default: 0.
//
// usecols : int or sequence, optional
//
// Which columns to read, with 0 being the first. For example,
// ``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns.
// The default, None, results in all columns being read.
//
// .. versionchanged:: 1.11.0
// When a single column has to be read it is possible to use
// an integer instead of a tuple. E.g ``usecols = 3`` reads the
// fourth column the same way as ``usecols = (3,)`` would.
//
// unpack : bool, optional
//
// If True, the returned array is transposed, so that arguments may be
// unpacked using ``x, y, z = loadtxt(...)``. When used with a
// structured data-type, arrays are returned for each field.
// Default is False.
//
// ndmin : int, optional
//
// The returned array will have at least `ndmin` dimensions.
// Otherwise mono-dimensional axes will be squeezed.
// Legal values: 0 (default), 1 or 2.
//
// .. versionadded:: 1.6.0
//
// encoding : str, optional
//
// Encoding used to decode the inputfile. Does not apply to input streams.
// The special value 'bytes' enables backward compatibility workarounds
// that ensures you receive byte arrays as results if possible and passes
// 'latin1' encoded strings to converters. Override this value to receive
// unicode arrays and pass strings as input to converters. If set to None
// the system default is used. The default value is 'bytes'.
//
// .. versionadded:: 1.14.0
//
// max_rows : int, optional
//
// Read `max_rows` rows of content after `skiprows` lines. The default is
// to read all the rows. Note that empty rows containing no data such as
// empty lines and comment lines are not counted towards `max_rows`,
// while such lines are counted in `skiprows`.
//
// .. versionadded:: 1.16.0
//
// .. versionchanged:: 1.23.0
// Lines containing no data, including comment lines (e.g., lines
// starting with '#' or as specified via `comments`) are not counted
// towards `max_rows`.
//
// quotechar : unicode character or None, optional
//
// The character used to denote the start and end of a quoted item.
// Occurrences of the delimiter or comment characters are ignored within
// a quoted item. The default value is ``quotechar=None``, which means
// quoting support is disabled.
//
// If two consecutive instances of `quotechar` are found within a quoted
// field, the first is treated as an escape character. See examples.
//
// .. versionadded:: 1.23.0
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// out : ndarray
//
// Data read from the text file.
//
// See Also
// --------
// load, fromstring, fromregex
// genfromtxt : Load data with missing values handled as specified.
// scipy.io.loadmat : reads MATLAB data files
//
// Notes
// -----
// This function aims to be a fast reader for simply formatted files. The
// `genfromtxt` function provides more sophisticated handling of, e.g.,
// lines with missing values.
//
// Each row in the input text file must have the same number of values to be
// able to read all values. If all rows do not have same number of values, a
// subset of up to n columns (where n is the least number of values present
// in all rows) can be read by specifying the columns via `usecols`.
//
// .. versionadded:: 1.10.0
//
// The strings produced by the Python float.hex method can be used as
// input for floats.
//
// Examples
// --------
// >>> from io import StringIO # StringIO behaves like a file object
// >>> c = StringIO("0 1\n2 3")
// >>> np.loadtxt(c)
// array([[0., 1.],
//
// [2., 3.]])
//
// >>> d = StringIO("M 21 72\nF 35 58")
// >>> np.loadtxt(d, dtype={'names': ('gender', 'age', 'weight'),
// ... 'formats': ('S1', 'i4', 'f4')})
// array([(b'M', 21, 72.), (b'F', 35, 58.)],
//
// dtype=[('gender', 'S1'), ('age', '<i4'), ('weight', '<f4')])
//
// >>> c = StringIO("1,0,2\n3,0,4")
// >>> x, y = np.loadtxt(c, delimiter=',', usecols=(0, 2), unpack=True)
// >>> x
// array([1., 3.])
// >>> y
// array([2., 4.])
//
// The `converters` argument is used to specify functions to preprocess the
// text prior to parsing. `converters` can be a dictionary that maps
// preprocessing functions to each column:
//
// >>> s = StringIO("1.618, 2.296\n3.141, 4.669\n")
// >>> conv = {
// ... 0: lambda x: np.floor(float(x)), # conversion fn for column 0
// ... 1: lambda x: np.ceil(float(x)), # conversion fn for column 1
// ... }
// >>> np.loadtxt(s, delimiter=",", converters=conv)
// array([[1., 3.],
//
// [3., 5.]])
//
// `converters` can be a callable instead of a dictionary, in which case it
// is applied to all columns:
//
// >>> s = StringIO("0xDE 0xAD\n0xC0 0xDE")
// >>> import functools
// >>> conv = functools.partial(int, base=16)
// >>> np.loadtxt(s, converters=conv)
// array([[222., 173.],
//
// [192., 222.]])
//
// This example shows how `converters` can be used to convert a field
// with a trailing minus sign into a negative number.
//
// >>> s = StringIO('10.01 31.25-\n19.22 64.31\n17.57- 63.94')
// >>> def conv(fld):
// ... return -float(fld[:-1]) if fld.endswith(b'-') else float(fld)
// ...
// >>> np.loadtxt(s, converters=conv)
// array([[ 10.01, -31.25],
//
// [ 19.22, 64.31],
// [-17.57, 63.94]])
//
// Using a callable as the converter can be particularly useful for handling
// values with different formatting, e.g. floats with underscores:
//
// >>> s = StringIO("1 2.7 100_000")
// >>> np.loadtxt(s, converters=float)
// array([1.e+00, 2.7e+00, 1.e+05])
//
// This idea can be extended to automatically handle values specified in
// many different formats:
//
// >>> def conv(val):
// ... try:
// ... return float(val)
// ... except ValueError:
// ... return float.fromhex(val)
// >>> s = StringIO("1, 2.5, 3_000, 0b4, 0x1.4000000000000p+2")
// >>> np.loadtxt(s, delimiter=",", converters=conv, encoding=None)
// array([1.0e+00, 2.5e+00, 3.0e+03, 1.8e+02, 5.0e+00])
//
// Note that with the default “encoding="bytes"“, the inputs to the
// converter function are latin-1 encoded byte strings. To deactivate the
// implicit encoding prior to conversion, use “encoding=None“
//
// >>> s = StringIO('10.01 31.25-\n19.22 64.31\n17.57- 63.94')
// >>> conv = lambda x: -float(x[:-1]) if x.endswith('-') else float(x)
// >>> np.loadtxt(s, converters=conv, encoding=None)
// array([[ 10.01, -31.25],
//
// [ 19.22, 64.31],
// [-17.57, 63.94]])
//
// Support for quoted fields is enabled with the `quotechar` parameter.
// Comment and delimiter characters are ignored when they appear within a
// quoted item delineated by `quotechar`:
//
// >>> s = StringIO('"alpha, #42", 10.0\n"beta, #64", 2.0\n')
// >>> dtype = np.dtype([("label", "U12"), ("value", float)])
// >>> np.loadtxt(s, dtype=dtype, delimiter=",", quotechar='"')
// array([('alpha, #42', 10.), ('beta, #64', 2.)],
//
// dtype=[('label', '<U12'), ('value', '<f8')])
//
// Quoted fields can be separated by multiple whitespace characters:
//
// >>> s = StringIO('"alpha, #42" 10.0\n"beta, #64" 2.0\n')
// >>> dtype = np.dtype([("label", "U12"), ("value", float)])
// >>> np.loadtxt(s, dtype=dtype, delimiter=None, quotechar='"')
// array([('alpha, #42', 10.), ('beta, #64', 2.)],
//
// dtype=[('label', '<U12'), ('value', '<f8')])
//
// Two consecutive quote characters within a quoted field are treated as a
// single escaped character:
//
// >>> s = StringIO('"Hello, my name is ""Monty""!"')
// >>> np.loadtxt(s, dtype="U", delimiter=",", quotechar='"')
// array('Hello, my name is "Monty"!', dtype='<U26')
//
// Read subset of columns when all rows do not contain equal number of values:
//
// >>> d = StringIO("1 2\n2 4\n3 9 12\n4 16 20")
// >>> np.loadtxt(d, usecols=(0, 1))
// array([[ 1., 2.],
//
// [ 2., 4.],
// [ 3., 9.],
// [ 4., 16.]])
//
//go:linkname Loadtxt py.loadtxt
func Loadtxt(fname *py.Object, dtype *py.Object, comments *py.Object, delimiter *py.Object, converters *py.Object, skiprows *py.Object, usecols *py.Object, unpack *py.Object, ndmin *py.Object, encoding *py.Object, maxRows *py.Object) *py.Object
// Load data from a text file, with missing values handled as specified.
//
// Each line past the first `skip_header` lines is split at the `delimiter`
// character, and characters following the `comments` character are discarded.
//
// Parameters
// ----------
// fname : file, str, pathlib.Path, list of str, generator
//
// File, filename, list, or generator to read. If the filename
// extension is ``.gz`` or ``.bz2``, the file is first decompressed. Note
// that generators must return bytes or strings. The strings
// in a list or produced by a generator are treated as lines.
//
// dtype : dtype, optional
//
// Data type of the resulting array.
// If None, the dtypes will be determined by the contents of each
// column, individually.
//
// comments : str, optional
//
// The character used to indicate the start of a comment.
// All the characters occurring on a line after a comment are discarded.
//
// delimiter : str, int, or sequence, optional
//
// The string used to separate values. By default, any consecutive
// whitespaces act as delimiter. An integer or sequence of integers
// can also be provided as width(s) of each field.
//
// skiprows : int, optional
//
// `skiprows` was removed in numpy 1.10. Please use `skip_header` instead.
//
// skip_header : int, optional
//
// The number of lines to skip at the beginning of the file.
//
// skip_footer : int, optional
//
// The number of lines to skip at the end of the file.
//
// converters : variable, optional
//
// The set of functions that convert the data of a column to a value.
// The converters can also be used to provide a default value
// for missing data: ``converters = {3: lambda s: float(s or 0)}``.
//
// missing : variable, optional
//
// `missing` was removed in numpy 1.10. Please use `missing_values`
// instead.
//
// missing_values : variable, optional
//
// The set of strings corresponding to missing data.
//
// filling_values : variable, optional
//
// The set of values to be used as default when the data are missing.
//
// usecols : sequence, optional
//
// Which columns to read, with 0 being the first. For example,
// ``usecols = (1, 4, 5)`` will extract the 2nd, 5th and 6th columns.
//
// names : {None, True, str, sequence}, optional
//
// If `names` is True, the field names are read from the first line after
// the first `skip_header` lines. This line can optionally be preceded
// by a comment delimiter. If `names` is a sequence or a single-string of
// comma-separated names, the names will be used to define the field names
// in a structured dtype. If `names` is None, the names of the dtype
// fields will be used, if any.
//
// excludelist : sequence, optional
//
// A list of names to exclude. This list is appended to the default list
// ['return','file','print']. Excluded names are appended with an
// underscore: for example, `file` would become `file_`.
//
// deletechars : str, optional
//
// A string combining invalid characters that must be deleted from the
// names.
//
// defaultfmt : str, optional
//
// A format used to define default field names, such as "f%i" or "f_%02i".
//
// autostrip : bool, optional
//
// Whether to automatically strip white spaces from the variables.
//
// replace_space : char, optional
//
// Character(s) used in replacement of white spaces in the variable
// names. By default, use a '_'.
//
// case_sensitive : {True, False, 'upper', 'lower'}, optional
//
// If True, field names are case sensitive.
// If False or 'upper', field names are converted to upper case.
// If 'lower', field names are converted to lower case.
//
// unpack : bool, optional
//
// If True, the returned array is transposed, so that arguments may be
// unpacked using ``x, y, z = genfromtxt(...)``. When used with a
// structured data-type, arrays are returned for each field.
// Default is False.
//
// usemask : bool, optional
//
// If True, return a masked array.
// If False, return a regular array.
//
// loose : bool, optional
//
// If True, do not raise errors for invalid values.
//
// invalid_raise : bool, optional
//
// If True, an exception is raised if an inconsistency is detected in the
// number of columns.
// If False, a warning is emitted and the offending lines are skipped.
//
// max_rows : int, optional
//
// The maximum number of rows to read. Must not be used with skip_footer
// at the same time. If given, the value must be at least 1. Default is
// to read the entire file.
//
// .. versionadded:: 1.10.0
//
// encoding : str, optional
//
// Encoding used to decode the inputfile. Does not apply when `fname` is
// a file object. The special value 'bytes' enables backward compatibility
// workarounds that ensure that you receive byte arrays when possible
// and passes latin1 encoded strings to converters. Override this value to
// receive unicode arrays and pass strings as input to converters. If set
// to None the system default is used. The default value is 'bytes'.
//
// .. versionadded:: 1.14.0
//
// ndmin : int, optional
//
// Same parameter as `loadtxt`
//
// .. versionadded:: 1.23.0
//
// like : array_like, optional
//
// Reference object to allow the creation of arrays which are not
// NumPy arrays. If an array-like passed in as ``like`` supports
// the ``__array_function__`` protocol, the result will be defined
// by it. In this case, it ensures the creation of an array object
// compatible with that passed in via this argument.
//
// .. versionadded:: 1.20.0
//
// Returns
// -------
// out : ndarray
//
// Data read from the text file. If `usemask` is True, this is a
// masked array.
//
// See Also
// --------
// numpy.loadtxt : equivalent function when no data is missing.
//
// Notes
// -----
// - When spaces are used as delimiters, or when no delimiter has been given
// as input, there should not be any missing data between two fields.
// - When the variables are named (either by a flexible dtype or with `names`),
// there must not be any header in the file (else a ValueError
// exception is raised).
// - Individual values are not stripped of spaces by default.
// When using a custom converter, make sure the function does remove spaces.
//
// References
// ----------
// .. [1] NumPy User Guide, section `I/O with NumPy
//
// <https://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html>`_.
//
// Examples
// --------
// >>> from io import StringIO
// >>> import numpy as np
//
// # Comma delimited file with mixed dtype
//
// >>> s = StringIO(u"1,1.3,abcde")
// >>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
// ... ('mystring','S5')], delimiter=",")
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', 'S5')])
//
// Using dtype = None
//
// >>> _ = s.seek(0) # needed for StringIO example only
// >>> data = np.genfromtxt(s, dtype=None,
// ... names = ['myint','myfloat','mystring'], delimiter=",")
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', 'S5')])
//
// # Specifying dtype and names
//
// >>> _ = s.seek(0)
// >>> data = np.genfromtxt(s, dtype="i8,f8,S5",
// ... names=['myint','myfloat','mystring'], delimiter=",")
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', 'S5')])
//
// # An example with fixed-width columns
//
// >>> s = StringIO(u"11.3abcde")
// >>> data = np.genfromtxt(s, dtype=None, names=['intvar','fltvar','strvar'],
// ... delimiter=[1,3,5])
// >>> data
// array((1, 1.3, b'abcde'),
//
// dtype=[('intvar', '<i8'), ('fltvar', '<f8'), ('strvar', 'S5')])
//
// # An example to show comments
//
// >>> f = StringIO(”'
// ... text,# of chars
// ... hello world,11
// ... numpy,5”')
// >>> np.genfromtxt(f, dtype='S12,S12', delimiter=',')
// array([(b'text', b”), (b'hello world', b'11'), (b'numpy', b'5')],
//
// dtype=[('f0', 'S12'), ('f1', 'S12')])
//
//go:linkname Genfromtxt py.genfromtxt
func Genfromtxt(fname *py.Object, dtype *py.Object, comments *py.Object, delimiter *py.Object, skipHeader *py.Object, skipFooter *py.Object, converters *py.Object, missingValues *py.Object, fillingValues *py.Object, usecols *py.Object, names *py.Object, excludelist *py.Object, deletechars *py.Object, replaceSpace *py.Object, autostrip *py.Object, caseSensitive *py.Object, defaultfmt *py.Object, unpack *py.Object, usemask *py.Object, loose *py.Object, invalidRaise *py.Object, maxRows *py.Object, encoding *py.Object) *py.Object
// Load ASCII data from a file and return it in a record array.
//
// If “usemask=False“ a standard `recarray` is returned,

View File

@@ -42,15 +42,6 @@ func Arange(start, stop, step, dtype *py.Object) *py.Object
//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)

7351
py/pandas/gen.go Normal file

File diff suppressed because it is too large Load Diff

BIN
py/pandas/llgo_autogen.lla Normal file

Binary file not shown.

57
py/pandas/pandas.go Normal file
View File

@@ -0,0 +1,57 @@
/*
* 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 pandas
import (
_ "unsafe"
"github.com/goplus/llgo/py"
)
// https://pandas.pydata.org/docs/reference/index.html
// read_excel(io, sheet_name=0, *, header=0, names=None, index_col=None, usecols=None,
// dtype=None, engine=None, converters=None, true_values=None, false_values=None,
// skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True,
// verbose=False, parse_dates=False, date_parser=_NoDefault.no_default, date_format=None,
// thousands=None, decimal='.', comment=None, skipfooter=0, storage_options=None,
// dtype_backend=_NoDefault.no_default, engine_kwargs=None)
//
// See https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html
//
//go:linkname ReadExcel py.read_excel
func ReadExcel(io, sheetName *py.Object) *py.Object
// See https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html
//
//go:linkname ReadCsv py.read_csv
func ReadCsv(filepathOrBuffer *py.Object) *py.Object
// eval(expr, parser='pandas', engine=None, local_dict=None, global_dict=None, resolvers=(),
// level=0, target=None, inplace=False)
//
// See https://pandas.pydata.org/docs/reference/api/pandas.eval.html#pandas.eval
//
//go:linkname Eval py.eval
func Eval(expr, parser, engine, localDict, globalDict, resolvers, level, target, inplace *py.Object) *py.Object
// show_versions(as_json=False)
//
// See https://pandas.pydata.org/docs/reference/api/pandas.show_versions.html
//
//go:linkname ShowVersions py.show_versions
func ShowVersions(asJson *py.Object) *py.Object

View File

@@ -320,20 +320,36 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
}
}
case isLogicOp(op): // op: & | ^ << >> &^
if op == token.AND_NOT {
switch op {
case token.AND_NOT:
return Expr{b.impl.CreateAnd(x.impl, b.impl.CreateNot(y.impl, ""), ""), x.Type}
}
kind := x.kind
llop := logicOpToLLVM[op-logicOpBase]
if op == token.SHR && kind == vkUnsigned {
llop = llvm.LShr // Logical Shift Right
}
if op == token.SHL || op == token.SHR {
if b.Prog.SizeOf(x.Type) != b.Prog.SizeOf(y.Type) {
case token.SHL, token.SHR:
if y.kind == vkSigned {
check := Expr{b.impl.CreateICmp(llvm.IntSLT, y.impl, llvm.ConstInt(y.ll, 0, false), ""), b.Prog.Bool()}
b.InlineCall(b.Func.Pkg.rtFunc("CheckRuntimeError"), check, b.Str("negative shift amount"))
}
xsize, ysize := b.Prog.SizeOf(x.Type), b.Prog.SizeOf(y.Type)
if xsize != ysize {
y = b.Convert(x.Type, y)
}
overflows := b.impl.CreateICmp(llvm.IntUGE, y.impl, llvm.ConstInt(y.ll, xsize*8, false), "")
xzero := llvm.ConstInt(x.ll, 0, false)
if op == token.SHL {
rhs := b.impl.CreateShl(x.impl, y.impl, "")
return Expr{b.impl.CreateSelect(overflows, xzero, rhs, ""), x.Type}
} else {
if x.kind == vkSigned {
rhs := b.impl.CreateSelect(overflows, llvm.ConstInt(y.ll, 8*xsize-1, false), y.impl, "")
return Expr{b.impl.CreateAShr(x.impl, rhs, ""), x.Type}
} else {
rsh := b.impl.CreateLShr(x.impl, y.impl, "")
return Expr{b.impl.CreateSelect(overflows, xzero, rsh, ""), x.Type}
}
}
default:
llop := logicOpToLLVM[op-logicOpBase]
return Expr{llvm.CreateBinOp(b.impl, llop, x.impl, y.impl), x.Type}
}
return Expr{llvm.CreateBinOp(b.impl, llop, x.impl, y.impl), x.Type}
case isPredOp(op): // op: == != < <= < >=
tret := b.Prog.Bool()
kind := x.kind
@@ -1043,7 +1059,7 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
case *types.Basic:
switch typ.Kind() {
case types.Uintptr:
ret.impl = castInt(b.impl, x.impl, t.ll)
ret.impl = castUintptr(b, x.impl, t)
return
case types.UnsafePointer:
ret.impl = castPtr(b.impl, x.impl, t.ll)
@@ -1051,19 +1067,10 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
}
switch xtyp := x.RawType().Underlying().(type) {
case *types.Basic:
size := b.Prog.SizeOf(t)
xsize := b.Prog.SizeOf(x.Type)
if typ.Info()&types.IsInteger != 0 {
// int <- int/float
if xtyp.Info()&types.IsInteger != 0 {
// if xsize > size {
// ret.impl = b.impl.CreateTrunc(x.impl, t.ll, "")
// } else if typ.Info()&types.IsUnsigned != 0 {
// ret.impl = b.impl.CreateZExt(x.impl, t.ll, "")
// } else {
// ret.impl = b.impl.CreateSExt(x.impl, t.ll, "")
// }
ret.impl = castInt(b.impl, x.impl, t.ll)
ret.impl = castInt(b, x.impl, t)
return
} else if xtyp.Info()&types.IsFloat != 0 {
if typ.Info()&types.IsUnsigned != 0 {
@@ -1083,11 +1090,7 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
}
return
} else if xtyp.Info()&types.IsFloat != 0 {
if xsize > size {
ret.impl = b.impl.CreateFPTrunc(x.impl, t.ll, "")
} else {
ret.impl = b.impl.CreateFPExt(x.impl, t.ll, "")
}
ret.impl = castFloat(b, x.impl, t)
return
}
}
@@ -1099,15 +1102,33 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
panic("todo")
}
func castInt(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value {
xt := x.Type()
if xt.TypeKind() == llvm.PointerTypeKind {
return llvm.CreatePtrToInt(b, x, t)
func castUintptr(b Builder, x llvm.Value, typ Type) llvm.Value {
if x.Type().TypeKind() == llvm.PointerTypeKind {
return llvm.CreatePtrToInt(b.impl, x, typ.ll)
}
if xt.IntTypeWidth() <= t.IntTypeWidth() {
return llvm.CreateIntCast(b, x, t)
return castInt(b, x, typ)
}
func castInt(b Builder, x llvm.Value, typ Type) llvm.Value {
xsize := b.Prog.td.TypeAllocSize(x.Type())
size := b.Prog.td.TypeAllocSize(typ.ll)
if xsize > size {
return b.impl.CreateTrunc(x, typ.ll, "")
} else if typ.kind == vkUnsigned {
return b.impl.CreateZExt(x, typ.ll, "")
} else {
return b.impl.CreateSExt(x, typ.ll, "")
}
}
func castFloat(b Builder, x llvm.Value, typ Type) llvm.Value {
xsize := b.Prog.td.TypeAllocSize(x.Type())
size := b.Prog.td.TypeAllocSize(typ.ll)
if xsize > size {
return b.impl.CreateFPTrunc(x, typ.ll, "")
} else {
return b.impl.CreateFPExt(x, typ.ll, "")
}
return llvm.CreateTrunc(b, x, t)
}
func castPtr(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value {
@@ -1229,12 +1250,12 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
conv := func(v llvm.Value) llvm.Value {
switch kind {
case types.Float32:
v = castInt(b.impl, v, b.Prog.tyInt32())
v = castInt(b, v, b.Prog.Int32())
v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
case types.Float64:
v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
default:
v = castInt(b.impl, v, assertedTyp.ll)
v = castInt(b, v, assertedTyp)
}
return v
}
@@ -1383,7 +1404,7 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl
return
case vkString:
etSize := b.Prog.SizeOf(b.Prog.Type(types.Typ[types.Byte], InGo))
etSize := b.Prog.SizeOf(b.Prog.Byte())
ret.Type = src.Type
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"),
src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl
@@ -1399,24 +1420,24 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str(" "))
}
var fn string
var typ types.Type
var typ Type
switch arg.kind {
case vkBool:
fn = "PrintBool"
case vkSigned:
fn = "PrintInt"
typ = types.Typ[types.Int64]
typ = b.Prog.Int64()
case vkUnsigned:
fn = "PrintUint"
typ = types.Typ[types.Uint64]
typ = b.Prog.Uint64()
case vkFloat:
fn = "PrintFloat"
typ = types.Typ[types.Float64]
typ = b.Prog.Float64()
case vkSlice:
fn = "PrintSlice"
case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef:
fn = "PrintPointer"
typ = types.Typ[types.UnsafePointer]
typ = b.Prog.VoidPtr()
case vkString:
fn = "PrintString"
case vkInterface:
@@ -1426,8 +1447,8 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
default:
panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType()))
}
if typ != nil && typ != arg.raw.Type {
arg = b.Convert(b.Prog.Type(typ, InGo), arg)
if typ != nil && typ != arg.Type {
arg = b.Convert(typ, arg)
}
b.InlineCall(b.Func.Pkg.rtFunc(fn), arg)
}

View File

@@ -134,7 +134,13 @@ type aProgram struct {
stringTy Type
uintptrTy Type
intTy Type
uintTy Type
f64Ty Type
byteTy Type
i32Ty Type
u32Ty Type
i64Ty Type
u64Ty Type
pyObjPtr Type
pyObjPPtr Type
@@ -351,6 +357,14 @@ func (p Program) Int() Type {
return p.intTy
}
// Uint returns uint type.
func (p Program) Uint() Type {
if p.uintTy == nil {
p.uintTy = p.rawType(types.Typ[types.Uint])
}
return p.uintTy
}
// Uintptr returns uintptr type.
func (p Program) Uintptr() Type {
if p.uintptrTy == nil {
@@ -367,6 +381,46 @@ func (p Program) Float64() Type {
return p.f64Ty
}
// Byte returns byte type.
func (p Program) Byte() Type {
if p.byteTy == nil {
p.byteTy = p.rawType(types.Typ[types.Byte])
}
return p.byteTy
}
// Int32 returns int32 type.
func (p Program) Int32() Type {
if p.i32Ty == nil {
p.i32Ty = p.rawType(types.Typ[types.Int32])
}
return p.i32Ty
}
// Uint32 returns uint32 type.
func (p Program) Uint32() Type {
if p.u32Ty == nil {
p.u32Ty = p.rawType(types.Typ[types.Uint32])
}
return p.u32Ty
}
// Int64 returns int64 type.
func (p Program) Int64() Type {
if p.i64Ty == nil {
p.i64Ty = p.rawType(types.Typ[types.Int64])
}
return p.i64Ty
}
// Uint64 returns uint64 type.
func (p Program) Uint64() Type {
if p.u64Ty == nil {
p.u64Ty = p.rawType(types.Typ[types.Uint64])
}
return p.u64Ty
}
// -----------------------------------------------------------------------------
// A Package is a single analyzed Go package containing Members for

View File

@@ -446,7 +446,7 @@ func TestUnOp(t *testing.T) {
b := fn.MakeBody(1)
ptr := fn.Param(0)
val := b.UnOp(token.MUL, ptr)
val2 := b.BinOp(token.SHR, val, prog.Val(1))
val2 := b.BinOp(token.XOR, val, prog.Val(1))
b.Store(ptr, val2)
b.Return(val2)
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
@@ -455,9 +455,34 @@ source_filename = "foo/bar"
define i64 @fn(ptr %0) {
_llgo_0:
%1 = load i64, ptr %0, align 4
%2 = ashr i64 %1, 1
%2 = xor i64 %1, 1
store i64 %2, ptr %0, align 4
ret i64 %2
}
`)
}
func TestBasicType(t *testing.T) {
type typeInfo struct {
typ Type
kind types.BasicKind
}
prog := NewProgram(nil)
infos := []*typeInfo{
{prog.Bool(), types.Bool},
{prog.Byte(), types.Byte},
{prog.Int(), types.Int},
{prog.Uint(), types.Uint},
{prog.Int32(), types.Int32},
{prog.Int64(), types.Int64},
{prog.Uint32(), types.Uint32},
{prog.Uint64(), types.Uint64},
{prog.Uintptr(), types.Uintptr},
{prog.VoidPtr(), types.UnsafePointer},
}
for _, info := range infos {
if info.typ.RawType() != types.Typ[info.kind] {
t.Fatal("bad type", info)
}
}
}