type.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package transpiler
  2. import "fmt"
  3. import "strings"
  4. var TypeMap = map[string]TransFunction {
  5. // type = fun_sig | type_expr | ( expr )!
  6. "type": func (tree Tree, ptr int) string {
  7. var children = Children(tree, ptr)
  8. var expr, is_expr = children["expr"]
  9. if is_expr {
  10. return Transpile(tree, expr)
  11. } else {
  12. return TranspileFirstChild(tree, ptr)
  13. }
  14. },
  15. // fun_sig = @$ Call < opt_type_list >! <! opt_type! >!
  16. "fun_sig": func (tree Tree, ptr int) string {
  17. var children = Children(tree, ptr)
  18. var args = Transpile(tree, children["opt_type_list"])
  19. var ret = Transpile(tree, children["opt_type"])
  20. var file = GetFileName(tree)
  21. var row, col = GetRowColInfo(tree, ptr)
  22. return fmt.Sprintf (
  23. "%v(%v, [%v, %v], %v, %v, %v)",
  24. G(CALL), G(C_FUN_SIG), args, ret, file, row, col,
  25. )
  26. },
  27. // opt_type_list? = opt_type opt_type_list_tail
  28. "opt_type_list": func (tree Tree, ptr int) string {
  29. if Empty(tree, ptr) { return "[]" }
  30. return TranspileSubTree(tree, ptr, "opt_type", "opt_type_list_tail")
  31. },
  32. // opt_type = ? | type
  33. "opt_type": func (tree Tree, ptr int) string {
  34. var children = Children(tree, ptr)
  35. var type_ptr, has_type = children["type"]
  36. if has_type {
  37. return Transpile(tree, type_ptr)
  38. } else {
  39. return G(T_PLACEHOLDER)
  40. }
  41. },
  42. // typelist = type typelist_tail
  43. "typelist": func (tree Tree, ptr int) string {
  44. return TranspileSubTree(tree, ptr, "type", "typelist_tail")
  45. },
  46. // type_expr = identifier type_gets type_args
  47. "type_expr": func (tree Tree, ptr int) string {
  48. var file = GetFileName(tree)
  49. var children = Children(tree, ptr)
  50. var id = Transpile(tree, children["identifier"])
  51. var gets_ptr = children["type_gets"]
  52. var gets = FlatSubTree(tree, gets_ptr, "type_get", "type_gets")
  53. var t = id
  54. for _, get := range gets {
  55. // type_get = . name
  56. var key = TranspileLastChild(tree, get)
  57. var row, col = GetRowColInfo(tree, get)
  58. var buf strings.Builder
  59. buf.WriteString(G(GET))
  60. buf.WriteRune('(')
  61. WriteList(&buf, []string {
  62. t, key, "false", file, row, col,
  63. })
  64. buf.WriteRune(')')
  65. t = buf.String()
  66. }
  67. var args_ptr = children["type_args"]
  68. if NotEmpty(tree, args_ptr) {
  69. var args = Transpile(tree, args_ptr)
  70. var row, col = GetRowColInfo(tree, args_ptr)
  71. var buf strings.Builder
  72. buf.WriteString(G(CALL))
  73. buf.WriteRune('(')
  74. WriteList(&buf, []string {
  75. t, args, file, row, col,
  76. })
  77. buf.WriteRune(')')
  78. return buf.String()
  79. } else {
  80. return t
  81. }
  82. },
  83. // type_args? = Call < type_arglist! >!
  84. "type_args": TranspileChild("type_arglist"),
  85. // type_arglist = type_arg type_arglist_tail
  86. "type_arglist": func (tree Tree, ptr int) string {
  87. return TranspileSubTree(tree, ptr, "type_arg", "type_arglist_tail")
  88. },
  89. // type_arg = type | primitive
  90. "type_arg": TranspileFirstChild,
  91. // type_literal = simple_type_literal | finite_literal
  92. "type_literal": TranspileFirstChild,
  93. // simple_type_literal = { name _bar1 filters! }!
  94. "simple_type_literal": func (tree Tree, ptr int) string {
  95. var children = Children(tree, ptr)
  96. var name = GetTokenContent(tree, children["name"])
  97. var p_name = Transpile(tree, children["name"])
  98. var parameters = fmt.Sprintf (
  99. "[{ name: %v, type: %v }]",
  100. p_name, G(T_ANY),
  101. )
  102. var proto = fmt.Sprintf (
  103. "{ parameters: %v, value_type: %v }",
  104. parameters, G(T_BOOL),
  105. )
  106. var desc = Desc (
  107. []rune("lambda.type_checker"),
  108. []rune(fmt.Sprintf("(%v: Any)", string(name))),
  109. []rune("Bool"),
  110. )
  111. var checker_expr = Transpile(tree, children["filters"])
  112. var raw = BareFunction(fmt.Sprintf("return %v;", checker_expr))
  113. var checker = fmt.Sprintf (
  114. "%v(%v, %v, %v, %v)",
  115. L_WRAP, proto, "null", desc, raw,
  116. )
  117. return fmt.Sprintf("%v(%v)", G(C_TYPE), checker)
  118. },
  119. // filters = exprlist
  120. "filters": func (tree Tree, ptr int) string {
  121. var children = Children(tree, ptr)
  122. return Filters(tree, children["exprlist"])
  123. },
  124. // finite_literal = @one @of { exprlist }! | { exprlist }
  125. "finite_literal": func (tree Tree, ptr int) string {
  126. var children = Children(tree, ptr)
  127. var file = GetFileName(tree)
  128. var row, col = GetRowColInfo(tree, ptr)
  129. return fmt.Sprintf (
  130. "%v(%v, %v, %v, %v, %v)",
  131. G(CALL), G(C_FINITE),
  132. TranspileSubTree (
  133. tree, children["exprlist"], "expr", "exprlist_tail",
  134. ),
  135. file, row, col,
  136. )
  137. },
  138. // enum = @enum name {! namelist! }!
  139. "enum": func (tree Tree, ptr int) string {
  140. var file = GetFileName(tree)
  141. var row, col = GetRowColInfo(tree, ptr)
  142. var children = Children(tree, ptr)
  143. var e_name = Transpile(tree, children["name"])
  144. var l_ptr = children["namelist"]
  145. var name_ptrs = FlatSubTree(tree, l_ptr, "name", "namelist_tail")
  146. var names = make([]string, 0, 16)
  147. for _, name_ptr := range name_ptrs {
  148. names = append(names, Transpile(tree, name_ptr))
  149. }
  150. var names_str = strings.Join(names, ", ")
  151. var enum = fmt.Sprintf("%v(%v, [%v])", G(C_ENUM), e_name, names_str)
  152. return fmt.Sprintf (
  153. "%v(%v, [%v, %v, true, %v], %v, %v, %v)",
  154. G(CALL), L_VAR_DECL, e_name, enum, G(T_TYPE), file, row, col,
  155. )
  156. },
  157. // schema = @struct name generic_params { field_list }! schema_config
  158. "schema": func (tree Tree, ptr int) string {
  159. var file = GetFileName(tree)
  160. var row, col = GetRowColInfo(tree, ptr)
  161. var children = Children(tree, ptr)
  162. var name_ptr = children["name"]
  163. var gp_ptr = children["generic_params"]
  164. var name = Transpile(tree, name_ptr)
  165. var config = Transpile(tree, children["schema_config"])
  166. var table, defaults, contains = FieldList(tree, children["field_list"])
  167. var schema = fmt.Sprintf (
  168. "%v(%v, [%v, %v, %v, %v, %v], %v, %v, %v)",
  169. G(CALL), G(C_SCHEMA), name, table, defaults, contains, config,
  170. file, row, col,
  171. )
  172. var value string
  173. if NotEmpty(tree, gp_ptr) {
  174. value = TypeTemplate(tree, gp_ptr, name_ptr, schema)
  175. } else {
  176. value = schema
  177. }
  178. return fmt.Sprintf (
  179. "%v(%v, [%v, %v, true, %v], %v, %v, %v)",
  180. G(CALL), L_VAR_DECL, name, value, G(T_TYPE), file, row, col,
  181. )
  182. },
  183. // schema_config? = @config { struct_guard operator_defs }!
  184. "schema_config": func (tree Tree, ptr int) string {
  185. // rule name depended by FunctionMap["operator_defs"]
  186. if Empty(tree, ptr) { return "{ guard: null, ops: {} }" }
  187. var children = Children(tree, ptr)
  188. return fmt.Sprintf (
  189. "{ guard: %v, ops: %v }",
  190. Transpile(tree, children["struct_guard"]),
  191. Transpile(tree, children["operator_defs"]),
  192. )
  193. },
  194. // struct_guard? = @guard body!
  195. "struct_guard": func (tree Tree, ptr int) string {
  196. if Empty(tree, ptr) { return "null" }
  197. var children = Children(tree, ptr)
  198. var body_ptr = children["body"]
  199. var parameters = fmt.Sprintf (
  200. "[{ name: 'fields', type: %v }]",
  201. G(T_HASH),
  202. )
  203. var desc = Desc (
  204. []rune("struct_guard"),
  205. []rune("(fields: Hash)"),
  206. []rune("Void"),
  207. )
  208. return Function(tree, body_ptr, F_Sync, desc, parameters, G(T_VOID))
  209. },
  210. }