48 lines
1.1 KiB
Go
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]
|
|
}
|