gotype: support function types
This commit is contained in:
parent
3f8377d9fe
commit
fc0008a208
46
gotype.go
46
gotype.go
@ -1,14 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type gotype struct {
|
||||
SliceOf *gotype
|
||||
MapKey *gotype
|
||||
MapVal *gotype
|
||||
PtrTo *gotype
|
||||
Plain string
|
||||
|
||||
IsFunc bool
|
||||
FuncParams []gotype
|
||||
FuncReturn []gotype
|
||||
|
||||
Plain string
|
||||
// TODO channel-of (although we will never? construct one from PHP source)
|
||||
}
|
||||
|
||||
func goTypeListToString(gotypes []gotype) string {
|
||||
ret := make([]string, 0, len(gotypes))
|
||||
for _, gt := range gotypes {
|
||||
ret = append(ret, gt.AsGoString())
|
||||
}
|
||||
return strings.Join(ret, `, `)
|
||||
}
|
||||
|
||||
func (gt gotype) AsGoString() string {
|
||||
if gt.SliceOf != nil {
|
||||
return "[]" + gt.SliceOf.AsGoString()
|
||||
@ -19,17 +36,38 @@ func (gt gotype) AsGoString() string {
|
||||
} else if gt.PtrTo != nil {
|
||||
return "*" + gt.PtrTo.AsGoString()
|
||||
|
||||
} else if gt.IsFunc {
|
||||
|
||||
ret := "func(" + goTypeListToString(gt.FuncParams) + `)`
|
||||
if len(gt.FuncReturn) == 1 {
|
||||
ret += ` ` + gt.FuncReturn[0].AsGoString()
|
||||
} else if len(gt.FuncReturn) >= 2 {
|
||||
ret += ` (` + goTypeListToString(gt.FuncReturn) + `)`
|
||||
}
|
||||
return ret
|
||||
|
||||
} else {
|
||||
return gt.Plain
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (gt gotype) IsPlain() bool {
|
||||
if gt.SliceOf != nil || gt.MapKey != nil || gt.PtrTo != nil || gt.IsFunc {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (gt gotype) Equals(other *gotype) bool {
|
||||
return gt.AsGoString() == other.AsGoString()
|
||||
}
|
||||
|
||||
// ZeroValue returns a Go literal string for the zero value of this type.
|
||||
func (gt gotype) ZeroValue() string {
|
||||
if gt.SliceOf != nil || gt.MapKey != nil || gt.PtrTo != nil {
|
||||
return `nil` // gt.AsGoString() + "{}"
|
||||
|
||||
if !gt.IsPlain() {
|
||||
return `nil`
|
||||
}
|
||||
|
||||
// It's a plain type
|
||||
|
6
scope.go
6
scope.go
@ -43,11 +43,11 @@ func (this *Scope) Set(Name string, Type gotype) *LocalVar {
|
||||
|
||||
if lv := this.Has(Name); lv != nil {
|
||||
// Update known type for existing variable
|
||||
if lv.Type == unknownVarType {
|
||||
if lv.Type.Equals(&unknownVarType) {
|
||||
lv.Type = Type
|
||||
} else if lv.Type == Type {
|
||||
} else if lv.Type.Equals(&Type) {
|
||||
// no-op, more evidence for the same type
|
||||
} else if lv.Type != Type {
|
||||
} else if !lv.Type.Equals(&Type) {
|
||||
// conflicting type information
|
||||
lv.Type = mixedVarType
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user