Organize Compiler and Evaluator to be similar to each other

This commit is contained in:
Cheer Xiao 2014-10-13 22:18:30 +02:00
parent 5e83242617
commit b0eade37f8
2 changed files with 22 additions and 11 deletions

View File

@ -13,7 +13,8 @@ type Compiler struct {
compilerEphemeral
}
// compilerEphemeral wraps the ephemeral parts of a Compiler.
// compilerEphemeral wraps the ephemeral parts of a Compiler, namely the parts
// only valid through one startCompile-stopCompile cycle.
type compilerEphemeral struct {
name, text string
scopes []map[string]Type
@ -50,10 +51,15 @@ func (cp *Compiler) startCompile(name, text string, scope map[string]Type) {
}
}
func (cp *Compiler) stopCompile() {
cp.compilerEphemeral = compilerEphemeral{}
}
// Compile compiles a ChunkNode into an Op, with the knowledge of current
// scope. The supplied name and text are used in diagnostic messages.
func (cp *Compiler) Compile(name, text string, n *parse.ChunkNode, scope map[string]Type) (op Op, err error) {
cp.startCompile(name, text, scope)
defer cp.stopCompile()
defer util.Recover(&err)
return cp.compileChunk(n), nil
}

View File

@ -17,9 +17,8 @@ import (
// goroutine. When elvish code spawns goroutines, the Evaluator is copied and
// has certain components replaced.
type Evaluator struct {
Compiler *Compiler
name, text string
context string
Compiler *Compiler
evaluatorEphemeral
scope map[string]*Value
env *Env
searchPaths []string
@ -27,6 +26,12 @@ type Evaluator struct {
statusCb func([]Value)
}
// evaluatorEphemeral holds the ephemeral parts of an Evaluator, namely the
// parts only valid through one startEval-stopEval cycle.
type evaluatorEphemeral struct {
name, text, context string
}
func statusOk(vs []Value) bool {
for _, v := range vs {
v, ok := v.(*String)
@ -150,19 +155,19 @@ func (ev *Evaluator) eval(name, text string, op Op) (err error) {
if op == nil {
return nil
}
defer util.Recover(&err)
ev.startEval(name, text)
defer ev.stopEval()
ev.name = name
ev.text = text
ev.context = "top"
defer util.Recover(&err)
op(ev)
return nil
}
func (ev *Evaluator) startEval(name, text string) {
ev.evaluatorEphemeral = evaluatorEphemeral{name, text, "top"}
}
func (ev *Evaluator) stopEval() {
ev.name = ""
ev.text = ""
ev.context = ""
ev.evaluatorEphemeral = evaluatorEphemeral{}
}
// errorf stops the ev.eval immediately by panicking with a diagnostic message.