Example #1
0
func scm_define(args *goscm.Pair, env *goscm.Environ) (goscm.SCMT, error) {
	symb := args.Car
	switch reflect.TypeOf(symb) {
	case reflect.TypeOf(&goscm.Symbol{}):
		tobind, err := args.Cdr.(*goscm.Pair).Car.Eval(env)
		if err != nil {
			return goscm.SCM_Nil, err
		}
		env.Add(symb.(*goscm.Symbol), tobind)
		return symb, nil
	case reflect.TypeOf(&goscm.Pair{}):
		name := symb.(*goscm.Pair).Car.(*goscm.Symbol)
		proc_args := symb.(*goscm.Pair).Cdr
		proc_body := args.Cdr
		proc_tail := goscm.Cons(proc_args, proc_body)
		proc, err := scm_lambda(proc_tail, env)
		if err != nil {
			return goscm.SCM_Nil, err
		}
		env.Add(name, proc)
		return name, nil
	default:
		return goscm.SCM_Nil,
			errors.New("Attempting to define type: " + reflect.TypeOf(symb).String())
	}
}
Example #2
0
func scm_cons(args *goscm.Pair, env *goscm.Environ) (goscm.SCMT, error) {
	first := args.Car

	second_cell, ok := args.Cdr.(*goscm.Pair)
	if !ok {
		return goscm.SCM_Nil, errors.New("Weird (unexpected) dotted list")
	}

	if second_cell == goscm.SCM_Nil {
		return goscm.SCM_Nil, errors.New("Too few arguments")
	}

	second := second_cell.Car

	if second_cell.Cdr != goscm.SCM_Nil {
		return goscm.SCM_Nil, errors.New("Too many arguments")
	}

	return goscm.Cons(first, second), nil
}
Example #3
0
func read_list(b *bufio.Reader) (goscm.SCMT, error) {
	c, err := b.ReadByte()
	if c == ')' {
		return goscm.SCM_Nil, nil
	}
	if c == '.' {
		cdr, err := Read(b)
		if err != nil {
			return goscm.SCM_Nil, err
		}

		err = chomp_meaningless(b)
		if err != nil {
			return goscm.SCM_Nil, err
		}

		c, err = b.ReadByte()
		if c != ')' {
			return goscm.SCM_Nil, errors.New("Dot in list appears in wrong place")
		}
		if err != nil {
			return goscm.SCM_Nil, err
		}

		return cdr, nil
	}

	b.UnreadByte()
	elem, err := Read(b)
	if err != nil {
		return goscm.SCM_Nil, err
	}

	tail, err := read_list(b)
	if err != nil {
		return goscm.SCM_Nil, err
	}

	return goscm.Cons(elem, tail), nil
}
Example #4
0
func scm_reverse(args *goscm.Pair, env *goscm.Environ) (goscm.SCMT, error) {
	if args == goscm.SCM_Nil {
		return goscm.SCM_Nil, errors.New("Expected exactly one argument")
	}
	if args.Cdr != goscm.SCM_Nil {
		return goscm.SCM_Nil, errors.New("Expected exactly one argument")
	}
	if reflect.TypeOf(args.Car) != reflect.TypeOf(&goscm.Pair{}) {
		return goscm.SCM_Nil, errors.New("Expected list type")
	}

	list, err := args.Car.(*goscm.Pair).ToSlice()
	if err != nil {
		return goscm.SCM_Nil, err
	}

	ret := goscm.SCM_Nil
	for i := 0; i < len(list); i++ {
		ret = goscm.Cons(list[i], ret)
	}
	return ret, nil
}
Example #5
0
func scm_map(args *goscm.Pair, env *goscm.Environ) (goscm.SCMT, error) {
	argss, err := args.ToSlice()
	if err != nil {
		return goscm.SCM_Nil, err
	}

	if len(argss) < 2 {
		return goscm.SCM_Nil, errors.New("Too few arguments")
	}
	if len(argss) > 2 {
		return goscm.SCM_Nil, errors.New("Too many arguments")
	}

	proc, ok := argss[0].(goscm.Func)
	if !ok {
		return goscm.SCM_Nil, errors.New("Non-function in first position")
	}

	if reflect.TypeOf(argss[1]) != reflect.TypeOf(&goscm.Pair{}) {
		return goscm.SCM_Nil, errors.New("Expected pair")
	}

	tail, err := argss[1].(*goscm.Pair).ToSlice()
	if err != nil {
		return goscm.SCM_Nil, err
	}

	ret := goscm.SCM_Nil
	for i := len(tail) - 1; i >= 0; i-- {
		result, err := proc.Apply(goscm.NewList(tail[i]), env)
		if err != nil {
			return goscm.SCM_Nil, err
		}
		ret = goscm.Cons(result, ret)
	}

	return ret, nil
}