error.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package error
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strconv"
  6. "strings"
  7. "kumachan/parser/ast"
  8. "kumachan/parser/scanner"
  9. "kumachan/transformer/node"
  10. )
  11. const ERR_FOV = 5
  12. type E interface {
  13. Message() ErrorMessage
  14. }
  15. type MaybeErrorPoint interface { MaybeErrorPoint() }
  16. func (impl ErrorPoint) MaybeErrorPoint() {}
  17. type ErrorPoint struct {
  18. AST *ast.Tree
  19. Node node.Node
  20. }
  21. func GetErrorTypeName(e interface{}) string {
  22. var T = reflect.TypeOf(e)
  23. return T.String()
  24. }
  25. func MsgFailedToCompile(cause interface{}, err []ErrorMessage) ErrorMessage {
  26. var err_type = GetErrorTypeName(cause)
  27. var msg = make(ErrorMessage, 0)
  28. msg.WriteText(TS_ERROR, fmt.Sprintf (
  29. "*** Failed to Compile (%s)", err_type,
  30. ))
  31. msg.WriteText(TS_NORMAL, "\n*\n")
  32. msg.WriteAll(JoinErrMsg(err, T(TS_NORMAL, "\n*\n")))
  33. return msg
  34. }
  35. func FormatError (
  36. code scanner.Code,
  37. info scanner.RowColInfo,
  38. span_map scanner.RowSpanMap,
  39. file_name string,
  40. coordinate scanner.Point,
  41. spot scanner.Span,
  42. fov uint,
  43. highlight TextStyle,
  44. description ErrorMessage,
  45. ) ErrorMessage {
  46. var nh_rows = make([]scanner.Span, 0)
  47. var i = coordinate.Row
  48. var j = coordinate.Row
  49. for i > 1 && uint(coordinate.Row - i) < (fov/2) {
  50. i -= 1
  51. }
  52. var last_row int
  53. if len(code) > 0 {
  54. last_row = info[len(code)-1].Row
  55. } else {
  56. last_row = 1
  57. }
  58. for j < last_row && uint(j - coordinate.Row) < (fov/2) {
  59. j += 1
  60. }
  61. var start_row = i
  62. var end_row = j
  63. for r := start_row; r <= end_row; r += 1 {
  64. nh_rows = append(nh_rows, span_map[r])
  65. }
  66. var expected_width = len(strconv.Itoa(last_row))
  67. var align = func(num int) string {
  68. var num_str = strconv.Itoa(num)
  69. var num_width = len(num_str)
  70. var buf strings.Builder
  71. buf.WriteString(num_str)
  72. for i := num_width; i < expected_width; i += 1 {
  73. buf.WriteRune(' ')
  74. }
  75. return buf.String()
  76. }
  77. var msg = make(ErrorMessage, 0)
  78. msg.WriteText(TS_INFO, "-----")
  79. msg.WriteInnerText(TS_INFO, fmt.Sprintf (
  80. "(row %d, column %d)",
  81. coordinate.Row, coordinate.Col,
  82. ))
  83. msg.WriteText(TS_INFO, file_name)
  84. msg.Write(T_LF)
  85. var style = TS_NORMAL
  86. for i, row := range nh_rows {
  87. var current_row = (start_row + i)
  88. msg.WriteText(TS_NORMAL, fmt.Sprintf (
  89. " %s |", align(current_row),
  90. ))
  91. msg.Write(T_SPACE)
  92. var buf strings.Builder
  93. for j, char := range code[row.Start: row.End] {
  94. var pos = (row.Start + j)
  95. if pos == spot.Start {
  96. msg.WriteBuffer(style, &buf)
  97. style = highlight
  98. }
  99. if pos == spot.End {
  100. msg.WriteBuffer(style, &buf)
  101. style = TS_NORMAL
  102. }
  103. buf.WriteRune(char)
  104. }
  105. if row.End == spot.Start {
  106. msg.WriteBuffer(style, &buf)
  107. style = highlight
  108. }
  109. if row.End == spot.End {
  110. msg.WriteBuffer(style, &buf)
  111. style = TS_NORMAL
  112. }
  113. msg.WriteBuffer(style, &buf)
  114. msg.Write(T_LF)
  115. }
  116. msg.WriteAll(description)
  117. return msg
  118. }
  119. func FormatErrorAt (
  120. point ErrorPoint,
  121. desc ErrorMessage,
  122. ) ErrorMessage {
  123. var AST = point.AST
  124. var Node = point.Node
  125. return FormatError (
  126. AST.Code, AST.Info, AST.SpanMap,
  127. AST.Name, Node.Point, Node.Span,
  128. ERR_FOV, TS_SPOT, desc,
  129. )
  130. }