node.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package parser
  10. import (
  11. "bytes"
  12. "fmt"
  13. "devt.de/krotik/common/stringutil"
  14. )
  15. /*
  16. ASTNode models a node in the AST
  17. */
  18. type ASTNode struct {
  19. Name string // Name of the node
  20. Token *LexToken // Lexer token of this ASTNode
  21. Children []*ASTNode // Child nodes
  22. Runtime Runtime // Runtime component for this ASTNode
  23. binding int // Binding power of this node
  24. nullDenotation func(p *parser, self *ASTNode) (*ASTNode, error) // Configure token as beginning node
  25. leftDenotation func(p *parser, self *ASTNode, left *ASTNode) (*ASTNode, error) // Configure token as left node
  26. }
  27. /*
  28. ASTFromPlain creates an AST from a plain AST.
  29. A plain AST is a nested map structure like this:
  30. {
  31. name : <name of node>
  32. value : <value of node>
  33. children : [ <child nodes> ]
  34. }
  35. */
  36. func ASTFromPlain(plainAST map[string]interface{}) (*ASTNode, error) {
  37. var astChildren []*ASTNode
  38. nameValue, ok := plainAST["name"]
  39. if !ok {
  40. return nil, fmt.Errorf("Found plain ast node without a name: %v", plainAST)
  41. }
  42. name := fmt.Sprint(nameValue)
  43. valueValue, ok := plainAST["value"]
  44. if stringutil.IndexOf(name, ValueNodes) != -1 && !ok {
  45. return nil, fmt.Errorf("Found plain ast value node without a value: %v", name)
  46. }
  47. value := fmt.Sprint(valueValue)
  48. // Create children
  49. if children, ok := plainAST["children"]; ok {
  50. if ic, ok := children.([]interface{}); ok {
  51. // Do a list conversion if necessary - this is necessary when we parse
  52. // JSON with map[string]interface{} this
  53. childrenList := make([]map[string]interface{}, len(ic))
  54. for i := range ic {
  55. childrenList[i] = ic[i].(map[string]interface{})
  56. }
  57. children = childrenList
  58. }
  59. for _, child := range children.([]map[string]interface{}) {
  60. astChild, err := ASTFromPlain(child)
  61. if err != nil {
  62. return nil, err
  63. }
  64. astChildren = append(astChildren, astChild)
  65. }
  66. }
  67. return &ASTNode{fmt.Sprint(name), &LexToken{TokenGeneral, 0,
  68. fmt.Sprint(value), 0, 0}, astChildren, nil, 0, nil, nil}, nil
  69. }
  70. /*
  71. newAstNode creates an instance of this ASTNode which is connected to a concrete lexer token.
  72. */
  73. func newAstNode(name string, p *parser, t *LexToken) *ASTNode {
  74. ret := &ASTNode{name, t, make([]*ASTNode, 0, 2), nil, 0, nil, nil}
  75. if p.rp != nil {
  76. ret.Runtime = p.rp.Runtime(ret)
  77. }
  78. return ret
  79. }
  80. /*
  81. changeAstNode changes the name of a given ASTNode.
  82. */
  83. func changeAstNode(node *ASTNode, newname string, p *parser) *ASTNode {
  84. node.Name = newname
  85. node.Runtime = nil
  86. if p.rp != nil {
  87. node.Runtime = p.rp.Runtime(node)
  88. }
  89. return node
  90. }
  91. /*
  92. instane creates a new instance of this ASTNode which is connected to a concrete lexer token.
  93. */
  94. func (n *ASTNode) instance(p *parser, t *LexToken) *ASTNode {
  95. ret := &ASTNode{n.Name, t, make([]*ASTNode, 0, 2), nil, n.binding, n.nullDenotation, n.leftDenotation}
  96. if p.rp != nil {
  97. ret.Runtime = p.rp.Runtime(ret)
  98. }
  99. return ret
  100. }
  101. /*
  102. Plain returns this ASTNode and all its children as plain AST. A plain AST
  103. only contains map objects, lists and primitive types which can be serialized
  104. with JSON.
  105. */
  106. func (n *ASTNode) Plain() map[string]interface{} {
  107. ret := make(map[string]interface{})
  108. ret["name"] = n.Name
  109. lenChildren := len(n.Children)
  110. if lenChildren > 0 {
  111. children := make([]map[string]interface{}, lenChildren)
  112. for i, child := range n.Children {
  113. children[i] = child.Plain()
  114. }
  115. ret["children"] = children
  116. }
  117. if stringutil.IndexOf(n.Name, ValueNodes) != -1 {
  118. ret["value"] = n.Token.Val
  119. }
  120. return ret
  121. }
  122. /*
  123. String returns a string representation of this token.
  124. */
  125. func (n *ASTNode) String() string {
  126. var buf bytes.Buffer
  127. n.levelString(0, &buf)
  128. return buf.String()
  129. }
  130. /*
  131. levelString function to recursively print the tree.
  132. */
  133. func (n *ASTNode) levelString(indent int, buf *bytes.Buffer) {
  134. // Print current level
  135. buf.WriteString(stringutil.GenerateRollingString(" ", indent*2))
  136. if stringutil.IndexOf(n.Name, ValueNodes) != -1 {
  137. buf.WriteString(fmt.Sprintf(n.Name+": %v", n.Token.Val))
  138. } else {
  139. buf.WriteString(n.Name)
  140. }
  141. buf.WriteString("\n")
  142. // Print children
  143. for _, child := range n.Children {
  144. child.levelString(indent+1, buf)
  145. }
  146. }