diff --git a/gotype.go b/gotype.go new file mode 100644 index 0000000..b0b917e --- /dev/null +++ b/gotype.go @@ -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() + `{}` + + } + +} diff --git a/node.go b/node.go index 4b7920b..58a7f89 100644 --- a/node.go +++ b/node.go @@ -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 } } diff --git a/scope.go b/scope.go index 4f94f67..cf92bd4 100644 --- a/scope.go +++ b/scope.go @@ -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