Beispiel #1
0
func ParseLambda(tuple *ast.Tuple) *ast.Lambda {
	// (lambda <formals> <body>)
	// switch <formals>:
	//  (<variable1> ...)
	//  <variable>
	//  (<variable1> ... <variablen> . <variablen+1>)

	elements := tuple.Elements
	if len(elements) < 3 {
		panic(fmt.Sprint("lambda: bad syntax: ", tuple))
	}
	pattern := elements[1]
	body := ast.NewBlock(ParseList(elements[2:]))

	switch pattern.(type) {
	case *ast.Name:
		return ast.NewLambda(pattern, body)
	case *ast.Tuple:
		formals := ExpandFormals(pattern.(*ast.Tuple).Elements)
		_, ok := formals.(*ast.Pair)
		if ok || formals == ast.NilPair {
			return ast.NewLambda(formals, body)
		} else {
			// (. <variable>) is not allowed
			panic(fmt.Sprint("lambda: illegal use of `.'"))
		}
	default:
		panic(fmt.Sprint("unsupported parser type ", pattern))
	}
}
Beispiel #2
0
func ParseFunction(tuple *ast.Tuple, tail ast.Node) *ast.Function {
	//  expand definition: e.g.
	//  ((f x) y) <body> =>
	//  (lambda (x)
	//    (lambda (y) <body>))

	lambda := ast.NewLambda(nil, tail)
	for {
		elements := tuple.Elements
		lambda.Params = ExpandFormals(elements[1:])

		// len(elements) must be greater than 0
		switch elements[0].(type) {
		case *ast.Name:
			return ast.NewFunction(elements[0].(*ast.Name), lambda)
		case *ast.Tuple:
			tuple = elements[0].(*ast.Tuple)
			lambda = ast.NewLambda(nil, lambda)
		default:
			panic(fmt.Sprint("unsupported parser type ", elements[0]))
		}
	}
}