Пример #1
0
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
}
Пример #2
0
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)
}