transpiler.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package transpiler
  2. import "fmt"
  3. import "strconv"
  4. import "io"
  5. import "io/ioutil"
  6. import "../parser/syntax"
  7. import "../parser"
  8. type Tree = *parser.Tree
  9. type TransFunction = func(Tree, int) string
  10. var Rules = []map[string]TransFunction {
  11. RootMap, CommandMap, FunctionMap,
  12. TypeMap, OO_Map, ExpressionMap, LiteralMap,
  13. }
  14. var TransMapByName = make(map[string]TransFunction)
  15. var TransMap = make(map[syntax.Id]TransFunction)
  16. func Transpile (tree Tree, ptr int) string {
  17. // hash returned by Children() is of type map[string]int,
  18. // which will return 0 if non-existing key requested.
  19. // so we use -1 to indicate root node instead
  20. if ptr == 0 {
  21. panic("invalid usage of Transpile(): please use ptr=-1 for root node")
  22. }
  23. if ptr == -1 {
  24. ptr = 0
  25. }
  26. var id = tree.Nodes[ptr].Part.Id
  27. // fmt.Printf("transpile: %v\n", syntax.Id2Name[id])
  28. var f, exists = TransMap[id]
  29. if exists {
  30. return f(tree, ptr)
  31. } else {
  32. panic (
  33. fmt.Sprintf (
  34. "transpilation rule for %v does not exist",
  35. syntax.Id2Name[id],
  36. ),
  37. )
  38. }
  39. }
  40. func TranspileFirstChild (tree Tree, ptr int) string {
  41. var node = &tree.Nodes[ptr]
  42. if node.Length > 0 {
  43. return Transpile(tree, node.Children[0])
  44. } else {
  45. parser.PrintTreeNode(ptr, node)
  46. panic("unable to transpile first child: this node has no child")
  47. }
  48. }
  49. func TranspileLastChild (tree Tree, ptr int) string {
  50. var node = &tree.Nodes[ptr]
  51. if node.Length > 0 {
  52. return Transpile(tree, node.Children[node.Length-1])
  53. } else {
  54. parser.PrintTreeNode(ptr, node)
  55. panic("unable to transpile last child: this node has no child")
  56. }
  57. }
  58. func TranspileChild (child_name string) TransFunction {
  59. return func (tree Tree, ptr int) string {
  60. var id = syntax.Name2Id[child_name]
  61. var node = &tree.Nodes[ptr]
  62. for i := 0; i < node.Length; i++ {
  63. var child_ptr = node.Children[i]
  64. if tree.Nodes[child_ptr].Part.Id == id {
  65. return Transpile(tree, child_ptr)
  66. }
  67. }
  68. parser.PrintTreeNode(ptr, node)
  69. panic("unable to find " + child_name + " in this node")
  70. }
  71. }
  72. func Children (tree Tree, ptr int) map[string]int {
  73. var node = &tree.Nodes[ptr]
  74. var hash = make(map[string]int)
  75. for i := node.Length-1; i >= 0; i-- {
  76. // reversed loop: smaller index override bigger index
  77. var child_ptr = node.Children[i]
  78. var name = syntax.Id2Name[tree.Nodes[child_ptr].Part.Id]
  79. hash[name] = child_ptr
  80. }
  81. return hash
  82. }
  83. func GetFileName (tree Tree) string {
  84. return EscapeRawString([]rune(tree.File))
  85. }
  86. func GetRowColInfo (tree Tree, ptr int) (string, string) {
  87. var point = tree.Info[tree.Tokens[tree.Nodes[ptr].Pos].Pos]
  88. return strconv.Itoa(point.Row), strconv.Itoa(point.Col)
  89. }
  90. func TranspileFile (file io.Reader, name string, root string) string {
  91. var content, err = ioutil.ReadAll(file)
  92. if err != nil { panic(fmt.Sprintf("error reading %v: %v", name, err)) }
  93. var code = []rune(string(content))
  94. var tree = parser.BuildTree(root, code, name)
  95. return Transpile(&tree, -1)
  96. }
  97. func ApplyRules () {
  98. for _, item := range Rules {
  99. for key, value := range item {
  100. var _, exists = TransMapByName[key]
  101. if exists { panic("duplicate transpilation rule for " + key) }
  102. TransMapByName[key] = value
  103. }
  104. }
  105. }
  106. func Init () {
  107. ApplyRules()
  108. for name, value := range TransMapByName {
  109. TransMap[syntax.Name2Id[name]] = value
  110. }
  111. }