diff --git a/pkg/eval/builtin_special.go b/pkg/eval/builtin_special.go index a6e7f0d3..8b8bdb21 100644 --- a/pkg/eval/builtin_special.go +++ b/pkg/eval/builtin_special.go @@ -305,9 +305,10 @@ func evalModule(fm *Frame, key string, src *Source) (Ns, error) { newFm := &Frame{ fm.Evaler, src, + diag.Ranging{From: 0, To: len(src.Code)}, modGlobal, make(Ns), fm.ports, - 0, len(src.Code), fm.addTraceback(), false, + fm.addTraceback(), false, } op, err := compile(newFm.Builtin.static(), modGlobal.static(), n, src) diff --git a/pkg/eval/compile_effect.go b/pkg/eval/compile_effect.go index 02457b6f..eb43475b 100644 --- a/pkg/eval/compile_effect.go +++ b/pkg/eval/compile_effect.go @@ -232,7 +232,7 @@ func (cp *compiler) formOp(n *parse.Form) effectOp { redirOps := cp.redirOps(n.Redirs) // TODO: n.ErrorRedir - return makeEffectOp(n, &formOp{saveVarsOps, assignmentOps, redirOps, specialOpFunc, headOp, argOps, optsOp, spaceyAssignOp, n.Range().From, n.Range().To}) + return makeEffectOp(n, &formOp{saveVarsOps, assignmentOps, redirOps, specialOpFunc, headOp, argOps, optsOp, spaceyAssignOp}) } func (cp *compiler) formOps(ns []*parse.Form) []effectOp { @@ -252,10 +252,12 @@ type formOp struct { argOps []valuesOp optsOp valuesOpBody spaceyAssignOp effectOp - begin, end int } func (op *formOp) invoke(fm *Frame) (errRet error) { + // Save the range for the entire form. + formRange := fm.srcRange + // ec here is always a subevaler created in compiler.pipeline, so it can // be safely modified. @@ -357,8 +359,7 @@ func (op *formOp) invoke(fm *Frame) (errRet error) { } } - fm.begin, fm.end = op.begin, op.end - + fm.srcRange = formRange if headFn != nil { return headFn.Call(fm, args, convertedOpts) } diff --git a/pkg/eval/frame.go b/pkg/eval/frame.go index 6523bf60..c806728d 100644 --- a/pkg/eval/frame.go +++ b/pkg/eval/frame.go @@ -16,13 +16,13 @@ import ( // shortly after creation; new Frame's are "forked" when needed. type Frame struct { *Evaler - srcMeta *Source + srcMeta *Source + srcRange diag.Ranging local, up Ns ports []*Port - begin, end int - traceback *stackTrace + traceback *stackTrace background bool } @@ -33,9 +33,10 @@ type Frame struct { func NewTopFrame(ev *Evaler, src *Source, ports []*Port) *Frame { return &Frame{ ev, src, + diag.Ranging{From: 0, To: len(src.Code)}, ev.Global, make(Ns), ports, - 0, len(src.Code), nil, false, + nil, false, } } @@ -125,10 +126,10 @@ func (fm *Frame) fork(name string) *Frame { } } return &Frame{ - fm.Evaler, fm.srcMeta, + fm.Evaler, fm.srcMeta, fm.srcRange, fm.local, fm.up, newPorts, - fm.begin, fm.end, fm.traceback, fm.background, + fm.traceback, fm.background, } } @@ -201,7 +202,7 @@ func (fm *Frame) makeException(e error) error { func (fm *Frame) addTraceback() *stackTrace { return &stackTrace{ entry: diag.NewContext( - fm.srcMeta.Name, fm.srcMeta.Code, fm.begin, fm.end), + fm.srcMeta.Name, fm.srcMeta.Code, fm.srcRange.From, fm.srcRange.To), next: fm.traceback, } } @@ -209,6 +210,6 @@ func (fm *Frame) addTraceback() *stackTrace { // Amends the being and end of the current frame and returns the result of // fmt.Errorf. func (fm *Frame) errorpf(begin, end int, format string, args ...interface{}) error { - fm.begin, fm.end = begin, end + fm.srcRange = diag.Ranging{From: begin, To: end} return fmt.Errorf(format, args...) } diff --git a/pkg/eval/op.go b/pkg/eval/op.go index 52cbee22..b98ad9de 100644 --- a/pkg/eval/op.go +++ b/pkg/eval/op.go @@ -29,7 +29,7 @@ type effectOpBody interface { // Executes an effectOp for side effects. func (op effectOp) exec(fm *Frame) error { - fm.begin, fm.end = op.From, op.To + fm.srcRange = op.Ranging return op.body.invoke(fm) } @@ -50,7 +50,7 @@ type valuesOpBody interface { // Executes a ValuesOp and produces values. func (op valuesOp) exec(fm *Frame) ([]interface{}, error) { - fm.begin, fm.end = op.From, op.To + fm.srcRange = op.Ranging return op.body.invoke(fm) } @@ -71,6 +71,6 @@ func (op lvaluesOp) exec(fm *Frame) ([]vars.Var, error) { if op.body == nil { return []vars.Var{}, nil } - fm.begin, fm.end = op.From, op.To + fm.srcRange = op.Ranging return op.body.invoke(fm) }