debug.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package parser
  2. import (
  3. "fmt"
  4. "kumachan/parser/ast"
  5. )
  6. import "strings"
  7. import "unicode/utf8"
  8. import "kumachan/parser/syntax"
  9. func GetUtf8Length(s string) int {
  10. return utf8.RuneCountInString(s)
  11. }
  12. func GetANSIColor (n int) int {
  13. return 31 + n % 6
  14. }
  15. func Repeat (n int, f func(int)) {
  16. for i := 0; i < n; i++ {
  17. f(i)
  18. }
  19. }
  20. func Fill (buf *strings.Builder, n int, s string, blank string) {
  21. buf.WriteString(s)
  22. Repeat(n-GetUtf8Length(s), func (_ int) {
  23. buf.WriteString(blank)
  24. })
  25. }
  26. func PrintTreeNode (ptr int, node *ast.TreeNode) {
  27. var buf strings.Builder
  28. fmt.Fprintf(&buf, "\033[1m\033[%vm", GetANSIColor(ptr))
  29. fmt.Fprintf(&buf, "(%v)", ptr)
  30. fmt.Fprintf(&buf, "\033[0m")
  31. buf.WriteRune(' ')
  32. fmt.Fprintf(&buf, "\033[1m")
  33. buf.WriteString(syntax.Id2Name[node.Part.Id])
  34. fmt.Fprintf(&buf, "\033[0m")
  35. buf.WriteRune(' ')
  36. buf.WriteRune('[')
  37. for i := 0; i < node.Length; i++ {
  38. var child_ptr = node.Children[i]
  39. fmt.Fprintf(&buf, "\033[1m\033[%vm", GetANSIColor(child_ptr))
  40. fmt.Fprintf(&buf, "%v", child_ptr)
  41. fmt.Fprintf(&buf, "\033[0m")
  42. if i != node.Length-1 {
  43. buf.WriteString(", ")
  44. }
  45. }
  46. buf.WriteRune(']')
  47. fmt.Fprintf(
  48. &buf, " <\033[1m\033[%vm%v\033[0m> ",
  49. GetANSIColor(node.Parent), node.Parent,
  50. )
  51. fmt.Fprintf(
  52. &buf, "status=%v, tried=%v, index=%v, pos=%+v, amount=%v\n",
  53. node.Status, node.Tried, node.Index, node.Pos, node.Amount,
  54. )
  55. fmt.Print(buf.String())
  56. }
  57. func PrintBareTree (tree []ast.TreeNode) {
  58. for i := 0; i < len(tree); i++ {
  59. PrintTreeNode(i, &tree[i])
  60. }
  61. }
  62. func PrintTreeRecursively (
  63. buf *strings.Builder,
  64. tree *ast.Tree, ptr int, depth int, is_last []bool,
  65. ) {
  66. const INC = 2
  67. const SPACE = " "
  68. var node = &tree.Nodes[ptr]
  69. Repeat(depth+1, func (i int) {
  70. if depth > 0 && i < depth {
  71. if is_last[i] {
  72. Fill(buf, INC, "", SPACE)
  73. } else {
  74. Fill(buf, INC, "│", SPACE)
  75. }
  76. } else {
  77. if is_last[depth] {
  78. Fill(buf, INC, "└", "─")
  79. } else {
  80. Fill(buf, INC, "├", "─")
  81. }
  82. }
  83. })
  84. if node.Length > 0 {
  85. buf.WriteString("┬─")
  86. } else {
  87. buf.WriteString("──")
  88. }
  89. fmt.Fprintf(buf, "\033[1m\033[%vm", GetANSIColor(depth))
  90. fmt.Fprintf(buf, "[%v]", syntax.Id2Name[node.Part.Id])
  91. fmt.Fprintf(buf, "\033[0m")
  92. fmt.Fprintf(buf, "\033[%vm", GetANSIColor(depth))
  93. buf.WriteRune(' ')
  94. switch node.Part.PartType {
  95. case syntax.MatchToken:
  96. var token = tree.Tokens[node.Pos + node.Amount - 1]
  97. fmt.Fprintf(buf, "'%v'", string(token.Content))
  98. buf.WriteRune(' ')
  99. var point = tree.Info[token.Span.Start]
  100. fmt.Fprintf(buf, "at <%v,%v>", point.Row, point.Col)
  101. fmt.Fprintf(buf, "\033[0m")
  102. buf.WriteRune('\n')
  103. case syntax.MatchKeyword:
  104. fmt.Fprintf(buf, "\033[0m")
  105. buf.WriteRune('\n')
  106. case syntax.Recursive:
  107. if node.Length == 0 {
  108. buf.WriteString("(empty)")
  109. }
  110. fmt.Fprintf(buf, "\033[0m")
  111. buf.WriteRune('\n')
  112. for i := 0; i < node.Length; i++ {
  113. var child = node.Children[i]
  114. is_last = append(is_last, i == node.Length-1)
  115. PrintTreeRecursively(buf, tree, child, depth+1, is_last)
  116. is_last = is_last[0: len(is_last)-1]
  117. }
  118. }
  119. }
  120. func PrintTree (tree *ast.Tree) {
  121. var buf strings.Builder
  122. var is_last = make([]bool, 0, 1000)
  123. is_last = append(is_last, true)
  124. PrintTreeRecursively(&buf, tree, 0, 0, is_last)
  125. fmt.Println(buf.String())
  126. }