github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/ast/error.go (about) 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 // Error returns error message if the node is invalid 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 /* check for empty source */ 81 if self.Src == "" { 82 return fmt.Sprintf("no sources available: %#v", self) 83 } 84 85 /* prevent slicing before the beginning */ 86 if p < 0 { 87 p, q, i = 0, q - p, i + p 88 } 89 90 /* prevent slicing beyond the end */ 91 if n := len(self.Src); q > n { 92 n = q - n 93 q = len(self.Src) 94 95 /* move the left bound if possible */ 96 if p > n { 97 i += n 98 p -= n 99 } 100 } 101 102 /* left and right length */ 103 x := clamp_zero(i) 104 y := clamp_zero(q - p - i - 1) 105 106 /* compose the error description */ 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 }