summaryrefslogtreecommitdiff
path: root/usr/austin/eval/scope.go
diff options
context:
space:
mode:
Diffstat (limited to 'usr/austin/eval/scope.go')
-rw-r--r--usr/austin/eval/scope.go29
1 files changed, 25 insertions, 4 deletions
diff --git a/usr/austin/eval/scope.go b/usr/austin/eval/scope.go
index b3622588c..2b1a968e6 100644
--- a/usr/austin/eval/scope.go
+++ b/usr/austin/eval/scope.go
@@ -9,11 +9,11 @@ import (
)
func NewRootScope() *Scope {
- return &Scope{nil, make(map[string] Def), 0};
+ return &Scope{defs: make(map[string] Def)};
}
func (s *Scope) Fork() *Scope {
- return &Scope{s, make(map[string] Def), 0};
+ return &Scope{outer: s, defs: make(map[string] Def)};
}
func (s *Scope) DefineVar(name string, t Type) *Variable {
@@ -26,11 +26,11 @@ func (s *Scope) DefineVar(name string, t Type) *Variable {
return v;
}
-func (s *Scope) DefineConst(name string, v Value) *Constant {
+func (s *Scope) DefineConst(name string, t Type, v Value) *Constant {
if _, ok := s.defs[name]; ok {
return nil;
}
- c := &Constant{v.Type(), v};
+ c := &Constant{t, v};
s.defs[name] = c;
return c;
}
@@ -53,6 +53,27 @@ func (s *Scope) Lookup(name string) (Def, *Scope) {
return nil, nil;
}
+func (s *Scope) NewFrame(outer *Frame) *Frame {
+ if s.varTypes == nil {
+ // First creation of a frame from this scope. Compute
+ // and memoize the types of all variables.
+ ts := make([]Type, s.numVars);
+ for _, d := range s.defs {
+ if v, ok := d.(*Variable); ok {
+ ts[v.Index] = v.Type;
+ }
+ }
+ s.varTypes = ts;
+ }
+
+ // Create frame
+ vars := make([]Value, s.numVars);
+ for i, t := range s.varTypes {
+ vars[i] = t.Zero();
+ }
+ return &Frame{outer, s, vars};
+}
+
func (f *Frame) Get(s *Scope, index int) Value {
for f.Scope != s {
f = f.Outer;