generator.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. package generator
  2. import (
  3. "../parser"
  4. "bytes"
  5. "fmt"
  6. "go/ast"
  7. "go/token"
  8. "regexp"
  9. "strings"
  10. )
  11. func GenerateAST(tree []parser.Node) *ast.File {
  12. f := &ast.File{Name: makeIdent("main")}
  13. decls := make([]ast.Decl, 0, len(tree))
  14. if len(tree) < 1 {
  15. return f
  16. }
  17. if isNSDecl(tree[0]) {
  18. name, imports := getNamespace(tree[0].(*parser.CallNode))
  19. f.Name = name
  20. if imports != nil {
  21. decls = append(decls, imports)
  22. }
  23. tree = tree[1:]
  24. }
  25. decls = append(decls, generateDecls(tree)...)
  26. f.Decls = decls
  27. return f
  28. }
  29. func generateDecls(tree []parser.Node) []ast.Decl {
  30. decls := make([]ast.Decl, len(tree))
  31. for i, node := range tree {
  32. if node.Type() != parser.NodeCall {
  33. panic("expected call node in root scope!")
  34. }
  35. decls[i] = evalDeclNode(node.(*parser.CallNode))
  36. }
  37. return decls
  38. }
  39. func evalDeclNode(node *parser.CallNode) ast.Decl {
  40. // Let's just assume that all top-level functions called will be "def"
  41. if node.Callee.Type() != parser.NodeIdent {
  42. panic("expecting call to identifier (i.e. def, defconst, etc.)")
  43. }
  44. callee := node.Callee.(*parser.IdentNode)
  45. switch callee.Ident {
  46. case "def":
  47. return evalDef(node)
  48. }
  49. return nil
  50. }
  51. func evalDef(node *parser.CallNode) ast.Decl {
  52. if len(node.Args) < 2 {
  53. panic(fmt.Sprintf("expecting expression to be assigned to variable: %q", node.Args[0]))
  54. }
  55. val := EvalExpr(node.Args[1])
  56. fn, ok := val.(*ast.FuncLit)
  57. ident := makeIdent(goify(node.Args[0].(*parser.IdentNode).Ident, true))
  58. if ok {
  59. if ident.Name != "Main" {
  60. return makeFuncDeclFromFuncLit(ident, fn)
  61. } else {
  62. ident.Name = "main"
  63. return mainable(makeFuncDeclFromFuncLit(ident, fn))
  64. }
  65. } else {
  66. return makeGeneralDecl(token.VAR, []ast.Spec{makeValueSpec(ident, val)})
  67. }
  68. }
  69. func isNSDecl(node parser.Node) bool {
  70. if node.Type() != parser.NodeCall {
  71. return false
  72. }
  73. call := node.(*parser.CallNode)
  74. if call.Callee.(*parser.IdentNode).Ident != "ns" {
  75. return false
  76. }
  77. if len(call.Args) < 1 {
  78. return false
  79. }
  80. return true
  81. }
  82. func getNamespace(node *parser.CallNode) (*ast.Ident, ast.Decl) {
  83. return getPackageName(node), getImports(node)
  84. }
  85. func getPackageName(node *parser.CallNode) *ast.Ident {
  86. if node.Args[0].Type() != parser.NodeIdent {
  87. panic("ns package name is not an identifier!")
  88. }
  89. return makeIdent(node.Args[0].(*parser.IdentNode).Ident)
  90. }
  91. func getImports(node *parser.CallNode) ast.Decl {
  92. if len(node.Args) < 2 {
  93. return nil
  94. }
  95. imports := node.Args[1:]
  96. specs := make([]ast.Spec, len(imports))
  97. for i, imp := range imports {
  98. if t := imp.Type(); t == parser.NodeVector {
  99. specs[i] = makeImportSpecFromVector(imp.(*parser.VectorNode))
  100. } else if t == parser.NodeString {
  101. path := makeBasicLit(token.STRING, imp.(*parser.StringNode).Value)
  102. specs[i] = makeImportSpec(path, nil)
  103. } else {
  104. panic("invalid import!")
  105. }
  106. }
  107. decl := makeGeneralDecl(token.IMPORT, specs)
  108. decl.Lparen = token.Pos(1) // Need this so we can have multiple imports
  109. return decl
  110. }
  111. func EvalExprs(nodes []parser.Node) []ast.Expr {
  112. out := make([]ast.Expr, len(nodes))
  113. for i, node := range nodes {
  114. out[i] = EvalExpr(node)
  115. }
  116. return out
  117. }
  118. func EvalExpr(node parser.Node) ast.Expr {
  119. switch t := node.Type(); t {
  120. case parser.NodeCall:
  121. node := node.(*parser.CallNode)
  122. return evalFunCall(node)
  123. case parser.NodeVector:
  124. node := node.(*parser.VectorNode)
  125. return makeVector(makeIdent("Any"), EvalExprs(node.Nodes))
  126. case parser.NodeNumber:
  127. node := node.(*parser.NumberNode)
  128. return makeBasicLit(node.NumberType, node.Value)
  129. case parser.NodeString:
  130. node := node.(*parser.StringNode)
  131. return makeBasicLit(token.STRING, node.Value)
  132. case parser.NodeIdent:
  133. node := node.(*parser.IdentNode)
  134. if strings.Contains(node.Ident, "/") {
  135. parts := strings.Split(node.Ident, "/")
  136. outerSelector := makeSelectorExpr(makeIdent(parts[0]), makeIdent(goify(parts[1], true)))
  137. for i := 2; i < len(parts); i++ {
  138. outerSelector = makeSelectorExpr(outerSelector, makeIdent(goify(parts[i], true)))
  139. }
  140. return outerSelector
  141. }
  142. return makeIdent(goify(node.Ident, false))
  143. default:
  144. println(t)
  145. panic("not implemented yet!")
  146. }
  147. }
  148. func evalFunCall(node *parser.CallNode) ast.Expr {
  149. switch {
  150. case checkLetArgs(node):
  151. return makeLetFun(node)
  152. case checkFunArgs(node):
  153. nodes := node.Args[0].(*parser.VectorNode).Nodes
  154. idents := make([]*parser.IdentNode, len(nodes))
  155. for i := 0; i < len(nodes); i++ {
  156. idents[i] = nodes[i].(*parser.IdentNode)
  157. }
  158. params := makeIdentSlice(idents)
  159. body := wrapExprsWithStmt(EvalExprs(node.Args[1:]))
  160. return makeFunLit(params, body)
  161. case checkDefArgs(node):
  162. panic("you can't have a def within an expression!")
  163. case checkNSArgs(node):
  164. panic("you can't define a namespace in an expression!")
  165. }
  166. callee := EvalExpr(node.Callee)
  167. if c, ok := callee.(*ast.Ident); ok {
  168. c.Name = goify(c.Name, true)
  169. }
  170. args := EvalExprs(node.Args)
  171. return makeFunCall(callee, args)
  172. }
  173. func checkNSArgs(node *parser.CallNode) bool {
  174. if node.Callee.Type() != parser.NodeIdent {
  175. return false
  176. }
  177. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "ns" {
  178. return false
  179. }
  180. return true
  181. }
  182. // Only need this to check if "def" is in
  183. // an expression, which is illegal
  184. func checkDefArgs(node *parser.CallNode) bool {
  185. if node.Callee.Type() != parser.NodeIdent {
  186. return false
  187. }
  188. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "def" {
  189. return false
  190. }
  191. return true
  192. }
  193. func checkFunArgs(node *parser.CallNode) bool {
  194. // Need an identifier for it to be "fn"
  195. if node.Callee.Type() != parser.NodeIdent {
  196. return false
  197. }
  198. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "fn" {
  199. return false
  200. }
  201. // Need argument list and at least one expression
  202. if len(node.Args) < 2 {
  203. return false
  204. }
  205. // Parameters should be a vector
  206. params := node.Args[0]
  207. if params.Type() != parser.NodeVector {
  208. return false
  209. }
  210. p := params.(*parser.VectorNode)
  211. for _, param := range p.Nodes {
  212. // TODO: change this in case of variable unpacking
  213. if param.Type() != parser.NodeIdent {
  214. return false
  215. }
  216. }
  217. return true
  218. }
  219. func checkLetArgs(node *parser.CallNode) bool {
  220. // Need an identifier for it to be "let"
  221. if node.Callee.Type() != parser.NodeIdent {
  222. return false
  223. }
  224. // Not a "let"
  225. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "let" {
  226. return false
  227. }
  228. // Need _at least_ the bindings & one expression
  229. if len(node.Args) < 2 {
  230. return false
  231. }
  232. // Bindings should be a vector
  233. bindings := node.Args[0]
  234. if bindings.Type() != parser.NodeVector {
  235. return false
  236. }
  237. // There should be an even number of elements in the bindings
  238. b := bindings.(*parser.VectorNode)
  239. if len(b.Nodes)%2 != 0 {
  240. return false
  241. }
  242. // The bound identifiers, should be identifiers
  243. for i := 0; i < len(b.Nodes); i += 2 {
  244. if b.Nodes[i].Type() != parser.NodeIdent {
  245. return false
  246. }
  247. }
  248. return true
  249. }
  250. func makeLetFun(node *parser.CallNode) ast.Expr {
  251. bindings := makeBindings(node.Args[0].(*parser.VectorNode))
  252. // TODO: clean this!
  253. return makeFunCall(makeFunLit([]*ast.Ident{}, append(bindings, wrapExprsWithStmt(EvalExprs(node.Args[1:]))...)), []ast.Expr{})
  254. }
  255. func makeBindings(bindings *parser.VectorNode) []ast.Stmt {
  256. vars := make([]*ast.Ident, len(bindings.Nodes)/2)
  257. for i := 0; i < len(bindings.Nodes); i += 2 {
  258. vars[i/2] = makeIdent(bindings.Nodes[i].(*parser.IdentNode).Ident)
  259. }
  260. vals := make([]ast.Expr, len(bindings.Nodes)/2)
  261. for i := 1; i < len(bindings.Nodes); i += 2 {
  262. vals[(i-1)/2] = EvalExpr(bindings.Nodes[i])
  263. }
  264. stmts := make([]ast.Stmt, len(vars))
  265. for i := 0; i < len(vars); i++ {
  266. stmts[i] = makeAssignStmt(vars[i], vals[i])
  267. }
  268. return stmts
  269. }
  270. func makeAssignStmt(name, val ast.Expr) *ast.AssignStmt {
  271. return &ast.AssignStmt{
  272. Lhs: []ast.Expr{name},
  273. Rhs: []ast.Expr{val},
  274. // TODO: check if following line can be omitted
  275. Tok: token.DEFINE,
  276. }
  277. }
  278. func wrapExprsWithStmt(exps []ast.Expr) []ast.Stmt {
  279. out := make([]ast.Stmt, len(exps))
  280. for i, v := range exps {
  281. out[i] = makeExprStmt(v)
  282. }
  283. return out
  284. }
  285. func makeExprStmt(exp ast.Expr) ast.Stmt {
  286. return &ast.ExprStmt{X: exp}
  287. }
  288. func makeFunCall(callee ast.Expr, args []ast.Expr) ast.Expr {
  289. return &ast.CallExpr{
  290. Fun: callee,
  291. Args: args,
  292. }
  293. }
  294. func makeFunLit(args []*ast.Ident, body []ast.Stmt) *ast.FuncLit {
  295. node := &ast.FuncLit{
  296. Type: &ast.FuncType{
  297. Results: &ast.FieldList{
  298. List: []*ast.Field{
  299. &ast.Field{
  300. Type: makeIdent("Any"),
  301. },
  302. },
  303. },
  304. },
  305. Body: makeBlockStmt(returnLast(body)),
  306. }
  307. if len(args) > 0 {
  308. node.Type.Params = makeParameterList(args)
  309. }
  310. return node
  311. }
  312. func makeParameterList(args []*ast.Ident) *ast.FieldList {
  313. return &ast.FieldList{
  314. List: []*ast.Field{
  315. &ast.Field{
  316. Type: makeIdent("Any"),
  317. Names: args,
  318. },
  319. },
  320. }
  321. }
  322. func returnLast(stmts []ast.Stmt) []ast.Stmt {
  323. if len(stmts) < 1 {
  324. return stmts
  325. }
  326. stmts[len(stmts)-1] = &ast.ReturnStmt{
  327. Results: []ast.Expr{
  328. stmts[len(stmts)-1].(*ast.ExprStmt).X,
  329. },
  330. }
  331. return stmts
  332. }
  333. func makeIdentSlice(nodes []*parser.IdentNode) []*ast.Ident {
  334. out := make([]*ast.Ident, len(nodes))
  335. for i, node := range nodes {
  336. out[i] = makeIdent(node.Ident)
  337. }
  338. return out
  339. }
  340. func makeIdent(name string) *ast.Ident {
  341. return ast.NewIdent(name)
  342. }
  343. func makeVector(typ *ast.Ident, elements []ast.Expr) *ast.CompositeLit {
  344. return makeCompositeLit(&ast.ArrayType{Elt: typ}, elements)
  345. }
  346. func makeCompositeLit(typ ast.Expr, elements []ast.Expr) *ast.CompositeLit {
  347. return &ast.CompositeLit{
  348. Type: typ,
  349. Elts: elements,
  350. }
  351. }
  352. func makeBasicLit(kind token.Token, value string) *ast.BasicLit {
  353. return &ast.BasicLit{Kind: kind, Value: value}
  354. }
  355. func makeBlockStmt(statements []ast.Stmt) *ast.BlockStmt {
  356. return &ast.BlockStmt{List: statements}
  357. }
  358. func makeGeneralDecl(typ token.Token, specs []ast.Spec) *ast.GenDecl {
  359. return &ast.GenDecl{
  360. Tok: typ,
  361. Specs: specs,
  362. }
  363. }
  364. func makeImportSpec(path *ast.BasicLit, name *ast.Ident) *ast.ImportSpec {
  365. spec := &ast.ImportSpec{Path: path}
  366. if name != nil {
  367. spec.Name = name
  368. }
  369. return spec
  370. }
  371. func makeImportSpecFromVector(vect *parser.VectorNode) *ast.ImportSpec {
  372. if len(vect.Nodes) < 3 {
  373. panic("invalid use of import!")
  374. }
  375. if vect.Nodes[0].Type() != parser.NodeString {
  376. panic("invalid use of import!")
  377. }
  378. pathString := vect.Nodes[0].(*parser.StringNode).Value
  379. path := makeBasicLit(token.STRING, pathString)
  380. if vect.Nodes[1].Type() != parser.NodeIdent || vect.Nodes[1].(*parser.IdentNode).Ident != ":as" {
  381. panic("invalid use of import! expecting: \":as\"!!!")
  382. }
  383. name := makeIdent(vect.Nodes[2].(*parser.IdentNode).Ident)
  384. return makeImportSpec(path, name)
  385. }
  386. func mainable(fn *ast.FuncDecl) *ast.FuncDecl {
  387. fn.Type.Results = nil
  388. returnStmt := fn.Body.List[len(fn.Body.List)-1].(*ast.ReturnStmt)
  389. fn.Body.List[len(fn.Body.List)-1] = makeExprStmt(returnStmt.Results[0])
  390. return fn
  391. }
  392. func makeFuncDeclFromFuncLit(name *ast.Ident, f *ast.FuncLit) *ast.FuncDecl {
  393. return &ast.FuncDecl{
  394. Name: name,
  395. Type: f.Type,
  396. Body: f.Body,
  397. }
  398. }
  399. func makeValueSpec(name *ast.Ident, value ast.Expr) *ast.ValueSpec {
  400. return &ast.ValueSpec{
  401. Names: []*ast.Ident{name},
  402. Values: []ast.Expr{value},
  403. }
  404. }
  405. func makeSelectorExpr(x ast.Expr, sel *ast.Ident) *ast.SelectorExpr {
  406. return &ast.SelectorExpr{
  407. X: x,
  408. Sel: sel,
  409. }
  410. }
  411. var camelingRegex = regexp.MustCompile("[0-9A-Za-z]+")
  412. func goify(src string, capitalizeFirst bool) string {
  413. src = strings.Replace(src, "/", ".", -1)
  414. byteSrc := []byte(src)
  415. chunks := camelingRegex.FindAll(byteSrc, -1)
  416. for idx, val := range chunks {
  417. if idx > 0 || capitalizeFirst {
  418. chunks[idx] = bytes.Title(val)
  419. }
  420. }
  421. return string(bytes.Join(chunks, nil))
  422. }