Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: named and unnamed type assignment 2 of 3 #1246

Merged
merged 12 commits into from
May 31, 2024
22 changes: 22 additions & 0 deletions examples/gno.land/r/demo/tests/realm_compositelit.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package tests

type (
Word uint
nat []Word
)

var zero = &Int{
neg: true,
abs: []Word{0},
}

// structLit
type Int struct {
neg bool
abs nat
}

func GetZeroType() nat {
a := zero.abs
return a
}
19 changes: 19 additions & 0 deletions examples/gno.land/r/demo/tests/realm_method38d.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package tests

var abs nat

func (n nat) Add() nat {
return []Word{0}
}

func GetAbs() nat {
abs = []Word{0}

return abs
}

func AbsAdd() nat {
rt := GetAbs().Add()

return rt
}
60 changes: 53 additions & 7 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -1538,8 +1538,13 @@
lhs0 := n.Lhs[0].(*NameExpr).Name
lhs1 := n.Lhs[1].(*NameExpr).Name

dt := evalStaticTypeOf(store, last, cx.X)
mt := baseOf(dt).(*MapType)
var mt *MapType
st := evalStaticTypeOf(store, last, cx.X)
if dt, ok := st.(*DeclaredType); ok {
thehowl marked this conversation as resolved.
Show resolved Hide resolved
mt = dt.Base.(*MapType)
piux2 marked this conversation as resolved.
Show resolved Hide resolved
} else if mt, ok = st.(*MapType); !ok {
panic("should not happen")

Check warning on line 1546 in gnovm/pkg/gnolang/preprocess.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/preprocess.go#L1541-L1546

Added lines #L1541 - L1546 were not covered by tests
piux2 marked this conversation as resolved.
Show resolved Hide resolved
}
// re-definitions
last.Define(lhs0, anyValue(mt.Value))
last.Define(lhs1, anyValue(BoolType))
Expand Down Expand Up @@ -2146,12 +2151,12 @@
func evalConst(store Store, last BlockNode, x Expr) *ConstExpr {
// TODO: some check or verification for ensuring x
// is constant? From the machine?
cv := NewMachine(".dontcare", store)
tv := cv.EvalStatic(last, x)
cv.Release()
m := NewMachine(".dontcare", store)
cv := m.EvalStatic(last, x)
m.Release()
cx := &ConstExpr{
Source: x,
TypedValue: tv,
TypedValue: cv,
}
cx.SetAttribute(ATTR_PREPROCESSED, true)
setConstAttrs(cx)
Expand Down Expand Up @@ -2308,11 +2313,13 @@
// "push" expected type into shift binary's left operand.
checkOrConvertType(store, last, &bx.Left, t, autoNative)
} else if *x != nil { // XXX if x != nil && t != nil {
// check type
xt := evalStaticTypeOf(store, last, *x)
if t != nil {
checkType(xt, t, autoNative)
}
if isUntyped(xt) {
// convert type
if isUntyped(xt) { // convert if x is untyped literal
if t == nil {
t = defaultTypeOf(xt)
}
Expand All @@ -2333,13 +2340,52 @@
// default:
}
}
// convert x to destination type t
thehowl marked this conversation as resolved.
Show resolved Hide resolved
cx := Expr(Call(constType(nil, t), *x))
cx = Preprocess(store, last, cx).(Expr)
*x = cx
} else {
// if one side is declared name type and the other side is unnamed type
if isNamedConversion(xt, t) {
thehowl marked this conversation as resolved.
Show resolved Hide resolved
// covert right (xt) to the type of the left (t)
cx := Expr(Call(constType(nil, t), *x))
deelawn marked this conversation as resolved.
Show resolved Hide resolved
cx = Preprocess(store, last, cx).(Expr)
*x = cx
}

Check warning on line 2354 in gnovm/pkg/gnolang/preprocess.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/preprocess.go#L2350-L2354

Added lines #L2350 - L2354 were not covered by tests
}
}
}

// Return true if we need to convert named and unnamed types in an assignment
func isNamedConversion(xt, t Type) bool {
if t == nil {
t = xt
}

Check warning on line 2363 in gnovm/pkg/gnolang/preprocess.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/preprocess.go#L2362-L2363

Added lines #L2362 - L2363 were not covered by tests

// t is left hand destination type, xt is right hand expression type
// In a few special cases, we should not consider compare named and unnamed type
// case 1: if left is interface, which is unnamed, we dont convert to the left type even right is named type.
piux2 marked this conversation as resolved.
Show resolved Hide resolved

_, c1 := t.(*InterfaceType)

// case2: TypeType is used in make() new() native uverse definition and TypeType.IsNamed() will panic on unexpected.

_, oktt := t.(*TypeType)
_, oktt2 := xt.(*TypeType)
c2 := oktt || oktt2

//
if !c1 && !c2 { // carve out above two cases
// covert right to the type of left if one side is unnamed type and the other side is not

if t.IsNamed() && !xt.IsNamed() ||
!t.IsNamed() && xt.IsNamed() {
return true
}

Check warning on line 2384 in gnovm/pkg/gnolang/preprocess.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/preprocess.go#L2383-L2384

Added lines #L2383 - L2384 were not covered by tests
}
return false
}

