Skip to content

Commit

Permalink
PointerType is *PointerType; VPTypeDeref and VPTypeMethod
Browse files Browse the repository at this point in the history
  • Loading branch information
jaekwon committed Apr 27, 2021
1 parent eee0ff2 commit 6ccbc9c
Show file tree
Hide file tree
Showing 22 changed files with 390 additions and 107 deletions.
12 changes: 12 additions & 0 deletions go2gno.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,18 @@ func Go2Gno(gon ast.Node) (n Node) {
"unexpected *ast.TypeSwitchStmt.Assign type %s",
reflect.TypeOf(gon.Assign).String()))
}
case *ast.ChanType:
var dir ChanDir
if gon.Dir&ast.SEND > 0 {
dir |= SEND
}
if gon.Dir&ast.RECV > 0 {
dir |= RECV
}
return &ChanTypeExpr{
Dir: dir,
Value: toExpr(gon.Value),
}
default:
panic(fmt.Sprintf("unknown Go type %v: %s\n",
reflect.TypeOf(gon),
Expand Down
8 changes: 4 additions & 4 deletions gonative.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func go2GnoType2(rt reflect.Type) (t Type) {
mt.Value = go2GnoType(rt.Elem())
return mt
case reflect.Ptr:
return PointerType{
return &PointerType{
// this is the only recursive call to go2GnoType2().
Elt: go2GnoType2(rt.Elem()),
}
Expand Down Expand Up @@ -724,7 +724,7 @@ func go2GnoValue2(rv reflect.Value) (tv TypedValue) {
case reflect.Map:
panic("not yet implemented")
case reflect.Ptr:
tv.T = PointerType{Elt: go2GnoType2(rv.Type().Elem())}
tv.T = &PointerType{Elt: go2GnoType2(rv.Type().Elem())}
val := go2GnoValue2(rv.Elem())
tv.V = PointerValue{TypedValue: &val} // heap alloc
case reflect.Struct:
Expand Down Expand Up @@ -818,7 +818,7 @@ func gno2GoType(t Type) reflect.Type {
default:
panic("should not happen")
}
case PointerType:
case *PointerType:
et := gno2GoType(ct.Elem())
return reflect.PtrTo(et)
case *ArrayType:
Expand Down Expand Up @@ -945,7 +945,7 @@ func gno2GoValue(tv *TypedValue, rv reflect.Value) (ret reflect.Value) {
"unexpected type %s",
tv.T.String()))
}
case PointerType:
case *PointerType:
// This doesn't take into account pointer relativity, or even
// identical pointers -- every non-nil gno pointer type results in a
// new addressable value in go.
Expand Down
4 changes: 2 additions & 2 deletions hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ func (tv *TypedValue) ValueImage(rlm *Realm, owned bool) *ValueImage {
ValType: ValTypeBytes,
Data: pbz,
}
case PointerType:
case *PointerType:
pv := tv.V.(PointerValue)
if pv.TypedValue == nil {
panic("should not happen")
Expand Down Expand Up @@ -870,7 +870,7 @@ func (tv *TypedValue) ElemImage(rlm *Realm, owned bool) ElemImage {
TypeID: tv.T.TypeID(),
}
}
case PointerType, *SliceType, *TypeType:
case *PointerType, *SliceType, *TypeType:
// 0x13,sz(TypeID),sz(ValueHash) if other.
vi := tv.ValueImage(rlm, owned)
return ElemImage{
Expand Down
4 changes: 3 additions & 1 deletion interpret.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ const (
OpSliceType Op = 0x72 // []X{}
OpPointerType Op = 0x73 // *X
OpInterfaceType Op = 0x74 // interface{...}
OpChanType Op = 0x75 // chan[X]
OpChanType Op = 0x75 // [<-]chan[<-]X
OpFuncType Op = 0x76 // func(params...)results...
OpMapType Op = 0x77 // map[X]Y
OpStructType Op = 0x78 // struct{...}
Expand Down Expand Up @@ -691,6 +691,8 @@ func (m *Machine) Run() {
m.doOpArrayType()
case OpSliceType:
m.doOpSliceType()
case OpChanType:
m.doOpChanType()
case OpFuncType:
m.doOpFuncType()
case OpMapType:
Expand Down
23 changes: 20 additions & 3 deletions nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -1377,9 +1377,10 @@ type VPType uint8
const (
VPTypeUverse VPType = 0x00
VPTypeDefault VPType = 0x01
VPTypeInterface VPType = 0x02
VPTypeNative VPType = 0x03
// TODO: consider VPTypeDeclared (method)
VPTypeDeref VPType = 0x02
VPTypeMethod VPType = 0x03
VPTypeInterface VPType = 0x04
VPTypeNative VPType = 0x05
)

func NewValuePath(t VPType, depth uint8, index uint16, n Name) ValuePath {
Expand All @@ -1401,6 +1402,14 @@ func NewValuePathDefault(depth uint8, index uint16, n Name) ValuePath {
return NewValuePath(VPTypeDefault, depth, index, n)
}

func NewValuePathDeref(depth uint8, index uint16, n Name) ValuePath {
return NewValuePath(VPTypeDeref, depth, index, n)
}

func NewValuePathMethod(index uint16, n Name) ValuePath {
return NewValuePath(VPTypeMethod, 1, index, n)
}

func NewValuePathInterface(n Name) ValuePath {
return NewValuePath(VPTypeInterface, 1, 0, n)
}
Expand All @@ -1419,6 +1428,14 @@ func (vp ValuePath) Validate() {
if vp.Depth == 0 {
panic("general value path cannot have depth 0")
}
case VPTypeDeref:
if vp.Depth == 0 {
panic("dereference value path cannot have depth 0")
}
case VPTypeMethod:
if vp.Depth != 1 {
panic("method value path must have depth 1")
}
case VPTypeInterface:
if vp.Depth != 1 {
panic("interface value path must have depth 1")
Expand Down
3 changes: 3 additions & 0 deletions op_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ func isEql(lv, rv *TypedValue) bool {
}
}
return lv.V == rv.V
case PointerKind:
// TODO: assumes runtime instance normalization.
return lv.V == rv.V
case StructKind:
panic("NOT YET IMPLEMENTED")
default:
Expand Down
5 changes: 5 additions & 0 deletions op_eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,11 @@ func (m *Machine) doOpEval() {
// evaluate x
m.PushExpr(x.X)
m.PushOp(OpEval)
case *ChanTypeExpr:
m.PushOp(OpChanType)
// continuation
m.PushExpr(x.Value)
m.PushOp(OpEval) // OpEvalType?
default:
panic(fmt.Sprintf("unexpected expression %#v", x))
}
Expand Down
8 changes: 4 additions & 4 deletions op_expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ func (m *Machine) doOpSlice() {
func (m *Machine) doOpStar() {
xv := m.PopValue()
switch bt := baseOf(xv.T).(type) {
case PointerType:
case *PointerType:
pv := xv.V.(PointerValue)
if pv.T == DataByteType {
tv := TypedValue{T: xv.T.(PointerType).Elt}
tv := TypedValue{T: xv.T.(*PointerType).Elt}
tv.SetUint8(*(pv.V.(DataByteValue).Ref))
m.PushValue(tv)
} else {
Expand All @@ -140,7 +140,7 @@ func (m *Machine) doOpStar() {
}
case *TypeType:
t := xv.GetType()
m.PushValue(asValue(PointerType{Elt: t}))
m.PushValue(asValue(&PointerType{Elt: t}))
case *nativeType:
panic("not yet implemented")
default:
Expand All @@ -166,7 +166,7 @@ func (m *Machine) doOpRef() {
}
}
m.PushValue(TypedValue{
T: PointerType{Elt: xv.T},
T: &PointerType{Elt: xv.T},
V: xv,
})
}
Expand Down
39 changes: 33 additions & 6 deletions op_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,19 @@ func (m *Machine) doOpInterfaceType() {
})
}

func (m *Machine) doOpChanType() {
x := m.PopExpr().(*ChanTypeExpr)
tv := m.PeekValue(1) // re-use as result.
ct := &ChanType{
Dir: x.Dir,
Elt: tv.GetType(),
}
*tv = TypedValue{
T: gTypeType,
V: TypeValue{Type: ct},
}
}

// Evaluate the type of a typed (i.e. not untyped) value.
// This function expects const expressions to have been
// already swapped for *constExpr in the preprocessor. If not, panics.
Expand Down Expand Up @@ -222,7 +235,7 @@ func (m *Machine) doOpTypeOf() {
ft := ct.Base.(*InterfaceType).
GetMethodType(path.Name)
m.PushValue(asValue(ft))
case VPTypeDefault:
case VPTypeMethod:
if debug {
if ct.Base.Kind() == InterfaceKind {
panic("should not happen")
Expand All @@ -248,8 +261,14 @@ func (m *Machine) doOpTypeOf() {
}
ft := ct.GetMethodType(path.Name)
m.PushValue(asValue(ft))
case PointerType:
case *PointerType:
if dt, ok := ct.Elt.(*DeclaredType); ok {
if debug {
if path.Type != VPTypeDeref &&
path.Type != VPTypeMethod {
panic("should not happen")
}
}
xt = dt
goto TYPE_SWITCH
} else {
Expand Down Expand Up @@ -277,6 +296,11 @@ func (m *Machine) doOpTypeOf() {
m.Run() // XXX replace
xv := m.ReapValues(start)[0]
switch t := xv.GetType().(type) {
case *PointerType:
dt := t.Elt.(*DeclaredType)
t2 := dt.GetValueRefAt(path).T
m.PushValue(asValue(t2))
return
case *DeclaredType:
t2 := t.GetValueRefAt(path).T
m.PushValue(asValue(t2))
Expand All @@ -296,7 +320,10 @@ func (m *Machine) doOpTypeOf() {
m.PushValue(asValue(t2))
return
default:
panic("unexpected selector base typeval.")
panic(fmt.Sprintf(
"unexpected selector base typeval: %s of kind %s.",
xv.GetType().String(),
xv.GetType().Kind().String()))
}
case *PackageType:
start := m.NumValues
Expand Down Expand Up @@ -363,7 +390,7 @@ func (m *Machine) doOpTypeOf() {
m.PushOp(OpTypeOf)
m.Run() // XXX replace
xt := m.ReapValues(start)[0].V.(TypeValue).Type
if pt, ok := xt.(PointerType); ok {
if pt, ok := xt.(*PointerType); ok {
m.PushValue(asValue(&SliceType{
Elt: pt.Elt.Elem(),
}))
Expand All @@ -379,7 +406,7 @@ func (m *Machine) doOpTypeOf() {
m.PushOp(OpTypeOf)
m.Run() // XXX replace
xt := m.ReapValues(start)[0].GetType()
if pt, ok := xt.(PointerType); ok {
if pt, ok := xt.(*PointerType); ok {
m.PushValue(asValue(pt.Elt))
} else if _, ok := xt.(*TypeType); ok {
m.PushValue(asValue(gTypeType))
Expand All @@ -393,7 +420,7 @@ func (m *Machine) doOpTypeOf() {
m.PushOp(OpTypeOf)
m.Run() // XXX replace
xt := m.ReapValues(start)[0].GetType()
m.PushValue(asValue(PointerType{Elt: xt}))
m.PushValue(asValue(&PointerType{Elt: xt}))
case *TypeAssertExpr:
if x.HasOK {
panic("type assert assignment used with return 2 values; has no type")
Expand Down
Loading

0 comments on commit 6ccbc9c

Please sign in to comment.