Skip to content

Instantly share code, notes, and snippets.

@kfsone
Created March 1, 2021 23:41
Show Gist options
  • Save kfsone/89f25d1b64cc60edb58a2a403e1f43d0 to your computer and use it in GitHub Desktop.
Save kfsone/89f25d1b64cc60edb58a2a403e1f43d0 to your computer and use it in GitHub Desktop.
func (e *Error) Error() string {
w := new(strings.Builder)
fmt.Fprintf(w, "%d:%d: error: ", e.ErrorToken.Pos.Line, e.ErrorToken.Pos.Column)
if e.Err != nil {
fmt.Fprintf(w, "%w: %q", e.Err, e.ErrorToken.Lit)
} else {
if len(e.ExpectedTokens) == 1 {
// if there's only one expectation, don't describe it in list terms.
fmt.Fprint(w, "expected: ", e.ExpectedTokens[0])
} else if len(e.ExpectedTokens) == 2 {
// for two, use a simple "either" expression
fmt.Fprint(w, "expected either ", e.ExpectedTokens[0], " or ", e.ExpectedTokens[1])
} else {
// for a plurality > 2, use the expression "expected one of" and use an oxford comma to
// conclude the list.
fmt.Fprintf(w, "expected one of: ")
expected := make([]string, len(e.ExpectedTokens))
for idx, tok := range e.ExpectedTokens {
switch idx {
case 0:
// noop
default:
if idx == len(expected) - 1 {
fmt.Fprint(w, ", or ")
} else {
fmt.Fprint(w, ", ")
}
}
fmt.Fprint(w, tok)
}
}
fmt.Fprint(w, "; got: ", string(e.ErrorToken.Lit))
}
return w.String()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment