Esempio n. 1
0
func ParseBegin(tuple *ast.Tuple) *ast.Begin {
	// (begin <expression1> <expression2> ...)

	elements := tuple.Elements
	exprs := ParseList(elements[1:])
	return ast.NewBegin(ast.NewBlock(exprs))
}
Esempio n. 2
0
func ParseDefine(tuple *ast.Tuple) *ast.Define {
	elements := tuple.Elements
	if len(elements) < 3 {
		panic(fmt.Sprint("define: bad syntax (missing expressions) ", tuple))
	}

	switch elements[1].(type) {
	case *ast.Name:
		// (define <variable> <expression>)
		if len(elements) > 3 {
			panic(fmt.Sprint("define: bad syntax (multiple expressions) ", tuple))
		}
		pattern := elements[1].(*ast.Name)
		value := ParseNode(elements[2])
		return ast.NewDefine(pattern, value)

	case *ast.Tuple:
		// (define (<variable> <formals>) <body>)
		// (define (<variable> . <formal>) <body>)
		tail := ast.NewBlock(ParseList(elements[2:]))
		function := ParseFunction(elements[1].(*ast.Tuple), tail)
		return ast.NewDefine(function.Caller, function)

	default:
		panic(fmt.Sprint("unsupported parser type ", elements[1]))
	}
}
Esempio n. 3
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))
	}
}
Esempio n. 4
0
func ParseLetFamily(tuple *ast.Tuple) ast.Node {
	// (let_ <bindings> <body>)
	//  <bindings> should have the form ->
	//    ((<variable1> <init1>) ...)
	//  where each <init> is an expression

	elements := tuple.Elements
	if len(elements) < 3 {
		panic(fmt.Sprintf("%s: bad syntax, no expression in body", elements[0]))
	}

	if _, ok := elements[1].(*ast.Tuple); !ok {
		panic(fmt.Sprintf("%s: bad syntax, expected bindings, given: %s", elements[0], elements[1]))
	}

	bindings := elements[1].(*ast.Tuple).Elements
	patterns := make([]*ast.Name, len(bindings))
	exprs := make([]ast.Node, len(bindings))
	for i, binding := range bindings {
		if tuple, ok := binding.(*ast.Tuple); ok {
			if len(tuple.Elements) == 2 {
				if name, ok := tuple.Elements[0].(*ast.Name); ok {
					patterns[i] = name
					exprs[i] = ParseNode(tuple.Elements[1])
					continue
				}
			}
		}
		panic(fmt.Sprintf("%s: bad syntax, not an identifer and expression for a binding %s", elements[0], binding))
	}

	body := ast.NewBlock(ParseList(elements[2:]))
	name, _ := elements[0].(*ast.Name)
	switch name.Identifier {
	case constants.LET:
		return ast.NewLet(patterns, exprs, body)
	case constants.LET_STAR:
		return ast.NewLetStar(patterns, exprs, body)
	case constants.LET_REC:
		return ast.NewLetRec(patterns, exprs, body)
	default:
		panic(fmt.Sprintf("%s: should not be here", elements[0]))
	}
}
Esempio n. 5
0
func ParseBlock(tuple *ast.Tuple) *ast.Block {
	elements := tuple.Elements
	exprs := ParseList(elements)
	return ast.NewBlock(exprs)
}