php2go/scope.go

61 lines
1.2 KiB
Go
Raw Normal View History

2020-04-05 04:35:44 +00:00
package main
var (
unknownVarType gotype = gotype{Plain: `unknown`} // placeholder
mixedVarType gotype = gotype{Plain: `mixed`} // when setting an incompatible type
2020-04-05 04:35:44 +00:00
)
type LocalVar struct {
Name string
Type gotype
2020-04-05 04:35:44 +00:00
}
type Scope struct {
parent *Scope
locals []LocalVar
}
func NewScope() *Scope {
return &Scope{}
}
func (this *Scope) NewScope() *Scope {
return &Scope{
parent: this,
}
}
func (this *Scope) Has(varName string) *LocalVar {
for idx := range this.locals {
if this.locals[idx].Name == varName {
return &this.locals[idx] // Mutable
}
}
if this.parent != nil {
return this.parent.Has(varName)
}
return nil // not found
}
func (this *Scope) Set(Name string, Type gotype) *LocalVar {
2020-04-05 04:35:44 +00:00
if lv := this.Has(Name); lv != nil {
// Update known type for existing variable
2020-04-16 06:36:34 +00:00
if lv.Type.Equals(&unknownVarType) {
2020-04-05 04:35:44 +00:00
lv.Type = Type
2020-04-16 06:36:34 +00:00
} else if lv.Type.Equals(&Type) {
2020-04-05 04:35:44 +00:00
// no-op, more evidence for the same type
2020-04-16 06:36:34 +00:00
} else if !lv.Type.Equals(&Type) {
2020-04-05 04:35:44 +00:00
// conflicting type information
lv.Type = mixedVarType
}
return lv
}
// Insert new
this.locals = append(this.locals, LocalVar{Name: Name, Type: Type})
return &this.locals[len(this.locals)-1]
}