48 lines
1.1 KiB
Go

package core
import (
"git.akyoto.dev/cli/q/src/build/ast"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/token"
)
// Scope represents an independent code block.
type Scope struct {
cpu.State
variables map[string]*Variable
}
// Scope returns the current scope.
func (s *state) Scope() *Scope {
return s.scopes[len(s.scopes)-1]
}
// pushScope pushes a new scope to the top of the stack.
func (s *state) pushScope(body ast.AST) {
scope := &Scope{}
if len(s.scopes) > 0 {
lastScope := s.scopes[len(s.scopes)-1]
scope.State = lastScope.State
scope.variables = make(map[string]*Variable, len(lastScope.variables))
for k, v := range lastScope.variables {
scope.variables[k] = &Variable{
Value: v.Value,
Name: v.Name,
Register: v.Register,
Alive: ast.Count(body, token.Identifier, v.Name),
}
}
} else {
scope.variables = map[string]*Variable{}
}
s.scopes = append(s.scopes, scope)
}
// popScope removes the scope at the top of the stack.
func (s *state) popScope() {
s.scopes = s.scopes[:len(s.scopes)-1]
}