error.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package parser
  2. import "os"
  3. import "fmt"
  4. import "strings"
  5. const SiblingOffset = 2
  6. const Bold = "\033[1m"
  7. const Red = "\033[31m"
  8. const Blue = "\033[34m"
  9. const Reset = "\033[0m"
  10. func InternalError (msg string) {
  11. panic(fmt.Sprintf("Internal Parser Error: %v", msg))
  12. }
  13. func Error (tree *Tree, ptr int, msg string) {
  14. var node = &tree.Nodes[ptr]
  15. var p int
  16. if node.Pos >= len(tree.Tokens) {
  17. p = len(tree.Tokens)-1
  18. } else {
  19. p = node.Pos
  20. }
  21. var token = &tree.Tokens[p]
  22. var point = tree.Info[token.Pos]
  23. var file = tree.File
  24. var l, r = GetSiblingRange(tree, p)
  25. /*
  26. fmt.Fprintf(os.Stderr, "[Debug] (%v, %v)\n", l, r)
  27. for i := range tree.Code {
  28. fmt.Fprintf(os.Stderr, "[Debug] %v: %v\n", i, string([]rune{tree.Code[i]}))
  29. }
  30. */
  31. var spot = string(tree.Code[l:r])
  32. var lines = strings.Split(spot, "\n")
  33. fmt.Fprintf (
  34. os.Stderr, "%vFile:%v %v%v%v\n",
  35. Bold, Reset, Blue, file, Reset,
  36. )
  37. var cp = l
  38. for i, line := range lines {
  39. var row = point.Row - SiblingOffset + i
  40. if row < 1 {
  41. row = 1
  42. }
  43. fmt.Fprintf(os.Stderr, "%v | ", row)
  44. for _, char := range []rune(line) {
  45. if cp == token.Pos {
  46. fmt.Fprintf(os.Stderr, "%v%v", Red, Bold)
  47. }
  48. fmt.Fprintf(os.Stderr, "%v", string([]rune{char}))
  49. if cp == token.Pos {
  50. fmt.Fprintf(os.Stderr, "%v", Reset)
  51. }
  52. cp += 1
  53. }
  54. fmt.Fprintf(os.Stderr, "\n")
  55. cp += 1
  56. }
  57. fmt.Fprintf (
  58. os.Stderr, "%v%v at (row %v, column %v) in %v%v\n",
  59. Red, msg, point.Row, point.Col, file, Reset,
  60. )
  61. os.Exit(1)
  62. }
  63. func GetSiblingRange (tree *Tree, token_ptr int) (int, int) {
  64. var token = &tree.Tokens[token_ptr]
  65. var point = tree.Info[token.Pos]
  66. var left_bound = point.Row - SiblingOffset
  67. var right_bound = point.Row + SiblingOffset
  68. var p = token.Pos
  69. var l = token_ptr
  70. var L = p
  71. for {
  72. if l-1 >= 0 {
  73. var left_token = &tree.Tokens[l-1]
  74. var left_point = tree.Info[left_token.Pos]
  75. if left_point.Row >= left_bound {
  76. l -= 1
  77. L = left_token.Pos
  78. } else {
  79. break
  80. }
  81. } else {
  82. break
  83. }
  84. }
  85. var r = token_ptr
  86. var R = p + len(token.Content)
  87. for {
  88. if r+1 < len(tree.Tokens) {
  89. var right_token = &tree.Tokens[r+1]
  90. var right_point = tree.Info[right_token.Pos]
  91. if right_point.Row <= right_bound {
  92. r += 1
  93. R = right_token.Pos + len(right_token.Content)
  94. } else {
  95. break
  96. }
  97. } else {
  98. break
  99. }
  100. }
  101. return L, R
  102. }