aboutsummaryrefslogtreecommitdiff
path: root/errors/errors.go
blob: a8d1eb09b3c7269d2a1f0771605c13a5c276992e (plain)
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
package errors

import (
	"fmt"
	"strings"

	"usebox.net/lang/tokens"
)

type ErrCode int

const (
	Unimplemented ErrCode = iota
	SyntaxError
	IncompleteEscape
	InvalidChar
	ExpectedIdent
	ExpectedType
	AlreadyDeclared
	Undefined
	ExpectedSemicolon
	ExpectedComma
	ExpectedExpr
	ExpectedLParen
	ExpectedRParen
	ExpectedLBrace
	ExpectedRBrace
	ExpectedIn
	ExpectedRBracket
	ExpectedAssign
	ExpectedDefinition
	AssignConst
	FailedNumeric
	InvalidOperation
	InvalidValue
	InvalidLength
	InvalidIndex
	InvalidType
	TypeMismatch
	InvalidTarget
	UndefinedIdent
	NotCallable
	NotIndexable
	NotStruct
	InvalidNumberArgs
	CallError
	NoReturn
	TailCallError
	RecursiveStruct
	Unexpected
)

type Error struct {
	Code    ErrCode
	Message string
	Err     error
}

func (e Error) Error() string {
	return e.Message
}

func (e Error) Unwrap() error {
	return e.Err
}

func formatError(loc tokens.Location, msg ...string) string {
	return fmt.Sprintf("%s:%d col %d error: %s", loc.File, loc.Line, loc.Column, strings.Join(msg, " "))
}

func NewError(code ErrCode, loc tokens.Location, msg ...string) error {
	return Error{
		Code:    code,
		Message: formatError(loc, msg...),
	}
}

func NewErrorWrap(code ErrCode, loc tokens.Location, err error, msg ...string) error {
	return Error{
		Code:    code,
		Message: formatError(loc, msg...),
		Err:     err,
	}
}

type ErrorList struct {
	Errors []error
}

func (el ErrorList) Error() string {
	var b strings.Builder
	var nerrors = len(el.Errors)

	for i := 0; i < nerrors; i++ {
		fmt.Fprint(&b, el.Errors[i])
		if i == 10 {
			fmt.Fprintf(&b, "\n...")
			break
		}
		if i < nerrors-1 {
			fmt.Fprintln(&b)
		}
	}

	return b.String()
}