makers.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package generator
  2. import (
  3. "github.com/jcla1/gisp/parser"
  4. h "github.com/jcla1/gisp/generator/helpers"
  5. "go/ast"
  6. "go/token"
  7. )
  8. func makeIfStmtFunc(node *parser.CallNode) ast.Expr {
  9. var elseBody ast.Stmt
  10. if len(node.Args) > 2 {
  11. elseBody = makeBlockStmt(h.S(makeReturnStmt(h.E(EvalExpr(node.Args[2])))))
  12. } else {
  13. elseBody = makeBlockStmt(h.S(makeReturnStmt(h.E(ast.NewIdent("nil")))))
  14. }
  15. cond := EvalExpr(node.Args[0])
  16. ifBody := makeBlockStmt(h.S(makeReturnStmt(h.E(EvalExpr(node.Args[1])))))
  17. ifStmt := makeIfStmt(cond, ifBody, elseBody)
  18. fnBody := makeBlockStmt(h.S(ifStmt))
  19. returnList := makeFieldList([]*ast.Field{makeField(nil, anyType)})
  20. fnType := makeFuncType(returnList, nil)
  21. fn := makeFuncLit(fnType, fnBody)
  22. return makeFuncCall(fn, h.EmptyE())
  23. }
  24. func makeLetFun(node *parser.CallNode) ast.Expr {
  25. bindings := makeBindings(node.Args[0].(*parser.VectorNode), token.DEFINE)
  26. body := append(bindings, wrapExprsWithStmt(EvalExprs(node.Args[1:]))...)
  27. body[len(body)-1] = makeReturnStmt(h.E(body[len(body)-1].(*ast.ExprStmt).X))
  28. fieldList := makeFieldList([]*ast.Field{makeField(nil, anyType)})
  29. typ := makeFuncType(fieldList, nil)
  30. fn := makeFuncLit(typ, makeBlockStmt(body))
  31. return makeFuncCall(fn, h.EmptyE())
  32. }
  33. func makeBindings(bindings *parser.VectorNode, assignmentType token.Token) []ast.Stmt {
  34. assignments := make([]ast.Stmt, len(bindings.Nodes))
  35. for i, bind := range bindings.Nodes {
  36. b := bind.(*parser.VectorNode)
  37. idents := b.Nodes[:len(b.Nodes)-1]
  38. vars := make([]ast.Expr, len(idents))
  39. for j, ident := range idents {
  40. vars[j] = makeIdomaticSelector(ident.(*parser.IdentNode).Ident)
  41. }
  42. assignments[i] = makeAssignStmt(vars, h.E(EvalExpr(b.Nodes[len(b.Nodes)-1])), assignmentType)
  43. }
  44. return assignments
  45. }
  46. func mainable(fn *ast.FuncLit) {
  47. fn.Type.Results = nil
  48. returnStmt := fn.Body.List[len(fn.Body.List)-1].(*ast.ReturnStmt)
  49. fn.Body.List[len(fn.Body.List)-1] = makeExprStmt(returnStmt.Results[0])
  50. // return fn
  51. }
  52. // func makeTypeAssertFromArgList(expr ast.Expr, args []parser.Node) *ast.TypeAssertExpr {
  53. // argList
  54. // // currently we only support HOF that were written in Gisp
  55. // returnList := makeFieldList([]*ast.Field{makeField(nil, anyType)})
  56. // fnType := makeFuncType(returnList, argList)
  57. // return makeTypeAssertion(expr, fnType)
  58. // }
  59. //////////////////////////////////
  60. // Checked makers from here on! //
  61. //////////////////////////////////
  62. func makeValueSpec(names []*ast.Ident, values []ast.Expr, typ ast.Expr) *ast.ValueSpec {
  63. return &ast.ValueSpec{
  64. Names: names,
  65. Values: values,
  66. Type: typ,
  67. }
  68. }
  69. func makeFunDeclFromFuncLit(name *ast.Ident, f *ast.FuncLit) *ast.FuncDecl {
  70. return &ast.FuncDecl{
  71. Name: name,
  72. Type: f.Type,
  73. Body: f.Body,
  74. }
  75. }
  76. func makeGeneralDecl(typ token.Token, specs []ast.Spec) *ast.GenDecl {
  77. return &ast.GenDecl{
  78. Tok: typ,
  79. Specs: specs,
  80. }
  81. }
  82. func makeDeclStmt(decl ast.Decl) *ast.DeclStmt {
  83. return &ast.DeclStmt{
  84. Decl: decl,
  85. }
  86. }
  87. func makeTypeAssertion(expr, typ ast.Expr) *ast.TypeAssertExpr {
  88. return &ast.TypeAssertExpr{
  89. X: expr,
  90. Type: typ,
  91. }
  92. }
  93. func makeEllipsis(typ ast.Expr) *ast.Ellipsis {
  94. return &ast.Ellipsis{
  95. Elt: typ,
  96. }
  97. }