Example #1
0
File: compile.go Project: jbert/gol
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
}
Example #2
0
File: compile.go Project: jbert/gol
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
	}
}