ast.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Abstract Syntax tree for the MUESLI interpreter
  2. package muesli
  3. import (
  4. "fmt"
  5. "strings"
  6. )
  7. type AstKind int
  8. const (
  9. AstKindProgram = AstKind(iota)
  10. AstKindStatements
  11. AstKindStatement
  12. AstKindSet
  13. AstKindGet
  14. AstKindTarget
  15. AstKindCommand
  16. AstKindArguments
  17. AstKindArgument
  18. AstKindExpression
  19. AstKindBlock
  20. AstKindParenthesis
  21. AstKindList
  22. AstKindCapture
  23. AstKindWordValue
  24. AstKindWord
  25. AstKindType
  26. AstKindValue
  27. AstKindEnd
  28. AstKindError
  29. )
  30. func (astkind AstKind) String() string {
  31. switch astkind {
  32. case AstKindProgram:
  33. return "AstKindProgram"
  34. case AstKindStatements:
  35. return "AstKindStatements"
  36. case AstKindStatement:
  37. return "AstKindStatement"
  38. case AstKindSet:
  39. return "AstKindSet"
  40. case AstKindGet:
  41. return "AstKindGet"
  42. case AstKindTarget:
  43. return "AstKindTarget"
  44. case AstKindCommand:
  45. return "AstKindCommand"
  46. case AstKindArguments:
  47. return "AstKindArguments"
  48. case AstKindArgument:
  49. return "AstKindArgument"
  50. case AstKindExpression:
  51. return "AstKindExpression"
  52. case AstKindBlock:
  53. return "AstKindBlock"
  54. case AstKindParenthesis:
  55. return "AstKindParenthesis"
  56. case AstKindList:
  57. return "AstKindList"
  58. case AstKindCapture:
  59. return "AstKindCapture"
  60. case AstKindWordValue:
  61. return "AstKindWordValue"
  62. case AstKindWord:
  63. return "AstKindWord"
  64. case AstKindType:
  65. return "AstKindType"
  66. case AstKindValue:
  67. return "AstKindValue"
  68. case AstKindEnd:
  69. return "AstKindEnd"
  70. case AstKindError:
  71. return "AstKindError"
  72. default:
  73. return "Unknown AstKind"
  74. }
  75. }
  76. /* AST node kind */
  77. type Ast struct {
  78. Parent *Ast
  79. Child *Ast
  80. Before *Ast
  81. After *Ast
  82. AstKind
  83. *Token
  84. }
  85. func NewAst(kind AstKind, parent *Ast, token *Token) *Ast {
  86. child := &Ast{parent, nil, nil, nil, kind, token}
  87. return child
  88. }
  89. func (ast *Ast) LastSibling() *Ast {
  90. res := ast
  91. for res != nil && res.After != nil {
  92. res = res.After
  93. }
  94. return res
  95. }
  96. func (ast *Ast) LastChild() *Ast {
  97. return ast.Child.LastSibling()
  98. }
  99. /* Detaches, I.E removes this node and all it's children from the parent tree. */
  100. func (ast *Ast) Remove() *Ast {
  101. parent := ast.Parent
  102. before := ast.Before
  103. after := ast.After
  104. if before != nil {
  105. before.After = after
  106. }
  107. if after != nil {
  108. after.Before = before
  109. }
  110. if parent != nil {
  111. /* Special case if ast is the first child of it's parent. */
  112. if ast == parent.Child {
  113. parent.Child = after
  114. }
  115. }
  116. ast.Parent = nil
  117. return ast
  118. }
  119. func (ast *Ast) InsertSibling(sibling *Ast) *Ast {
  120. after := ast.After
  121. ast.After = sibling
  122. sibling.Before = ast
  123. sibling.After = after
  124. if after != nil {
  125. after.Before = sibling
  126. }
  127. sibling.Parent = ast.Parent
  128. return sibling
  129. }
  130. func (ast *Ast) AppendSibling(sibling *Ast) *Ast {
  131. return ast.LastSibling().InsertSibling(sibling)
  132. }
  133. func (ast *Ast) AppendChild(child *Ast) *Ast {
  134. child.Parent = ast
  135. if ast.Child == nil {
  136. ast.Child = child
  137. } else {
  138. ast.Child.AppendSibling(child)
  139. }
  140. return child
  141. }
  142. func (ast *Ast) NewSibling(kind AstKind, token *Token) *Ast {
  143. sibling := NewAst(kind, ast.Parent, token)
  144. return ast.AppendSibling(sibling)
  145. }
  146. func (ast *Ast) NewChild(kind AstKind, token *Token) *Ast {
  147. sibling := NewAst(kind, ast.Parent, token)
  148. return ast.AppendChild(sibling)
  149. }
  150. func (ast *Ast) Walk(walker func(node *Ast) *Ast) *Ast {
  151. if found := walker(ast); found != nil {
  152. return found
  153. }
  154. if ast.Child != nil {
  155. if found := ast.Child.Walk(walker); found != nil {
  156. return found
  157. }
  158. }
  159. if ast.After != nil {
  160. if found := ast.After.Walk(walker); found != nil {
  161. return found
  162. }
  163. }
  164. return nil
  165. }
  166. func (ast *Ast) String() string {
  167. if ast.Token == nil {
  168. return fmt.Sprintf("Ast %s nil", ast.AstKind.String())
  169. }
  170. return fmt.Sprintf("Ast %s %v", ast.AstKind.String(), ast.Token.String())
  171. }
  172. func (ast *Ast) Display() {
  173. ast.Walk(func(node *Ast) *Ast {
  174. depth := node.Depth()
  175. fmt.Printf(strings.Repeat("--", depth))
  176. if node != nil {
  177. fmt.Printf("Ast: %s\n", node.String())
  178. } else {
  179. fmt.Printf("Ast: nil node\n")
  180. }
  181. return nil
  182. })
  183. }
  184. func (ast *Ast) Depth() int {
  185. var depth int = 0
  186. parent := ast.Parent
  187. for parent != nil {
  188. depth++
  189. parent = parent.Parent
  190. }
  191. return depth
  192. }
  193. func (ast *Ast) CountChildren() int {
  194. var count int = 0
  195. child := ast.Child
  196. for child != nil {
  197. count++
  198. child = child.After
  199. }
  200. return count
  201. }
  202. func (ast *Ast) Errors() []*Ast {
  203. res := make([]*Ast, 0)
  204. if ast == nil {
  205. return res
  206. }
  207. ast.Walk(func(node *Ast) *Ast {
  208. if node != nil && node.AstKind == AstKindError {
  209. res = append(res, node)
  210. }
  211. return nil
  212. })
  213. return res
  214. }