Store a util.Traceback in util.PosError.

This commit is contained in:
Qi Xiao 2016-10-13 23:03:17 +08:00
parent d341668167
commit 7054a4f0fe
8 changed files with 24 additions and 23 deletions

View File

@ -145,7 +145,7 @@ func (ed *Editor) refresh(fullRefresh bool, tips bool) error {
// Re-lex the line, unless we are in modeCompletion
src := ed.line
if ed.mode.Mode() != modeCompletion {
n, err := parse.Parse(src)
n, err := parse.Parse("[interactive]", src)
ed.parseErrorAtEnd = err != nil && atEnd(err, len(src))
if err != nil {
// If all the errors happen at the end, it is liekly complaining

View File

@ -189,7 +189,7 @@ func use(ec *EvalCtx, modname string, pfilename *string) {
}
}
n, err := parse.Parse(source)
n, err := parse.Parse(filename, source)
maybeThrow(err)
// Make an empty namespace.

View File

@ -36,7 +36,7 @@ func (cp *compiler) compiling(n parse.Node) {
}
func (cp *compiler) errorpf(begin, end int, format string, args ...interface{}) {
throw(&util.PosError{begin, end, fmt.Errorf(format, args...)})
throw(&util.PosError{fmt.Errorf(format, args...), "Compile error", util.Traceback{cp.name, cp.text, begin, end, nil}})
}
func (cp *compiler) errorf(format string, args ...interface{}) {

View File

@ -309,12 +309,13 @@ func (ec *EvalCtx) addTraceback() *util.Traceback {
// errorpf stops the ec.eval immediately by panicking with a diagnostic message.
// The panic is supposed to be caught by ec.eval.
func (ec *EvalCtx) errorpf(begin, end int, format string, args ...interface{}) {
throw(&util.PosError{begin, end, fmt.Errorf(format, args...)})
ec.begin, ec.end = begin, end
throwf(format, args...)
}
// SourceText evaluates a chunk of elvish source.
func (ev *Evaler) SourceText(name, src string) error {
n, err := parse.Parse(src)
n, err := parse.Parse(name, src)
if err != nil {
return err
}

View File

@ -12,8 +12,8 @@ import (
)
// Parse parses elvish source.
func Parse(src string) (*Chunk, error) {
ps := &parser{src, 0, 0, []map[rune]int{{}}, 0, nil}
func Parse(srcname, src string) (*Chunk, error) {
ps := &parser{srcname, src, 0, 0, []map[rune]int{{}}, 0, nil}
bn := parseChunk(ps)
if ps.pos != len(src) {
ps.error(errUnexpectedRune)

View File

@ -13,6 +13,7 @@ import (
//
// NOTE: The str member is assumed to be valid UF-8.
type parser struct {
srcName string
src string
pos int
overEOF int
@ -95,7 +96,7 @@ func (ps *parser) errorp(begin, end int, e error) {
if ps.errors == nil {
ps.errors = &util.Errors{}
}
ps.errors.Append(&util.PosError{begin, end, e})
ps.errors.Append(&util.PosError{e, "Parse error", util.Traceback{ps.srcName, ps.src, begin, end, nil}})
}
func (ps *parser) error(e error) {

View File

@ -139,20 +139,20 @@ func source(ev *eval.Evaler, fname string, notexistok bool) bool {
// evalText is like eval.Evaler.SourceText except that it reports errors.
func evalText(ev *eval.Evaler, name, src string) bool {
n, err := parse.Parse(src)
n, err := parse.Parse(name, src)
if err != nil {
printError(err, name, "Parse error", src)
printError(err, "Parse error")
return false
}
op, err := ev.Compile(n, name, src)
if err != nil {
printError(err, name, "Compile error", src)
printError(err, "Compile error")
return false
}
err = ev.Eval(name, src, op)
if err != nil {
printError(err, name, "Exception", src)
printError(err, "Exception")
return false
}
return true
@ -273,17 +273,17 @@ func newEvalerAndStore() (*eval.Evaler, *store.Store) {
return eval.NewEvaler(st), st
}
func printError(err error, srcname, errtype, src string) {
func printError(err error, errtype string) {
if err == nil {
return
}
switch err := err.(type) {
case *util.Errors:
for _, e := range err.Errors {
printError(e, srcname, errtype, src)
printError(e, errtype)
}
case *util.PosError:
fmt.Fprintln(os.Stderr, err.Pprint(srcname, errtype, src))
fmt.Fprintln(os.Stderr, err.Pprint())
case *util.TracebackError:
fmt.Fprintln(os.Stderr, err.Pprint())
default:

View File

@ -7,23 +7,22 @@ import (
// PosError is an error associated with a position range.
type PosError struct {
Begin int
End int
Err error
Err error
Type string
Traceback
}
func (pe *PosError) Error() string {
return fmt.Sprintf("%d-%d: %s", pe.Begin, pe.End, pe.msg())
return fmt.Sprintf("%d-%d: %s", pe.Traceback.Begin, pe.Traceback.End, pe.msg())
}
// Pprint pretty-prints a PosError.
func (pe *PosError) Pprint(srcname, errtype, src string) string {
func (pe *PosError) Pprint() string {
buf := new(bytes.Buffer)
// Error message
fmt.Fprintf(buf, "%s: \033[31;1m%s\033[m\n", errtype, pe.msg())
fmt.Fprintf(buf, "%s: \033[31;1m%s\033[m\n", pe.Type, pe.msg())
// Position
te := Traceback{srcname, src, pe.Begin, pe.End, nil}
te.Pprint(buf, " ")
pe.Traceback.Pprint(buf, " ")
return buf.String()
}