-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherrors.go
117 lines (102 loc) · 3.11 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package golisp2
import "fmt"
type (
// ParseError reflects an error that took place during parsing. It contains
// information
ParseError struct {
Msg string
Token ScannedToken
}
// ForbiddenRuneError indicates that an illegal character was found in the
// source.
ForbiddenRuneError struct {
R rune
Pos ScannerPosition
}
// TypeError is a runtime error when the incorrect type is passed to a
// function.
TypeError struct {
Actual, Expected string
Pos ScannerPosition
}
// EvalError is a basic runtime error indicating something went wrong during
// execution.
EvalError struct {
Msg string
Pos ScannerPosition
}
// ArgTypeError indicates a mismatch between a given argument value and the
// expected type.
//
// note (bs): this is a fairly awkward error type that probably should just be
// a type error. However, there are some structural limitations with built-ins
// that make that challenging.
ArgTypeError struct {
FnName string
ArgI int
Expected, Actual string
}
)
// NewParseError creates a new parse error with the given message and token.
func NewParseError(msg string, token ScannedToken) *ParseError {
return &ParseError{
Msg: msg,
Token: token,
}
}
// NewParseEOFError represents a parsing error for unexpected EOF.
func NewParseEOFError(msg string, pos ScannerPosition) *ParseError {
return &ParseError{
Msg: msg,
Token: ScannedToken{
Typ: NoTT,
Pos: pos,
},
}
}
// Error returns the informational error string about the parse error.
func (pe ParseError) Error() string {
// note (bs): I don't think this is a very well-laid out error message, but
// it's a place to start at least.
msg, token, pos := pe.Msg, pe.Token, pe.Token.Pos
return fmt.Sprintf(
"Parse error %s for token `%s`: file '%s' at line %d, column %d",
msg, token.Value, pos.SourceFile, pos.Row, pos.Col)
}
// NewForbiddenRuneError creates a ForbiddenRuneError for the given rune and
// location it was found.
func NewForbiddenRuneError(r rune, pos ScannerPosition) *ForbiddenRuneError {
return &ForbiddenRuneError{
R: r,
Pos: pos,
}
}
// Error returns the informational error string about the parse error.
func (pe ForbiddenRuneError) Error() string {
return fmt.Sprintf(
"Forbidden rune '%x' found in scan of '%s' (line %d, col %d)",
pe.R, pe.Pos.SourceFile, pe.Pos.Row, pe.Pos.Col)
}
// NewTypeError creates a new type error with the actual and expected types at
// the given location in source.
func NewTypeError(actual, expected string, pos ScannerPosition) *TypeError {
return &TypeError{
Actual: actual,
Expected: expected,
Pos: pos,
}
}
func (te TypeError) Error() string {
return fmt.Sprintf(
"Type error: expected '%s', got '%s' (%s:%d)",
te.Expected, te.Actual,
te.Pos.SourceFile, te.Pos.Row)
}
func (ee EvalError) Error() string {
return fmt.Sprintf("Eval error '%s': '%s' (line %d, col %d)",
ee.Msg, ee.Pos.SourceFile, ee.Pos.Row, ee.Pos.Col)
}
func (ate *ArgTypeError) Error() string {
return fmt.Sprintf("Arg-type error in '%s' at arg %d: expected '%s', got '%s'",
ate.FnName, ate.ArgI, ate.Expected, ate.Actual)
}