func scm_cond(args *goscm.Pair, env *goscm.Environ) (goscm.SCMT, error) { for args != goscm.SCM_Nil { condition, ok := args.Car.(*goscm.Pair) if !ok { return goscm.SCM_Nil, errors.New("Expected list") } pred, err := condition.Car.Eval(env) if err != nil { return goscm.SCM_Nil, err } if goscm.SCMTrue(pred) { consequent_cell, ok := condition.Cdr.(*goscm.Pair) if !ok { return goscm.SCM_Nil, errors.New("Cond entry list too short") } if consequent_cell.Cdr != goscm.SCM_Nil { return goscm.SCM_Nil, errors.New("Trailing list elements in cond entry") } return consequent_cell.Car, nil } args, ok = args.Cdr.(*goscm.Pair) if !ok { return goscm.SCM_Nil, errors.New("Condition entries are a dotted list?") } } return goscm.SCM_Nil, nil }
func scm_or(args *goscm.Pair, env *goscm.Environ) (goscm.SCMT, error) { if args == goscm.SCM_Nil { return goscm.NewSCMT(false), nil } result, err := args.Car.Eval(env) if err != nil { return goscm.SCM_Nil, err } if goscm.SCMTrue(result) { return goscm.NewSCMT(true), nil } if reflect.TypeOf(args.Cdr) != reflect.TypeOf(&goscm.Pair{}) { return goscm.SCM_Nil, errors.New("Expected nil-terminated list") } return scm_or(args.Cdr.(*goscm.Pair), env) }