debug.go 3.7 KB

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