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! 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) * [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)
* [os](https://pkg.go.dev/github.com/goplus/llgo/py/os) * [os](https://pkg.go.dev/github.com/goplus/llgo/py/os)

View File

@@ -29,6 +29,7 @@ import (
"strings" "strings"
"github.com/goplus/gogen" "github.com/goplus/gogen"
"github.com/goplus/llgo/chore/llpyg/pysig"
"github.com/goplus/llgo/ssa" "github.com/goplus/llgo/ssa"
) )
@@ -109,12 +110,12 @@ func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) {
if len(name) == 0 || name[0] == '_' { if len(name) == 0 || name[0] == '_' {
return return
} }
params, variadic, skip := ctx.genParams(pkg, symSig) if symSig == "<NULL>" {
if skip {
// TODO(xsw): don't skip any func // TODO(xsw): don't skip any func
log.Println("skip func:", name, symSig) log.Println("skip func:", name, symSig)
return return
} }
params, variadic := ctx.genParams(pkg, symSig)
name = genName(name, -1) name = genName(name, -1)
sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic) sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic)
fn := pkg.NewFuncDecl(token.NoPos, name, sig) fn := pkg.NewFuncDecl(token.NoPos, name, sig)
@@ -125,43 +126,32 @@ func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) {
// fn.BodyStart(pkg).End() // fn.BodyStart(pkg).End()
} }
func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool, bool) { func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool) {
if sig == "<NULL>" { args := pysig.Parse(sig)
return nil, false, true if len(args) == 0 {
return nil, false
} }
sig = strings.TrimSuffix(strings.TrimPrefix(sig, "("), ")") n := len(args)
if sig == "" { // empty params
return nil, false, false
}
parts := strings.Split(sig, ",")
n := len(parts)
objPtr := ctx.objPtr objPtr := ctx.objPtr
list := make([]*types.Var, 0, n) list := make([]*types.Var, 0, n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
part := strings.TrimSpace(parts[i]) name := args[i].Name
if part == "/" { if name == "/" {
continue continue
} }
if part == "*" { if name == "*" {
break break
} }
if strings.HasPrefix(part, "*") { if strings.HasPrefix(name, "*") {
if part[1] != '*' { if name[1] != '*' {
list = append(list, ssa.VArg()) 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, '=') list = append(list, pkg.NewParam(0, genName(name, 0), objPtr))
if pos >= 0 {
if strings.HasPrefix(part[pos+1:], "<") { // skip complex default value
return nil, false, true
} }
part = part[:pos] return types.NewTuple(list...), false
}
list = append(list, pkg.NewParam(0, genName(part, 0), objPtr))
}
return types.NewTuple(list...), false, false
} }
func genName(name string, idxDontTitle int) string { 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 br i1 %40, label %_llgo_16, label %_llgo_17
_llgo_16: ; preds = %_llgo_15 _llgo_16: ; preds = %_llgo_15
%41 = sext i8 %39 to i64 %41 = zext i8 %39 to i64
call void @main.printuint(i64 %41) call void @main.printuint(i64 %41)
br label %_llgo_1 br label %_llgo_1
@@ -335,7 +335,7 @@ _llgo_17: ; preds = %_llgo_15
br i1 %46, label %_llgo_18, label %_llgo_19 br i1 %46, label %_llgo_18, label %_llgo_19
_llgo_18: ; preds = %_llgo_17 _llgo_18: ; preds = %_llgo_17
%47 = sext i16 %45 to i64 %47 = zext i16 %45 to i64
call void @main.printuint(i64 %47) call void @main.printuint(i64 %47)
br label %_llgo_1 br label %_llgo_1
@@ -348,7 +348,7 @@ _llgo_19: ; preds = %_llgo_17
br i1 %52, label %_llgo_20, label %_llgo_21 br i1 %52, label %_llgo_20, label %_llgo_21
_llgo_20: ; preds = %_llgo_19 _llgo_20: ; preds = %_llgo_19
%53 = sext i32 %51 to i64 %53 = zext i32 %51 to i64
call void @main.printuint(i64 %53) call void @main.printuint(i64 %53)
br label %_llgo_1 br label %_llgo_1

View File

@@ -25,5 +25,5 @@ func main() {
data = append(data, "def"...) data = append(data, "def"...)
println(data) println(data)
var i any = 100 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) 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) %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.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) %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.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %130)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 -100) 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) { define void @main.cvtUinptr(i32 %0, i64 %1) {
_llgo_0: _llgo_0:
%2 = sext i32 %0 to i64 %2 = zext i32 %0 to i64
%3 = icmp ne i64 %2, %1 %3 = icmp ne i64 %2, %1
br i1 %3, label %_llgo_1, label %_llgo_2 br i1 %3, label %_llgo_1, label %_llgo_2

View File

@@ -2,7 +2,41 @@ package main
func main() { func main() {
println(mask(1)) 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 { func mask(x int8) int32 {
return int32(x) << 31 >> 31 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_argc = global ptr null
@__llgo_argv = global ptr null @__llgo_argv = global ptr null
@0 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 @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() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -32,6 +47,49 @@ _llgo_0:
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %3) 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) %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) 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 ret i32 0
} }
@@ -39,8 +97,79 @@ define i32 @main.mask(i8 %0) {
_llgo_0: _llgo_0:
%1 = sext i8 %0 to i32 %1 = sext i8 %0 to i32
%2 = shl i32 %1, 31 %2 = shl i32 %1, 31
%3 = ashr i32 %2, 31 %3 = select i1 false, i32 0, i32 %2
ret i32 %3 %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"() 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 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 %"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) dir, lib := filepath.Split(linkFile)
command := " -l " + lib command := " -l " + lib
if dir != "" { if dir != "" {
command += " -L " + dir command += " -L " + dir[:len(dir)-1]
} }
if isSingleLinkFile(pkg.ExportFile) { if isSingleLinkFile(pkg.ExportFile) {
pkg.ExportFile = command + " " + 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 //go:linkname Isfortran py.isfortran
func Isfortran(a *py.Object) *py.Object 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. // Construct an array by executing a function over each coordinate.
// //
// The resulting array therefore has a value “fn(x, y, z)“ at // 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 //go:linkname Gcd py.gcd
func Gcd(__llgo_va_list ...interface{}) *py.Object 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]) // heaviside(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
// //
// Compute the Heaviside step function. // Compute the Heaviside step function.
@@ -6204,6 +6239,70 @@ func RightShift(__llgo_va_list ...interface{}) *py.Object
//go:linkname Rint py.rint //go:linkname Rint py.rint
func Rint(__llgo_va_list ...interface{}) *py.Object 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]) // 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). // 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 //go:linkname BroadcastShapes py.broadcast_shapes
func BroadcastShapes(__llgo_va_list ...interface{}) *py.Object 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. // 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 // 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 //go:linkname Info py.info
func Info(object *py.Object, maxwidth *py.Object, output *py.Object, toplevel *py.Object) *py.Object 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. // Print the NumPy arrays in the given dictionary.
// //
// If there is no dictionary passed in or `vardict` is None then returns // 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 //go:linkname ShowRuntime py.show_runtime
func ShowRuntime() *py.Object 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. // Load ASCII data from a file and return it in a record array.
// //
// If “usemask=False“ a standard `recarray` is returned, // 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 //go:linkname Empty py.empty
func Empty(shape, dtype, order *py.Object) *py.Object 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. // Return a new array of given shape and type, filled with zeros.
// //
// numpy.zeros(shape, dtype=float, order='C', *, like=None) // 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: & | ^ << >> &^ 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} return Expr{b.impl.CreateAnd(x.impl, b.impl.CreateNot(y.impl, ""), ""), x.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"))
} }
kind := x.kind xsize, ysize := b.Prog.SizeOf(x.Type), b.Prog.SizeOf(y.Type)
llop := logicOpToLLVM[op-logicOpBase] if xsize != ysize {
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) {
y = b.Convert(x.Type, y) 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: == != < <= < >= case isPredOp(op): // op: == != < <= < >=
tret := b.Prog.Bool() tret := b.Prog.Bool()
kind := x.kind kind := x.kind
@@ -1043,7 +1059,7 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
case *types.Basic: case *types.Basic:
switch typ.Kind() { switch typ.Kind() {
case types.Uintptr: case types.Uintptr:
ret.impl = castInt(b.impl, x.impl, t.ll) ret.impl = castUintptr(b, x.impl, t)
return return
case types.UnsafePointer: case types.UnsafePointer:
ret.impl = castPtr(b.impl, x.impl, t.ll) 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) { switch xtyp := x.RawType().Underlying().(type) {
case *types.Basic: case *types.Basic:
size := b.Prog.SizeOf(t)
xsize := b.Prog.SizeOf(x.Type)
if typ.Info()&types.IsInteger != 0 { if typ.Info()&types.IsInteger != 0 {
// int <- int/float // int <- int/float
if xtyp.Info()&types.IsInteger != 0 { if xtyp.Info()&types.IsInteger != 0 {
// if xsize > size { ret.impl = castInt(b, x.impl, t)
// 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)
return return
} else if xtyp.Info()&types.IsFloat != 0 { } else if xtyp.Info()&types.IsFloat != 0 {
if typ.Info()&types.IsUnsigned != 0 { if typ.Info()&types.IsUnsigned != 0 {
@@ -1083,11 +1090,7 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
} }
return return
} else if xtyp.Info()&types.IsFloat != 0 { } else if xtyp.Info()&types.IsFloat != 0 {
if xsize > size { ret.impl = castFloat(b, x.impl, t)
ret.impl = b.impl.CreateFPTrunc(x.impl, t.ll, "")
} else {
ret.impl = b.impl.CreateFPExt(x.impl, t.ll, "")
}
return return
} }
} }
@@ -1099,15 +1102,33 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
panic("todo") panic("todo")
} }
func castInt(b llvm.Builder, x llvm.Value, t llvm.Type) llvm.Value { func castUintptr(b Builder, x llvm.Value, typ Type) llvm.Value {
xt := x.Type() if x.Type().TypeKind() == llvm.PointerTypeKind {
if xt.TypeKind() == llvm.PointerTypeKind { return llvm.CreatePtrToInt(b.impl, x, typ.ll)
return llvm.CreatePtrToInt(b, x, t)
} }
if xt.IntTypeWidth() <= t.IntTypeWidth() { return castInt(b, x, typ)
return llvm.CreateIntCast(b, x, t) }
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 { 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 { conv := func(v llvm.Value) llvm.Value {
switch kind { switch kind {
case types.Float32: 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, "") v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
case types.Float64: case types.Float64:
v = b.impl.CreateBitCast(v, assertedTyp.ll, "") v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
default: default:
v = castInt(b.impl, v, assertedTyp.ll) v = castInt(b, v, assertedTyp)
} }
return v 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 src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl
return return
case vkString: 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.Type = src.Type
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"), ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"),
src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl 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(" ")) b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str(" "))
} }
var fn string var fn string
var typ types.Type var typ Type
switch arg.kind { switch arg.kind {
case vkBool: case vkBool:
fn = "PrintBool" fn = "PrintBool"
case vkSigned: case vkSigned:
fn = "PrintInt" fn = "PrintInt"
typ = types.Typ[types.Int64] typ = b.Prog.Int64()
case vkUnsigned: case vkUnsigned:
fn = "PrintUint" fn = "PrintUint"
typ = types.Typ[types.Uint64] typ = b.Prog.Uint64()
case vkFloat: case vkFloat:
fn = "PrintFloat" fn = "PrintFloat"
typ = types.Typ[types.Float64] typ = b.Prog.Float64()
case vkSlice: case vkSlice:
fn = "PrintSlice" fn = "PrintSlice"
case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef: case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef:
fn = "PrintPointer" fn = "PrintPointer"
typ = types.Typ[types.UnsafePointer] typ = b.Prog.VoidPtr()
case vkString: case vkString:
fn = "PrintString" fn = "PrintString"
case vkInterface: case vkInterface:
@@ -1426,8 +1447,8 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
default: default:
panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType())) panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType()))
} }
if typ != nil && typ != arg.raw.Type { if typ != nil && typ != arg.Type {
arg = b.Convert(b.Prog.Type(typ, InGo), arg) arg = b.Convert(typ, arg)
} }
b.InlineCall(b.Func.Pkg.rtFunc(fn), arg) b.InlineCall(b.Func.Pkg.rtFunc(fn), arg)
} }

