error.go 2.5 KB

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