neoneo-go/pkg/compiler/vars.go
Evgenii Stratonikov 1ee4acbdbc compiler: manage variables in a separate varScope struct
Abstract var scope management from the funcScope.
2020-06-30 10:31:51 +03:00

63 lines
1.2 KiB
Go

package compiler
type varScope struct {
localsCnt int
argCnt int
arguments map[string]int
locals []map[string]int
}
func newVarScope() varScope {
return varScope{
arguments: make(map[string]int),
}
}
func (c *varScope) newScope() {
c.locals = append(c.locals, map[string]int{})
}
func (c *varScope) dropScope() {
c.locals = c.locals[:len(c.locals)-1]
}
func (c *varScope) getVarIndex(name string) (varType, int) {
for i := len(c.locals) - 1; i >= 0; i-- {
if i, ok := c.locals[i][name]; ok {
return varLocal, i
}
}
if i, ok := c.arguments[name]; ok {
return varArgument, i
}
return 0, -1
}
// newVariable creates a new local variable or argument in the scope of the function.
func (c *varScope) newVariable(t varType, name string) int {
var n int
switch t {
case varLocal:
return c.newLocal(name)
case varArgument:
_, ok := c.arguments[name]
if ok {
panic("argument is already allocated")
}
n = len(c.arguments)
c.arguments[name] = n
default:
panic("invalid type")
}
return n
}
// newLocal creates a new local variable in the current scope.
func (c *varScope) newLocal(name string) int {
idx := len(c.locals) - 1
m := c.locals[idx]
m[name] = c.localsCnt
c.localsCnt++
c.locals[idx] = m
return c.localsCnt - 1
}