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 }
func define(s *scheme.Scope, args []scheme.Sexpr) (scheme.Sexpr, error) { if len(args) != 2 { return nil, scheme.ProcError("define requires exactly 2 arguments") } idSym, ok := args[0].(*scheme.Symbol) if !ok { return nil, scheme.ProcError("invalid argument to define") } val, err := eval.Eval(s, args[1]) if err != nil { return nil, err } s.DefineHigh(idSym, val) return scheme.Nil, nil }