php2go/scope.go
2020-04-05 16:35:44 +12:00

61 lines
1.1 KiB
Go

package main
const (
unknownVarType string = `unknown` // placeholder
mixedVarType string = `mixed` // when setting an incompatible type
)
type LocalVar struct {
Name string
Type string
}
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, Type string) *LocalVar {
if lv := this.Has(Name); lv != nil {
// Update known type for existing variable
if lv.Type == unknownVarType {
lv.Type = Type
} else if lv.Type == Type {
// no-op, more evidence for the same type
} else if lv.Type != Type {
// 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]
}