...
1 package ast
2
3 import (
4 `fmt`
5 `strings`
6 `unsafe`
7
8 `github.com/bytedance/sonic/internal/native/types`
9 )
10
11
12 func newError(err types.ParsingError, msg string) *Node {
13 return &Node{
14 t: V_ERROR,
15 l: uint(err),
16 p: unsafe.Pointer(&msg),
17 }
18 }
19
20
21 func (self Node) Error() string {
22 if self.t != V_ERROR {
23 return ""
24 } else {
25 return *(*string)(self.p)
26 }
27 }
28
29 func newSyntaxError(err SyntaxError) *Node {
30 msg := err.Description()
31 return &Node{
32 t: V_ERROR,
33 l: uint(err.Code),
34 p: unsafe.Pointer(&msg),
35 }
36 }
37
38 func (self *Parser) syntaxError(err types.ParsingError) SyntaxError {
39 return SyntaxError{
40 Pos : self.p,
41 Src : self.s,
42 Code: err,
43 }
44 }
45
46 func unwrapError(err error) *Node {
47 if se, ok := err.(*Node); ok {
48 return se
49 }else if sse, ok := err.(Node); ok {
50 return &sse
51 } else {
52 msg := err.Error()
53 return &Node{
54 t: V_ERROR,
55 p: unsafe.Pointer(&msg),
56 }
57 }
58 }
59
60 type SyntaxError struct {
61 Pos int
62 Src string
63 Code types.ParsingError
64 Msg string
65 }
66
67 func (self SyntaxError) Error() string {
68 return fmt.Sprintf("%q", self.Description())
69 }
70
71 func (self SyntaxError) Description() string {
72 return "Syntax error " + self.description()
73 }
74
75 func (self SyntaxError) description() string {
76 i := 16
77 p := self.Pos - i
78 q := self.Pos + i
79
80
81 if self.Src == "" {
82 return fmt.Sprintf("no sources available: %#v", self)
83 }
84
85
86 if p < 0 {
87 p, q, i = 0, q - p, i + p
88 }
89
90
91 if n := len(self.Src); q > n {
92 n = q - n
93 q = len(self.Src)
94
95
96 if p > n {
97 i += n
98 p -= n
99 }
100 }
101
102
103 x := clamp_zero(i)
104 y := clamp_zero(q - p - i - 1)
105
106
107 return fmt.Sprintf(
108 "at index %d: %s\n\n\t%s\n\t%s^%s\n",
109 self.Pos,
110 self.Message(),
111 self.Src[p:q],
112 strings.Repeat(".", x),
113 strings.Repeat(".", y),
114 )
115 }
116
117 func (self SyntaxError) Message() string {
118 if self.Msg == "" {
119 return self.Code.Message()
120 }
121 return self.Msg
122 }
123
124 func clamp_zero(v int) int {
125 if v < 0 {
126 return 0
127 } else {
128 return v
129 }
130 }
131
View as plain text