コード例 #1
0
ファイル: eval.go プロジェクト: rickbutton/goscheme
func Eval(sc *scheme.Scope, e scheme.Sexpr) (scheme.Sexpr, error) {
	//e = transform(sc, e)
	switch e := e.(type) {
	case *scheme.Cons:
		cons := e
		car, err := Eval(sc, cons.Car)
		if err != nil {
			return nil, err
		}
		if !isFunction(car) && !isPrim(car) {
			return nil, evalError("Attempted application on non-function")
		}
		cdr := cons.Cdr
		args, err := scheme.Flatten(cdr)
		if err != nil {
			return nil, err
		}
		if isPrim(car) {
			return car.(*scheme.Primitive).Procedure()(sc, args)
		}
		f := car.(*scheme.Function).Procedure()
		for i, a := range args {
			args[i], err = Eval(sc, a)
			if err != nil {
				return nil, err
			}
		}
		return f(sc, args)
	case *scheme.Symbol:
		return sc.Lookup(e)
	}
	return e, nil
}
コード例 #2
0
ファイル: prims.go プロジェクト: rickbutton/goscheme
func let(s *scheme.Scope, ss []scheme.Sexpr) (scheme.Sexpr, error) {
	if len(ss) < 1 {
		return nil, scheme.ProcError("let requires at least one argument")
	}
	evalScope := scheme.NewScope(s)
	bindings, err := scheme.Flatten(ss[0])
	if err != nil {
		return nil, err
	}
	for _, b := range bindings {
		bs, err := scheme.Flatten(b)
		if err != nil {
			return nil, err
		}
		if len(bs) != 2 {
			return nil, scheme.ProcError("invalid binding on let")
		}
		sym, ok := bs[0].(*scheme.Symbol)
		if !ok {
			return nil, scheme.ProcError("invalid binding on let")
		}
		val, err := eval.Eval(s, bs[1])
		if err != nil {
			return nil, err
		}
		evalScope.Define(sym, val)
	}
	prog := ss[1:]
	var last scheme.Sexpr = scheme.Nil
	for _, l := range prog {
		last, err = eval.Eval(evalScope, l)
		if err != nil {
			return nil, err
		}
	}
	return last, nil
}