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