예제 #1
0
func TestLambda(t *testing.T) {
	env := environment.New(nil)

	environment.Define(env, &types.Symbol{"+"}, &types.Builtin{add})
	environment.Define(env, &types.Symbol{"begin"}, &types.Builtin{begin})

	f, _ := parser.Parse(strings.NewReader("(lambda (n) n)"))
	if a, err := Eval(env, f); err != nil {
		t.Error("Evaluating lambda failed:", err, f)
	} else if !types.IsSFunction(a) {
		t.Error("Evaluating lambda didn't return an SFunction:", a)
	}

	f, _ = parser.Parse(strings.NewReader("(define add1 (lambda (n) (+ 1 n)))"))
	if _, err := Eval(env, f); err != nil {
		t.Error("Evaluating define lambda failed:", err)
	}

	if a, err := environment.Get(env, &types.Symbol{"add1"}); err != nil {
		t.Error("'Get'ting add1 caused an error: ", err)
	} else if !types.IsSFunction(a) {
		t.Error("add1 is not an SFunction:", a)
	}

	f, _ = parser.Parse(strings.NewReader("(add1 1)"))
	if a, err := Eval(env, f); err != nil {
		t.Error("Evaluating (add1 1) failed:", err)
	} else if !types.Eqv(a, &types.Number{2}) {
		t.Error("(add1 1) != 2", a)
	}
}
예제 #2
0
func TestDefine(t *testing.T) {
	env := environment.New(nil)

	f, _ := parser.Parse(strings.NewReader("(define answer 42)"))
	if _, err := Eval(env, f); err != nil {
		t.Error("Evaluating (define answer 42) failed:", err)
	}

	if a, err := environment.Get(env, &types.Symbol{"answer"}); err != nil {
		t.Error("'Get'ting 'answer' caused an error: ", err)
	} else if !types.Eqv(a, &types.Number{42}) {
		t.Error("answer != 42", a)
	}
}
예제 #3
0
func Eval(env *environment.Environment, f types.Type) (types.Type, error) {
	if types.IsPair(f) {
		car, err := types.Car(f)
		if err != nil {
			return nil, err
		}

		cdr, err := types.Cdr(f)
		if err != nil {
			return nil, err
		}

		return Apply(env, car, cdr)
	}

	if types.IsSymbol(f) {
		return environment.Get(env, f.(*types.Symbol))
	}

	return f, nil
}