func (gb *GolangBackend) compileAnonOrNamedLambda(nl *gol.NodeLambda, name string) (string, error) { lambdaType, err := typ.Resolve(nl.Type()) if err != nil { return "", fmt.Errorf("Can't resolve lambda var: %s [%T]\n", lambdaType, lambdaType) } funcType, ok := lambdaType.(typ.Func) if !ok { return "", fmt.Errorf("Lambda doesn't have function type: %s [%T]\n", nl.Type(), nl.Type()) } if nl.Args.Len() != len(funcType.Args) { return "", fmt.Errorf("Arg/type mismatch: %d != %d\n", nl.Args.Len(), len(funcType.Args)) } i := 0 strArgs := make([]string, len(funcType.Args)) err = nl.Args.Foreach(func(child gol.Node) error { golangType, err := golangStringForType(funcType.Args[i]) if err != nil { return err } id := child.String() strArgs[i] = fmt.Sprintf("%s %s", mangleIdentifier(id), golangType) i++ return nil }) if err != nil { return "", err } golangRetType, err := golangStringForType(funcType.Result) if err != nil { return "", err } s := fmt.Sprintf("func %s(%s) %s {", mangleIdentifier(name), strings.Join(strArgs, ", "), golangRetType) body, err := gb.compile(nl.Body) if err != nil { return "", err } s += "return " + body s += "}" return s, nil }
func (gb *GolangBackend) compileDefine(nd *gol.NodeDefine) (string, error) { valueType, err := typ.Resolve(nd.Value.Type()) if err != nil { return "", err } funcType, isFunc := valueType.(typ.Func) if isFunc { lambda, ok := nd.Value.(*gol.NodeLambda) if !ok { return "", fmt.Errorf("Non-lambda [%T] with func type [%s]", nd.Value, funcType) } s, err := gb.compileAnonOrNamedLambda(lambda, nd.Symbol.String()) if err != nil { return "", err } gb.saveTopLevelDefn(s) return "", nil } else { // Not a function definition, use a local var golangValue, err := gb.compile(nd.Value) if err != nil { return "", err } symbolGolangType, err := golangStringForType(nd.Value.Type()) if err != nil { return "", err } s := gb.declareVar(nd.Symbol.String(), symbolGolangType) s += fmt.Sprintf("%s = %s\n", nd.Symbol.String(), golangValue, ) return s, nil } }