Skip to content

Commit

Permalink
Merge pull request #247 from Syuparn/fix-evalenv
Browse files Browse the repository at this point in the history
di: fix Str#evalEnv to handle built-in objests
  • Loading branch information
Syuparn authored Mar 8, 2023
2 parents 9174f94 + dc88f98 commit 0459d91
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 5 deletions.
2 changes: 1 addition & 1 deletion di/readnative.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func readNativeCode(
return nil, e
}
if obj.Pairs == nil {
return nil, errors.New("Pairs must not be nil")
return nil, errors.New("pairs must not be nil")
}

return obj.Pairs, nil
Expand Down
9 changes: 5 additions & 4 deletions di/strevalenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

func strEvalEnv(
_ *object.Env,
env *object.Env,
kwargs *object.PanObj,
args ...object.PanObject,
) object.PanObject {
Expand All @@ -20,11 +20,12 @@ func strEvalEnv(
return object.NewTypeErr("\\1 must be str")
}

env := object.NewEnv()
result := eval(strings.NewReader(self.Value), env)
// NOTE: object.NewEnv cannot be used because an empty env does not have built-in objects
newEnv := object.NewEnclosedEnv(env.Global())
result := eval(strings.NewReader(self.Value), newEnv)
if result.Type() == object.ErrType {
return result
}

return env.Items()
return newEnv.Items()
}
9 changes: 9 additions & 0 deletions di/strevalenv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ func TestEvalStrEvalEnv(t *testing.T) {
},
}),
},
{
`"x := true".evalEnv`,
toPanObj([]object.Pair{
{
Key: object.NewPanStr("x"),
Value: object.BuiltInTrue,
},
}),
},
}

for _, tt := range tests {
Expand Down
12 changes: 12 additions & 0 deletions object/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,18 @@ func (e *Env) Outer() *Env {
return e.outer
}

// Global returns the outer environment.
func (e *Env) Global() *Env {
env := e
for {
outer := env.Outer()
if outer == nil {
return env
}
env = outer
}
}

// InjectIO injects reader and writer for `IO` object
func (e *Env) InjectIO(in io.Reader, out io.Writer) {
// define const `IO` containing io of args
Expand Down
12 changes: 12 additions & 0 deletions object/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,15 @@ func TestGetInOuter(t *testing.T) {
obj.Inspect(), found.Inspect())
}
}

func TestEnvGlobal(t *testing.T) {
parent := NewEnv()
child := NewEnclosedEnv(parent)
grandChild := NewEnclosedEnv(child)

actual := grandChild.Global()
if actual != parent {
t.Errorf("wrong env. expected=%+v, got=%+v",
parent, actual)
}
}

0 comments on commit 0459d91

Please sign in to comment.