funcs.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  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 evalFuncCall(node *parser.CallNode) ast.Expr {
  9. switch {
  10. case isUnaryOperator(node):
  11. return makeUnaryExpr(unaryOperatorMap[node.Callee.(*parser.IdentNode).Ident], EvalExpr(node.Args[0]))
  12. case isCallableOperator(node):
  13. return makeNAryCallableExpr(node)
  14. case isLogicOperator(node):
  15. return makeNAryLogicExpr(node)
  16. case isLoop(node):
  17. return makeLoop(node)
  18. case isRecur(node):
  19. return makeRecur(node)
  20. case isAssert(node):
  21. return makeAssert(node)
  22. case isCoreFunc(node):
  23. return makeCoreCall(node)
  24. case checkLetArgs(node):
  25. return makeLetFun(node)
  26. case checkIfArgs(node):
  27. return makeIfStmtFunc(node)
  28. case checkFuncArgs(node):
  29. // TODO: In case of type annotations change the following
  30. returnField := []*ast.Field{makeField(nil, anyType)}
  31. results := makeFieldList(returnField)
  32. argIdents, ellipsis := getArgIdentsFromVector(node.Args[0].(*parser.VectorNode))
  33. params := make([]*ast.Field, 0, len(argIdents))
  34. if len(argIdents) != 0 {
  35. params = append(params, makeField(argIdents, anyType))
  36. }
  37. if ellipsis != nil {
  38. params = append(params, makeField(h.I(ellipsis), makeEllipsis(anyType)))
  39. }
  40. fnType := makeFuncType(results, makeFieldList(params))
  41. body := makeFuncBody(EvalExprs(node.Args[1:]))
  42. return makeFuncLit(fnType, body)
  43. case checkDefArgs(node):
  44. panic("you can't have a def within an expression!")
  45. case checkNSArgs(node):
  46. panic("you can't define a namespace in an expression!")
  47. }
  48. callee := EvalExpr(node.Callee)
  49. if c, ok := callee.(*ast.Ident); ok {
  50. callee = makeIdomaticIdent(c.Name)
  51. }
  52. args := EvalExprs(node.Args)
  53. return makeFuncCall(callee, args)
  54. }
  55. func getArgIdentsFromVector(vect *parser.VectorNode) ([]*ast.Ident, *ast.Ident) {
  56. args := vect.Nodes
  57. argIdents := make([]*ast.Ident, 0, len(vect.Nodes))
  58. var ident string
  59. var ellipsis *ast.Ident
  60. for i := 0; i < len(args); i++ {
  61. ident = args[i].(*parser.IdentNode).Ident
  62. if ident == "&" {
  63. ellipsis = makeIdomaticIdent(args[i+1].(*parser.IdentNode).Ident)
  64. break
  65. }
  66. argIdents = append(argIdents, makeIdomaticIdent(ident))
  67. }
  68. return argIdents, ellipsis
  69. }
  70. func makeFuncBody(exprs []ast.Expr) *ast.BlockStmt {
  71. wrapped := wrapExprsWithStmt(exprs)
  72. wrapped[len(wrapped)-1] = makeReturnStmt(h.E(wrapped[len(wrapped)-1].(*ast.ExprStmt).X))
  73. return makeBlockStmt(wrapped)
  74. }
  75. func makeFuncLit(typ *ast.FuncType, body *ast.BlockStmt) *ast.FuncLit {
  76. return &ast.FuncLit{
  77. Type: typ,
  78. Body: body,
  79. }
  80. }
  81. func makeFuncType(results, params *ast.FieldList) *ast.FuncType {
  82. return &ast.FuncType{
  83. Results: results,
  84. Params: params,
  85. }
  86. }
  87. func makeFieldList(list []*ast.Field) *ast.FieldList {
  88. return &ast.FieldList{
  89. List: list,
  90. }
  91. }
  92. func makeField(names []*ast.Ident, typ ast.Expr) *ast.Field {
  93. return &ast.Field{
  94. Names: names,
  95. Type: typ,
  96. }
  97. }
  98. func makeReturnStmt(exprs []ast.Expr) ast.Stmt {
  99. return &ast.ReturnStmt{
  100. Results: exprs,
  101. }
  102. }
  103. func makeFuncCall(callee ast.Expr, args []ast.Expr) *ast.CallExpr {
  104. return &ast.CallExpr{
  105. Fun: callee,
  106. Args: args,
  107. }
  108. }
  109. // Fn type checks (let, fn, def, ns, etc.)
  110. func checkIfArgs(node *parser.CallNode) bool {
  111. if node.Callee.Type() != parser.NodeIdent {
  112. return false
  113. }
  114. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "if" {
  115. return false
  116. }
  117. if len(node.Args) < 2 {
  118. return false
  119. }
  120. return true
  121. }
  122. // Only need this to check if "def" is in
  123. // an expression, which is illegal
  124. func checkDefArgs(node *parser.CallNode) bool {
  125. if node.Callee.Type() != parser.NodeIdent {
  126. return false
  127. }
  128. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "def" {
  129. return false
  130. }
  131. return true
  132. }
  133. func checkFuncArgs(node *parser.CallNode) bool {
  134. // Need an identifier for it to be "fn"
  135. if node.Callee.Type() != parser.NodeIdent {
  136. return false
  137. }
  138. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "fn" {
  139. return false
  140. }
  141. // Need argument list and at least one expression
  142. if len(node.Args) < 2 {
  143. return false
  144. }
  145. // Parameters should be a vector
  146. params := node.Args[0]
  147. if params.Type() != parser.NodeVector {
  148. return false
  149. }
  150. p := params.(*parser.VectorNode)
  151. for _, param := range p.Nodes {
  152. // TODO: change this in case of variable unpacking
  153. if param.Type() != parser.NodeIdent {
  154. return false
  155. }
  156. }
  157. return true
  158. }
  159. func checkLetArgs(node *parser.CallNode) bool {
  160. // Need an identifier for it to be "let"
  161. if node.Callee.Type() != parser.NodeIdent {
  162. return false
  163. }
  164. // Not a "let"
  165. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "let" {
  166. return false
  167. }
  168. // Need _at least_ the bindings & one expression
  169. if len(node.Args) < 2 {
  170. return false
  171. }
  172. // Bindings should be a vector
  173. bindings := node.Args[0]
  174. if bindings.Type() != parser.NodeVector {
  175. return false
  176. }
  177. // The bindings should be also vectors
  178. b := bindings.(*parser.VectorNode)
  179. for _, bind := range b.Nodes {
  180. if _, ok := bind.(*parser.VectorNode); !ok {
  181. return false
  182. }
  183. }
  184. // The bound identifiers, should be identifiers
  185. for _, bind := range b.Nodes {
  186. bindingVect := bind.(*parser.VectorNode)
  187. if bindingVect.Nodes[0].Type() != parser.NodeIdent {
  188. return false
  189. }
  190. }
  191. return true
  192. }
  193. func isLoop(node *parser.CallNode) bool {
  194. // Need an identifier for it to be "loop"
  195. if node.Callee.Type() != parser.NodeIdent {
  196. return false
  197. }
  198. // Not a "loop"
  199. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "loop" {
  200. return false
  201. }
  202. // Bindings should be a vector
  203. bindings := node.Args[0]
  204. if bindings.Type() != parser.NodeVector {
  205. return false
  206. }
  207. // The bindings should be also vectors
  208. b := bindings.(*parser.VectorNode)
  209. for _, bind := range b.Nodes {
  210. if _, ok := bind.(*parser.VectorNode); !ok {
  211. return false
  212. }
  213. }
  214. // The bound identifiers, should be identifiers
  215. for _, bind := range b.Nodes {
  216. bindingVect := bind.(*parser.VectorNode)
  217. if bindingVect.Nodes[0].Type() != parser.NodeIdent {
  218. return false
  219. }
  220. }
  221. if !searchForRecur(node.Args[1:]) {
  222. panic("no recur found in loop!")
  223. }
  224. return true
  225. }
  226. func isRecur(node *parser.CallNode) bool {
  227. // Need an identifier for it to be "loop"
  228. if node.Callee.Type() != parser.NodeIdent {
  229. return false
  230. }
  231. // Not a "loop"
  232. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "recur" {
  233. return false
  234. }
  235. // Bindings should be a vector
  236. bindings := node.Args[0]
  237. if bindings.Type() != parser.NodeVector {
  238. return false
  239. }
  240. // The bindings should be also vectors
  241. b := bindings.(*parser.VectorNode)
  242. for _, bind := range b.Nodes {
  243. if _, ok := bind.(*parser.VectorNode); !ok {
  244. return false
  245. }
  246. }
  247. // The bound identifiers, should be identifiers
  248. for _, bind := range b.Nodes {
  249. bindingVect := bind.(*parser.VectorNode)
  250. if bindingVect.Nodes[0].Type() != parser.NodeIdent {
  251. return false
  252. }
  253. }
  254. return true
  255. }
  256. func searchForRecur(nodes []parser.Node) bool {
  257. for _, node := range nodes {
  258. if node.Type() == parser.NodeCall {
  259. n := node.(*parser.CallNode)
  260. if ident, ok := n.Callee.(*parser.IdentNode); ok && ident.Ident == "recur" {
  261. return true
  262. } else if searchForRecur(n.Args) {
  263. return true
  264. }
  265. }
  266. }
  267. return false
  268. }
  269. func addNewValuesToBindings(bindingsVector *parser.VectorNode, vals []parser.Node) *parser.VectorNode {
  270. for i, _ := range bindingsVector.Nodes {
  271. bind := bindingsVector.Nodes[i].(*parser.VectorNode).Nodes
  272. bind[len(bind)-1] = vals[i]
  273. }
  274. return bindingsVector
  275. }
  276. func addRecurLabelAndBindings(label *parser.IdentNode, bindingsVector *parser.VectorNode, nodes []parser.Node) {
  277. for _, node := range nodes {
  278. if node.Type() == parser.NodeCall {
  279. n := node.(*parser.CallNode)
  280. if ident, ok := n.Callee.(*parser.IdentNode); ok && ident.Ident == "recur" {
  281. newValues := make([]parser.Node, len(n.Args))
  282. copy(newValues, n.Args)
  283. n.Args = make([]parser.Node, 2)
  284. n.Args[0] = addNewValuesToBindings(bindingsVector.Copy().(*parser.VectorNode), newValues)
  285. n.Args[1] = label
  286. } else {
  287. addRecurLabelAndBindings(label, bindingsVector, n.Args)
  288. }
  289. }
  290. }
  291. }
  292. func makeLoop(node *parser.CallNode) *ast.CallExpr {
  293. returnIdent := generateIdent()
  294. loopIdent := generateIdent()
  295. fnBody := h.EmptyS()
  296. bindingsVector := node.Args[0].(*parser.VectorNode)
  297. addRecurLabelAndBindings(parser.NewIdentNode(loopIdent.String()), bindingsVector.Copy().(*parser.VectorNode), node.Args[1:])
  298. bindings := makeBindings(bindingsVector, token.DEFINE)
  299. returnIdentValueSpec := makeValueSpec(h.I(returnIdent), nil, anyType)
  300. returnIdentDecl := makeDeclStmt(makeGeneralDecl(token.VAR, []ast.Spec{returnIdentValueSpec}))
  301. fnBody = append(fnBody, bindings...)
  302. fnBody = append(fnBody, returnIdentDecl)
  303. init := makeAssignStmt(h.E(loopIdent), h.E(ast.NewIdent("true")), token.DEFINE)
  304. forBody := h.EmptyS()
  305. forBody = append(forBody, makeAssignStmt(h.E(loopIdent), h.E(ast.NewIdent("false")), token.ASSIGN))
  306. forBody = append(forBody, wrapExprsWithStmt(EvalExprs(node.Args[1:len(node.Args)-1]))...)
  307. forBody = append(forBody, makeAssignStmt(h.E(returnIdent), h.E(EvalExpr(node.Args[len(node.Args)-1])), token.ASSIGN))
  308. forStmt := makeForStmt(init, nil, loopIdent, makeBlockStmt(forBody))
  309. fnBody = append(fnBody, forStmt)
  310. fnBody = append(fnBody, makeReturnStmt(h.E(returnIdent)))
  311. results := makeFieldList([]*ast.Field{makeField(nil, anyType)})
  312. fnType := makeFuncType(results, nil)
  313. fn := makeFuncLit(fnType, makeBlockStmt(fnBody))
  314. return makeFuncCall(fn, h.EmptyE())
  315. }
  316. func makeRecur(node *parser.CallNode) *ast.CallExpr {
  317. bindings := makeBindings(node.Args[0].(*parser.VectorNode), token.ASSIGN)
  318. loopUpdate := makeAssignStmt(h.E(EvalExpr(node.Args[1])), h.E(ast.NewIdent("true")), token.ASSIGN)
  319. body := append(h.EmptyS(), bindings...)
  320. body = append(body, loopUpdate, makeReturnStmt(h.E(ast.NewIdent("nil"))))
  321. resultType := makeFieldList([]*ast.Field{makeField(nil, anyType)})
  322. fnType := makeFuncType(resultType, nil)
  323. fn := makeFuncLit(fnType, makeBlockStmt(body))
  324. return makeFuncCall(fn, h.EmptyE())
  325. }
  326. func isAssert(node *parser.CallNode) bool {
  327. // Need an identifier for it to be "assert"
  328. if node.Callee.Type() != parser.NodeIdent {
  329. return false
  330. }
  331. // Not a "loop"
  332. if callee := node.Callee.(*parser.IdentNode); callee.Ident != "assert" {
  333. return false
  334. }
  335. if len(node.Args) != 2 {
  336. panic("assert needs 2 arguments")
  337. }
  338. if _, ok := node.Args[0].(*parser.IdentNode); !ok {
  339. panic("assert's first argument needs to be a type")
  340. }
  341. return true
  342. }
  343. func makeAssert(node *parser.CallNode) *ast.TypeAssertExpr {
  344. return makeTypeAssertion(EvalExpr(node.Args[1]), ast.NewIdent(node.Args[0].(*parser.IdentNode).Ident))
  345. }
  346. var coreFuncs = []string{"get"}
  347. func isCoreFunc(node *parser.CallNode) bool {
  348. // Need an identifier for it to be a func
  349. if node.Callee.Type() != parser.NodeIdent {
  350. return false
  351. }
  352. ident := node.Callee.(*parser.IdentNode).Ident
  353. for _, v := range coreFuncs {
  354. if v == ident {
  355. return true
  356. }
  357. }
  358. return false
  359. }
  360. // TODO: just a quick and dirty implementation
  361. func makeCoreCall(node *parser.CallNode) ast.Expr {
  362. ident := node.Callee.(*parser.IdentNode).Ident
  363. node.Callee.(*parser.IdentNode).Ident = "core/" + ident
  364. return evalFuncCall(node)
  365. }