// like checkOrConvertType(last, x, nil)
func convertIfConst(store Store, last BlockNode, x Expr) {
if cx, ok := x.(*ConstExpr); ok {
Expand Down
77 changes: 77 additions & 0 deletions gnovm/pkg/gnolang/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
String() string // for dev/debugging
Elem() Type // for TODO... types
GetPkgPath() string
IsNamed() bool // named vs unname type. property as a method
}

type TypeID string
Expand Down Expand Up @@ -323,6 +324,10 @@
return ""
}

func (pt PrimitiveType) IsNamed() bool {
return true
}

// ----------------------------------------
// Field type (partial)

Expand Down Expand Up @@ -369,6 +374,10 @@
panic("FieldType is a pseudotype with no package path")
}

func (ft FieldType) IsNamed() bool {
panic("unexpected")

Check warning on line 378 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L377-L378

Added lines #L377 - L378 were not covered by tests
piux2 marked this conversation as resolved.
Show resolved Hide resolved
}

// ----------------------------------------
// FieldTypeList

Expand Down Expand Up @@ -528,6 +537,10 @@
return ""
}

func (at *ArrayType) IsNamed() bool {
return false

Check warning on line 541 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L540-L541

Added lines #L540 - L541 were not covered by tests
}

// ----------------------------------------
// Slice type

Expand Down Expand Up @@ -574,6 +587,10 @@
return ""
}

func (st *SliceType) IsNamed() bool {
return false

Check warning on line 591 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L590-L591

Added lines #L590 - L591 were not covered by tests
}

// ----------------------------------------
// Pointer type

Expand Down Expand Up @@ -612,6 +629,10 @@
return pt.Elt.GetPkgPath()
}

func (pt *PointerType) IsNamed() bool {
return false

Check warning on line 633 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L632-L633

Added lines #L632 - L633 were not covered by tests
}

func (pt *PointerType) FindEmbeddedFieldType(callerPath string, n Name, m map[Type]struct{}) (
trail []ValuePath, hasPtr bool, rcvr Type, field Type, accessError bool,
) {
Expand Down Expand Up @@ -747,6 +768,10 @@
return st.PkgPath
}

func (st *StructType) IsNamed() bool {
return false

Check warning on line 772 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L771-L772

Added lines #L771 - L772 were not covered by tests
}

// NOTE only works for exposed non-embedded fields.
func (st *StructType) GetPathForName(n Name) ValuePath {
for i := 0; i < len(st.Fields); i++ {
Expand Down Expand Up @@ -867,6 +892,10 @@
panic("package types has no package path (unlike package values)")
}

func (pt *PackageType) IsNamed() bool {
panic("unexpected")

Check warning on line 896 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L895-L896

Added lines #L895 - L896 were not covered by tests
thehowl marked this conversation as resolved.
Show resolved Hide resolved
}

// ----------------------------------------
// Interface type

Expand Down Expand Up @@ -927,6 +956,10 @@
return it.PkgPath
}

func (it *InterfaceType) IsNamed() bool {
return false

Check warning on line 960 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L959-L960

Added lines #L959 - L960 were not covered by tests
}

func (it *InterfaceType) FindEmbeddedFieldType(callerPath string, n Name, m map[Type]struct{}) (
trail []ValuePath, hasPtr bool, rcvr Type, ft Type, accessError bool,
) {
Expand Down Expand Up @@ -1074,6 +1107,10 @@
return ""
}

func (ct *ChanType) IsNamed() bool {
return false

Check warning on line 1111 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1110-L1111

Added lines #L1110 - L1111 were not covered by tests
}

// ----------------------------------------
// Function type

Expand Down Expand Up @@ -1275,6 +1312,10 @@
panic("function types have no package path")
}

func (ft *FuncType) IsNamed() bool {
return false

Check warning on line 1316 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1315-L1316

Added lines #L1315 - L1316 were not covered by tests
}

