示例#1
0
文件: funcs.go 项目: sunclx/gsp
func makeLoop(node *parser.CallNode) *ast.CallExpr {
	returnIdent := generateIdent()
	loopIdent := generateIdent()

	fnBody := h.EmptyS()

	bindingsVector := node.Args[0].(*parser.VectorNode)

	addRecurLabelAndBindings(parser.NewIdentNode(loopIdent.String()), bindingsVector.Copy().(*parser.VectorNode), node.Args[1:])

	bindings := makeBindings(bindingsVector, token.DEFINE)
	returnIdentValueSpec := makeValueSpec(h.I(returnIdent), nil, anyType)
	returnIdentDecl := makeDeclStmt(makeGeneralDecl(token.VAR, []ast.Spec{returnIdentValueSpec}))

	fnBody = append(fnBody, bindings...)
	fnBody = append(fnBody, returnIdentDecl)

	init := makeAssignStmt(h.E(loopIdent), h.E(ast.NewIdent("true")), token.DEFINE)
	forBody := h.EmptyS()

	forBody = append(forBody, makeAssignStmt(h.E(loopIdent), h.E(ast.NewIdent("false")), token.ASSIGN))
	forBody = append(forBody, wrapExprsWithStmt(EvalExprs(node.Args[1:len(node.Args)-1]))...)
	forBody = append(forBody, makeAssignStmt(h.E(returnIdent), h.E(EvalExpr(node.Args[len(node.Args)-1])), token.ASSIGN))

	forStmt := makeForStmt(init, nil, loopIdent, makeBlockStmt(forBody))

	fnBody = append(fnBody, forStmt)
	fnBody = append(fnBody, makeReturnStmt(h.E(returnIdent)))

	results := makeFieldList([]*ast.Field{makeField(nil, anyType)})
	fnType := makeFuncType(results, nil)
	fn := makeFuncLit(fnType, makeBlockStmt(fnBody))

	return makeFuncCall(fn, h.EmptyE())
}
示例#2
0
文件: funcs.go 项目: sunclx/gsp
func makeRecur(node *parser.CallNode) *ast.CallExpr {
	bindings := makeBindings(node.Args[0].(*parser.VectorNode), token.ASSIGN)
	loopUpdate := makeAssignStmt(h.E(EvalExpr(node.Args[1])), h.E(ast.NewIdent("true")), token.ASSIGN)

	body := append(h.EmptyS(), bindings...)
	body = append(body, loopUpdate, makeReturnStmt(h.E(ast.NewIdent("nil"))))

	resultType := makeFieldList([]*ast.Field{makeField(nil, anyType)})
	fnType := makeFuncType(resultType, nil)
	fn := makeFuncLit(fnType, makeBlockStmt(body))
	return makeFuncCall(fn, h.EmptyE())
}