View File

@@ -134,7 +134,13 @@ type aProgram struct {
stringTy Type stringTy Type
uintptrTy Type uintptrTy Type
intTy Type intTy Type
uintTy Type
f64Ty Type f64Ty Type
byteTy Type
i32Ty Type
u32Ty Type
i64Ty Type
u64Ty Type
pyObjPtr Type pyObjPtr Type
pyObjPPtr Type pyObjPPtr Type
@@ -351,6 +357,14 @@ func (p Program) Int() Type {
return p.intTy 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. // Uintptr returns uintptr type.
func (p Program) Uintptr() Type { func (p Program) Uintptr() Type {
if p.uintptrTy == nil { if p.uintptrTy == nil {
@@ -367,6 +381,46 @@ func (p Program) Float64() Type {
return p.f64Ty 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 // 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) b := fn.MakeBody(1)
ptr := fn.Param(0) ptr := fn.Param(0)
val := b.UnOp(token.MUL, ptr) 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.Store(ptr, val2)
b.Return(val2) b.Return(val2)
assertPkg(t, pkg, `; ModuleID = 'foo/bar' assertPkg(t, pkg, `; ModuleID = 'foo/bar'
@@ -455,9 +455,34 @@ source_filename = "foo/bar"
define i64 @fn(ptr %0) { define i64 @fn(ptr %0) {
_llgo_0: _llgo_0:
%1 = load i64, ptr %0, align 4 %1 = load i64, ptr %0, align 4
%2 = ashr i64 %1, 1 %2 = xor i64 %1, 1
store i64 %2, ptr %0, align 4 store i64 %2, ptr %0, align 4
ret i64 %2 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)
}
}
}