From 780569a0601dbb9727146dad7fa5169b521e0f3d Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 5 May 2022 22:42:53 +0800 Subject: [PATCH 1/6] CastFromBool: support untyped bool --- ast.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ast.go b/ast.go index 144efccb..cfa7e0be 100644 --- a/ast.go +++ b/ast.go @@ -779,6 +779,13 @@ func matchRcast(pkg *Package, fn *internal.Elem, m types.Object, typ types.Type, // CastFromBool tries to cast a bool expression into integer. typ must be an integer type. func CastFromBool(cb *CodeBuilder, typ types.Type, v *Element) (ret *Element, ok bool) { if ok = isBool(cb, v); ok { + if v.CVal != nil { // untyped bool + var val int + if constant.BoolVal(v.CVal) { + val = 1 + } + return toExpr(nil, val, v.Src), true + } pkg := cb.pkg results := types.NewTuple(types.NewParam(token.NoPos, pkg.Types, "", typ)) ret = cb.NewClosure(nil, results, false).BodyStart(pkg). From 0f052b155b237b2ab733f0925863e2a0b2047f6d Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 5 May 2022 22:53:08 +0800 Subject: [PATCH 2/6] TestCastFromBool --- builtin_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/builtin_test.go b/builtin_test.go index e1ab6caa..7011deff 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -950,4 +950,21 @@ func TestTypeAST(t *testing.T) { } } +func TestCastFromBool(t *testing.T) { + ret, ok := CastFromBool(nil, types.Typ[types.Uint], &Element{ + Type: types.Typ[types.UntypedBool], + CVal: constant.MakeBool(true), + }) + if !ok || constant.Val(ret.CVal).(int64) != 1 { + t.Fatal("CastFromBool failed:", ret.CVal, ok) + } + ret, ok = CastFromBool(nil, types.Typ[types.Uint], &Element{ + Type: types.Typ[types.Bool], + CVal: constant.MakeBool(false), + }) + if !ok || constant.Val(ret.CVal).(int64) != 0 { + t.Fatal("CastFromBool failed:", ret.CVal, ok) + } +} + // ---------------------------------------------------------------------------- From 164024da73b3fcdbc7428543194c1ec783b0a99e Mon Sep 17 00:00:00 2001 From: xushiwei Date: Thu, 5 May 2022 23:30:41 +0800 Subject: [PATCH 3/6] TypeDecl.State --- package_test.go | 9 +++++++++ type_var_and_const.go | 25 ++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/package_test.go b/package_test.go index 93699164..f08dd242 100644 --- a/package_test.go +++ b/package_test.go @@ -608,8 +608,17 @@ func TestDeleteType(t *testing.T) { pkg := newMainPackage() typ := types.NewStruct(nil, nil) decl := pkg.NewType("foo") + if decl.State() != gox.TyStateUninited { + t.Fatal("TypeDecl.State failed") + } decl.InitType(pkg, typ) + if decl.State() != gox.TyStateInited { + t.Fatal("TypeDecl.State failed") + } decl.Delete() + if decl.State() != gox.TyStateDeleted { + t.Fatal("TypeDecl.State failed") + } domTest(t, pkg, `package main diff --git a/type_var_and_const.go b/type_var_and_const.go index f0455087..4df24a0c 100644 --- a/type_var_and_const.go +++ b/type_var_and_const.go @@ -38,6 +38,14 @@ func (p *CodeBuilder) EndConst() *Element { // ---------------------------------------------------------------------------- +type TyState int + +const ( + TyStateUninited TyState = iota + TyStateInited + TyStateDeleted +) + // TypeDecl type type TypeDecl struct { typ *types.Named @@ -56,13 +64,28 @@ func (p *TypeDecl) Type() *types.Named { return p.typ } +// State checkes state of this type. +// If Delete is called, it returns TyStateDeleted. +// If InitType is called (but not deleted), it returns TyStateInited. +// Otherwise it returns TyStateUninited. +func (p *TypeDecl) State() TyState { + if spec := p.decl.Specs; len(spec) > 0 { + if spec[0].(*ast.TypeSpec).Type != nil { + return TyStateInited + } + return TyStateUninited + } + return TyStateDeleted +} + // Delete deletes this type. // NOTE: It panics if you call InitType after Delete. func (p *TypeDecl) Delete() { p.decl.Specs = p.decl.Specs[:0] } -// Inited checkes if `InitType` is called or not. +// Inited checkes if InitType is called or not. +// Will panic if this type is deleted (please use State to check). func (p *TypeDecl) Inited() bool { return p.decl.Specs[0].(*ast.TypeSpec).Type != nil } From d7cc423dba138da41775eef8357b64167573a625 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 6 May 2022 09:10:56 +0800 Subject: [PATCH 4/6] ZeroLit: fix func() zeroLit --- codebuild.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/codebuild.go b/codebuild.go index 3d18600a..5711bc5d 100644 --- a/codebuild.go +++ b/codebuild.go @@ -721,15 +721,7 @@ retry: default: return p.Val(0) } - case *types.Interface: - return p.Val(nil) - case *types.Map: - return p.Val(nil) - case *types.Slice: - return p.Val(nil) - case *types.Pointer: - return p.Val(nil) - case *types.Chan: + case *types.Interface, *types.Map, *types.Slice, *types.Pointer, *types.Signature, *types.Chan: return p.Val(nil) case *types.Named: typ = p.getUnderlying(t) From 501e2d5c692ee96175792ea15d40b805a6248efe Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 6 May 2022 10:04:33 +0800 Subject: [PATCH 5/6] public SubstType --- builtin_test.go | 2 +- type_var_and_const.go | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/builtin_test.go b/builtin_test.go index 7011deff..d2586fe3 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -443,7 +443,7 @@ func TestSubstVar(t *testing.T) { } func TestUnderlying(t *testing.T) { - subst := &substType{} + subst := &SubstType{} bfReft := &bfRefType{typ: tyInt} if typ, ok := DerefType(bfReft); !ok || typ != tyInt { t.Fatal("TestDerefType failed") diff --git a/type_var_and_const.go b/type_var_and_const.go index 4df24a0c..ca45e6f2 100644 --- a/type_var_and_const.go +++ b/type_var_and_const.go @@ -769,27 +769,27 @@ func (p *TypeType) String() string { // ---------------------------------------------------------------------------- -type substType struct { - real types.Object +type SubstType struct { + Real types.Object } -func (p *substType) Underlying() types.Type { +func (p *SubstType) Underlying() types.Type { fatal("substitute type") return nil } -func (p *substType) String() string { - return fmt.Sprintf("substType{real: %v}", p.real) +func (p *SubstType) String() string { + return fmt.Sprintf("substType{real: %v}", p.Real) } func NewSubstVar(pos token.Pos, pkg *types.Package, name string, real types.Object) *types.Var { - return types.NewVar(pos, pkg, name, &substType{real: real}) + return types.NewVar(pos, pkg, name, &SubstType{Real: real}) } func LookupParent(scope *types.Scope, name string, pos token.Pos) (at *types.Scope, obj types.Object) { if at, obj = scope.LookupParent(name, pos); obj != nil { - if t, ok := obj.Type().(*substType); ok { - obj = t.real + if t, ok := obj.Type().(*SubstType); ok { + obj = t.Real } } return @@ -797,8 +797,8 @@ func LookupParent(scope *types.Scope, name string, pos token.Pos) (at *types.Sco func Lookup(scope *types.Scope, name string) (obj types.Object) { if obj = scope.Lookup(name); obj != nil { - if t, ok := obj.Type().(*substType); ok { - obj = t.real + if t, ok := obj.Type().(*SubstType); ok { + obj = t.Real } } return From aca7217230f964ea4bd1a9029203a94778da0c68 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 7 May 2022 08:48:39 +0800 Subject: [PATCH 6/6] rename NewSubstVar => NewSubst --- builtin_test.go | 2 +- type_var_and_const.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin_test.go b/builtin_test.go index d2586fe3..b4271e10 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -420,7 +420,7 @@ func TestSubstVar(t *testing.T) { pkg := NewPackage("", "foo", gblConf) a := pkg.NewAutoParam("a") scope := pkg.cb.Scope() - scope.Insert(NewSubstVar(token.NoPos, pkg.Types, "bar", a)) + scope.Insert(NewSubst(token.NoPos, pkg.Types, "bar", a)) o := Lookup(scope, "bar") if o != a { t.Fatal("TestSubstVar:", o) diff --git a/type_var_and_const.go b/type_var_and_const.go index ca45e6f2..2f19c9a6 100644 --- a/type_var_and_const.go +++ b/type_var_and_const.go @@ -782,7 +782,7 @@ func (p *SubstType) String() string { return fmt.Sprintf("substType{real: %v}", p.Real) } -func NewSubstVar(pos token.Pos, pkg *types.Package, name string, real types.Object) *types.Var { +func NewSubst(pos token.Pos, pkg *types.Package, name string, real types.Object) *types.Var { return types.NewVar(pos, pkg, name, &SubstType{Real: real}) }