func (ft *FuncType) HasVarg() bool {
if numParams := len(ft.Params); numParams == 0 {
return false
Expand Down Expand Up @@ -1333,6 +1374,10 @@
return ""
}

func (mt *MapType) IsNamed() bool {
return false

Check warning on line 1378 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1377-L1378

Added lines #L1377 - L1378 were not covered by tests
}

// ----------------------------------------
// Type (typeval) type

Expand Down Expand Up @@ -1361,6 +1406,10 @@
panic("typeval types have no package path")
}

func (tt *TypeType) IsNamed() bool {
panic("unexpected")

Check warning on line 1410 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1409-L1410

Added lines #L1409 - L1410 were not covered by tests
thehowl marked this conversation as resolved.
Show resolved Hide resolved
}

// ----------------------------------------
// Declared type
// Declared types have a name, base (underlying) type,
Expand Down Expand Up @@ -1445,6 +1494,10 @@
return dt.PkgPath
}

func (dt *DeclaredType) IsNamed() bool {
return true
}

func (dt *DeclaredType) DefineMethod(fv *FuncValue) {
dt.Methods = append(dt.Methods, TypedValue{
T: fv.Type,
Expand Down Expand Up @@ -1711,6 +1764,14 @@
return "go:" + nt.Type.PkgPath()
}

func (nt *NativeType) IsNamed() bool {
if nt.Type.Name() != "" {
return true
} else {
return false
}

Check warning on line 1772 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1771-L1772

Added lines #L1771 - L1772 were not covered by tests
thehowl marked this conversation as resolved.
Show resolved Hide resolved
}

func (nt *NativeType) GnoType(store Store) Type {
if nt.gnoType == nil {
nt.gnoType = store.Go2GnoType(nt.Type)
Expand Down Expand Up @@ -1839,6 +1900,10 @@
panic("blockType has no package path")
}

func (bt blockType) IsNamed() bool {
panic("unexpected")

Check warning on line 1904 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1903-L1904

Added lines #L1903 - L1904 were not covered by tests
thehowl marked this conversation as resolved.
Show resolved Hide resolved
}

// ----------------------------------------
// tupleType

Expand Down Expand Up @@ -1889,6 +1954,10 @@
panic("typleType has no package path")
}

func (tt *tupleType) IsNamed() bool {
panic("unexpected")

Check warning on line 1958 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1957-L1958

Added lines #L1957 - L1958 were not covered by tests
piux2 marked this conversation as resolved.
Show resolved Hide resolved
}

// ----------------------------------------
// RefType

Expand Down Expand Up @@ -1916,6 +1985,10 @@
panic("should not happen")
}

func (rt RefType) IsNamed() bool {
panic("unexpected")

Check warning on line 1989 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L1988-L1989

Added lines #L1988 - L1989 were not covered by tests
piux2 marked this conversation as resolved.
Show resolved Hide resolved
}

// ----------------------------------------
// MaybeNativeType

Expand Down Expand Up @@ -1946,6 +2019,10 @@
return mn.Type.GetPkgPath()
}

func (mn MaybeNativeType) IsNamed() bool {
return mn.Type.IsNamed()

Check warning on line 2023 in gnovm/pkg/gnolang/types.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/types.go#L2022-L2023

Added lines #L2022 - L2023 were not covered by tests
}

// ----------------------------------------
// Kind

Expand Down
22 changes: 20 additions & 2 deletions gnovm/pkg/gnolang/values_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,29 @@
case *ArrayType:
return tv.V.(*ArrayValue).String()
case *SliceType:
return tv.V.(*SliceValue).String()
switch sv := tv.V.(type) {
case nil:
return tv.String()
case *SliceValue:
return sv.String()
default:
panic(fmt.Sprintf(
"unexpected slice type %v",
reflect.TypeOf(tv.V)))

Check warning on line 238 in gnovm/pkg/gnolang/values_string.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/values_string.go#L230-L238

Added lines #L230 - L238 were not covered by tests
piux2 marked this conversation as resolved.
Show resolved Hide resolved
}
case *StructType:
return tv.V.(*StructValue).String()
case *MapType:
return tv.V.(*MapValue).String()
switch mv := tv.V.(type) {
case nil:
return tv.String()
case *MapValue:
return mv.String()
default:
panic(fmt.Sprintf(
"unexpected slice type %v",
piux2 marked this conversation as resolved.
Show resolved Hide resolved
reflect.TypeOf(tv.V)))

Check warning on line 251 in gnovm/pkg/gnolang/values_string.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/values_string.go#L243-L251

Added lines #L243 - L251 were not covered by tests
}
case *FuncType:
switch fv := tv.V.(type) {
case nil:
Expand Down
Loading
Loading