root.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package transpiler
  2. import "os"
  3. import "fmt"
  4. import "strings"
  5. import "path/filepath"
  6. import "../parser"
  7. import "../parser/syntax"
  8. var RootMap = map[string]TransFunction {
  9. // module = @module name! export imports includes commands
  10. "module": func (tree Tree, ptr int) string {
  11. var children = Children(tree, ptr)
  12. var module_name = Transpile(tree, children["name"])
  13. var export_names = Transpile(tree, children["export"])
  14. var imports = Transpile(tree, children["imports"])
  15. var includes = Transpile(tree, children["includes"])
  16. var commands = Commands(tree, children["commands"], false)
  17. var content = fmt.Sprintf("%v %v %v", imports, includes, commands)
  18. var init = BareFunction(content)
  19. return fmt.Sprintf (
  20. "%v.%v(%v, %v, %v)",
  21. RUNTIME, R_REG_MODULE, module_name, export_names, init,
  22. )
  23. },
  24. // export? = @export { namelist! }! | @export namelist!
  25. "export": func (tree Tree, ptr int) string {
  26. if Empty(tree, ptr) { return "[]" }
  27. return TranspileChild("namelist")(tree, ptr)
  28. },
  29. // imports? = cmd_import imports
  30. "imports": func (tree Tree, ptr int) string {
  31. if Empty(tree, ptr) { return "" }
  32. var im_ptrs = FlatSubTree(tree, ptr, "cmd_import", "imports")
  33. var buf strings.Builder
  34. for _, im_ptr := range im_ptrs {
  35. buf.WriteString(Transpile(tree, im_ptr))
  36. buf.WriteString("; ")
  37. }
  38. return buf.String()
  39. },
  40. // name = Name
  41. "name": func (tree Tree, ptr int) string {
  42. return EscapeRawString(GetTokenContent(tree, ptr))
  43. },
  44. // namelist = name namelist_tail
  45. "namelist": func (tree Tree, ptr int) string {
  46. return TranspileSubTree(tree, ptr, "name", "namelist_tail")
  47. },
  48. // includes? = include includes
  49. "includes": func (tree Tree, ptr int) string {
  50. if Empty(tree, ptr) { return "" }
  51. var inc_ptrs = FlatSubTree(tree, ptr, "include", "includes")
  52. var buf strings.Builder
  53. for i, inc_ptr := range inc_ptrs {
  54. buf.WriteString(Transpile(tree, inc_ptr))
  55. if i != len(inc_ptrs)-1 {
  56. buf.WriteRune(' ')
  57. }
  58. }
  59. return buf.String()
  60. },
  61. // include = @include string
  62. "include": func (tree Tree, ptr int) string {
  63. var children = Children(tree, ptr)
  64. var s = string(GetTokenContent(tree, children["string"]))
  65. var raw_path = strings.Trim(s, `'"`)
  66. var path = filepath.Dir(tree.File) + "/" + raw_path
  67. var f, err = os.Open(path)
  68. if err != nil { panic(fmt.Sprintf("error: %v: %v", path, err)) }
  69. defer f.Close()
  70. return TranspileFile(f, path, "included")
  71. },
  72. // included = includes commands
  73. "included": func (tree Tree, ptr int) string {
  74. var children = Children(tree, ptr)
  75. var includes = Transpile(tree, children["includes"])
  76. var commands = Commands(tree, children["commands"], false)
  77. return fmt.Sprintf("%v %v", includes, commands)
  78. },
  79. // eval = commands
  80. "eval": func (tree Tree, ptr int) string {
  81. var cmds_ptr = tree.Nodes[ptr].Children[0]
  82. var cmd_ptrs = FlatSubTree(tree, cmds_ptr, "command", "commands")
  83. if len(cmd_ptrs) == 0 {
  84. return fmt.Sprintf("%v.%v", RUNTIME, R_VOID)
  85. }
  86. var prev_row = -1
  87. var buf strings.Builder
  88. buf.WriteRune('(')
  89. for i, command_ptr := range cmd_ptrs {
  90. var node = &tree.Nodes[command_ptr]
  91. var token = tree.Tokens[node.Pos]
  92. var row = tree.Info[token.Pos].Row
  93. if row == prev_row && !tree.Semi[node.Pos] {
  94. parser.Error(tree, command_ptr, "semicolon expected")
  95. }
  96. prev_row = row
  97. var command = TranspileFirstChild(tree, command_ptr)
  98. var group_ptr = tree.Nodes[command_ptr].Children[0]
  99. var concrete_cmd_ptr = tree.Nodes[group_ptr].Children[0]
  100. var FlowId = syntax.Name2Id["cmd_flow"]
  101. var ErrId = syntax.Name2Id["cmd_err"]
  102. var concrete = tree.Nodes[concrete_cmd_ptr].Part.Id
  103. var body string
  104. if concrete == FlowId || concrete == ErrId {
  105. body = fmt.Sprintf("%v; return %v;", command, G(T_VOID))
  106. } else {
  107. body = fmt.Sprintf("return %v", command)
  108. }
  109. var prepend = fmt.Sprintf("let %v = null; ", ERROR_DUMP)
  110. buf.WriteString(BareFunction(prepend + body))
  111. fmt.Fprintf(&buf, "(%v.%v)", RUNTIME, R_EVAL_SCOPE)
  112. if i != len(cmd_ptrs)-1 {
  113. buf.WriteString(", ")
  114. }
  115. }
  116. buf.WriteRune(')')
  117. return buf.String()
  118. },
  119. }