error.go 3.1 KB

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