Skip to content

Commit

Permalink
feat:named and unnamed type assignment 2 of 3
Browse files Browse the repository at this point in the history
  • Loading branch information
piux2 committed Oct 15, 2023
1 parent fa8eb77 commit 2fd4c9b
Show file tree
Hide file tree
Showing 72 changed files with 2,513 additions and 68 deletions.
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 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node {
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 {
mt = dt.Base.(*MapType)
} 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
}
// re-definitions
last.Define(lhs0, anyValue(mt.Value))
last.Define(lhs1, anyValue(BoolType))
Expand Down Expand Up @@ -2146,12 +2151,12 @@ func getResultTypedValues(cx *CallExpr) []TypedValue {
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 @@ func checkOrConvertType(store Store, last BlockNode, x *Expr, t Type, autoNative
// "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 @@ func checkOrConvertType(store Store, last BlockNode, x *Expr, t Type, autoNative
// default:
}
}
// convert x to destination type t
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) {
// covert right (xt) to the type of the left (t)
cx := Expr(Call(constType(nil, t), *x))
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.

_, 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 @@ type Type interface {
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 @@ func (pt PrimitiveType) GetPkgPath() string {
return ""
}

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

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

Expand Down Expand Up @@ -369,6 +374,10 @@ func (ft FieldType) GetPkgPath() string {
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
}

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

Expand Down Expand Up @@ -528,6 +537,10 @@ func (at *ArrayType) GetPkgPath() string {
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 @@ func (st *SliceType) GetPkgPath() string {
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 @@ func (pt *PointerType) GetPkgPath() string {
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 @@ func (st *StructType) GetPkgPath() string {
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 @@ func (pt *PackageType) GetPkgPath() string {
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
}

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

Expand Down Expand Up @@ -927,6 +956,10 @@ func (it *InterfaceType) GetPkgPath() string {
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 @@ func (ct *ChanType) GetPkgPath() string {
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 @@ func (ft *FuncType) GetPkgPath() string {
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 @@ func (mt *MapType) GetPkgPath() string {
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 @@ func (tt *TypeType) GetPkgPath() string {
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
}

// ----------------------------------------
// Declared type
// Declared types have a name, base (underlying) type,
Expand Down Expand Up @@ -1445,6 +1494,10 @@ func (dt *DeclaredType) GetPkgPath() string {
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 @@ func (nt *NativeType) GetPkgPath() string {
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
}

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 @@ func (bt blockType) GetPkgPath() string {
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
}

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

Expand Down Expand Up @@ -1889,6 +1954,10 @@ func (tt *tupleType) GetPkgPath() string {
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
}

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

Expand Down Expand Up @@ -1916,6 +1985,10 @@ func (rt RefType) GetPkgPath() string {
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
}

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

Expand Down Expand Up @@ -1946,6 +2019,10 @@ func (mn MaybeNativeType) GetPkgPath() string {
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 @@ func (tv *TypedValue) Sprint(m *Machine) string {
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
}
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",
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

0 comments on commit 2fd4c9b

Please sign in to comment.