func Env() *goscm.Environ { env := goscm.NewEnv(nil) env.Add(goscm.NewSymbol("*"), goscm.NewForeign(scm_multiply)) env.Add(goscm.NewSymbol("+"), goscm.NewForeign(scm_add)) env.Add(goscm.NewSymbol("-"), goscm.NewForeign(scm_subtract)) env.Add(goscm.NewSymbol("/"), goscm.NewForeign(scm_divide)) env.Add(goscm.NewSymbol("<"), goscm.NewForeign(scm_lt)) env.Add(goscm.NewSymbol("<="), goscm.NewForeign(scm_le)) env.Add(goscm.NewSymbol("="), goscm.NewForeign(scm_numeq)) env.Add(goscm.NewSymbol(">"), goscm.NewForeign(scm_gt)) env.Add(goscm.NewSymbol(">="), goscm.NewForeign(scm_ge)) env.Add(goscm.NewSymbol("apply"), goscm.NewForeign(scm_apply)) env.Add(goscm.NewSymbol("car"), goscm.NewForeign(scm_car)) env.Add(goscm.NewSymbol("cdr"), goscm.NewForeign(scm_cdr)) env.Add(goscm.NewSymbol("cons"), goscm.NewForeign(scm_cons)) env.Add(goscm.NewSymbol("list"), goscm.NewForeign(scm_list)) env.Add(goscm.NewSymbol("map"), goscm.NewForeign(scm_map)) env.Add(goscm.NewSymbol("not"), goscm.NewForeign(scm_not)) env.Add(goscm.NewSymbol("reverse"), goscm.NewForeign(scm_reverse)) env.Add(goscm.NewSymbol("and"), goscm.NewSpecial(scm_and)) env.Add(goscm.NewSymbol("begin"), goscm.NewSpecial(scm_begin)) env.Add(goscm.NewSymbol("define"), goscm.NewSpecial(scm_define)) env.Add(goscm.NewSymbol("lambda"), goscm.NewSpecial(scm_lambda)) env.Add(goscm.NewSymbol("let"), goscm.NewSpecial(scm_let)) env.Add(goscm.NewSymbol("or"), goscm.NewSpecial(scm_or)) env.Add(goscm.NewSymbol("quote"), goscm.NewSpecial(scm_quote)) env.Add(goscm.NewSymbol("set!"), goscm.NewSpecial(scm_set_bang)) env.Add(goscm.NewSymbol("if"), goscm.NewSpecialTCO(scm_if)) env.Add(goscm.NewSymbol("cond"), goscm.NewSpecialTCO(scm_cond)) return env }
func scm_let(args *goscm.Pair, env *goscm.Environ) (goscm.SCMT, error) { body := args.Cdr.(*goscm.Pair) newenv := goscm.NewEnv(env) for vars := args.Car.(*goscm.Pair); vars != goscm.SCM_Nil; vars = vars.Cdr.(*goscm.Pair) { symb := vars.Car.(*goscm.Pair).Car.(*goscm.Symbol) val, err := vars.Car.(*goscm.Pair).Cdr.(*goscm.Pair).Car.Eval(env) if err != nil { return goscm.SCM_Nil, err } newenv.Add(symb, val) } return scm_begin(body, newenv) }