gotype: initial commit of Go type abstraction

This commit is contained in:
mappu 2020-04-11 12:49:08 +12:00
parent 71a4efbbda
commit 86266ae676
3 changed files with 68 additions and 9 deletions

59
gotype.go Normal file
View File

@ -0,0 +1,59 @@
package main
type gotype struct {
SliceOf *gotype
MapKey *gotype
MapVal *gotype
PtrTo *gotype
Plain string
// TODO channel-of (although we will never? construct one from PHP source)
}
func (gt gotype) AsGoString() string {
if gt.SliceOf != nil {
return "[]" + gt.SliceOf.AsGoString()
} else if gt.MapKey != nil {
return "map[" + gt.MapKey.AsGoString() + "]" + gt.MapVal.AsGoString()
} else if gt.PtrTo != nil {
return "*" + gt.PtrTo.AsGoString()
} else {
return gt.Plain
}
}
// 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() + "{}"
}
// It's a plain type
switch gt.Plain {
case "byte",
"int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64",
"float", "float64":
return `0`
case "bool":
return `false`
case "string":
return `""`
case "rune":
return `''`
default:
// probably a struct type
return gt.AsGoString() + `{}`
}
}

View File

@ -253,7 +253,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
// 'Modifiers' - protected public readonly ...
// prop.Modifiers
memberVars = append(memberVars, name+" "+memberType)
memberVars = append(memberVars, name+" "+memberType.AsGoString())
case *stmt.ClassConstList:
// Class constant
@ -1471,7 +1471,7 @@ func removeParens(expr string) string {
func (this *conversionState) resolveName(n node.Node) (string, error) {
// TODO support namespace lookups
ret := unknownVarType
ret := unknownVarType.AsGoString()
if n == nil || n == node.Node(nil) {
return ret, nil
}
@ -1709,9 +1709,9 @@ func (this *conversionState) convertArrayLiteralCommon(items []node.Node) (strin
}
if isMapType {
return `map[` + keyType + `]` + valType + `{` + strings.Join(entries, " ") + `}`, nil
return `map[` + keyType.AsGoString() + `]` + valType.AsGoString() + `{` + strings.Join(entries, " ") + `}`, nil
} else {
return `[]` + valType + `{` + strings.Join(entries, " ") + `}`, nil
return `[]` + valType.AsGoString() + `{` + strings.Join(entries, " ") + `}`, nil
}
}

View File

@ -1,13 +1,13 @@
package main
const (
unknownVarType string = `unknown` // placeholder
mixedVarType string = `mixed` // when setting an incompatible type
var (
unknownVarType gotype = gotype{Plain: `unknown`} // placeholder
mixedVarType gotype = gotype{Plain: `mixed`} // when setting an incompatible type
)
type LocalVar struct {
Name string
Type string
Type gotype
}
type Scope struct {
@ -39,7 +39,7 @@ func (this *Scope) Has(varName string) *LocalVar {
return nil // not found
}
func (this *Scope) Set(Name, Type string) *LocalVar {
func (this *Scope) Set(Name string, Type gotype) *LocalVar {
if lv := this.Has(Name); lv != nil {
// Update known type for existing variable