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  }