diff --git a/lib/eval.c b/lib/eval.c index 7507175..a4c7936 100644 --- a/lib/eval.c +++ b/lib/eval.c @@ -4,9 +4,8 @@ #include -void eval(am_t *am) +static void eval_atom(am_t *am) { - assert(am->expr->is_atom); switch (am->expr->atom.type) { case ATOM_TYPE_EMPTY_LIST: case ATOM_TYPE_INTEGER: @@ -18,3 +17,26 @@ void eval(am_t *am) break; } } + +static void eval_list(am_t *am) +{ + am->argl = am->expr->pair.cdr; + am->expr = am->expr->pair.car; + + assert(am->expr->is_atom); + assert(am->expr->atom.type == ATOM_TYPE_SYMBOL); + env_fetch(am); + + assert(am->val->is_atom); + assert(am->val->atom.type == ATOM_TYPE_PRIM_PROC); + assert(am->val->atom.prim_proc != NULL); + am->val->atom.prim_proc(am); +} + +void eval(am_t *am) +{ + if (am->expr->is_atom) + eval_atom(am); + else + eval_list(am); +} diff --git a/tests/eval_tests.c b/tests/eval_tests.c index bc23c63..0a3934b 100644 --- a/tests/eval_tests.c +++ b/tests/eval_tests.c @@ -69,6 +69,25 @@ static void test_foo_evals_to_42_when_set_in_env(void) TEST_ASSERT_EQUAL(42, am.val->atom.integer); } +static void test_add_1_2_3_evals_to_6(void) +{ + am.expr = expr_pair( + &am, expr_str_symbol(&am, "+"), + expr_pair( + &am, expr_integer(&am, 1), + expr_pair( + &am, expr_integer(&am, 2), + expr_pair( + &am, expr_integer(&am, 3), expr_empty_list(&am))))); + + eval(&am); + + TEST_ASSERT_NOT_NULL(am.val); + TEST_ASSERT_TRUE(am.val->is_atom); + TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); + TEST_ASSERT_EQUAL(6, am.val->atom.integer); +} + int main(void) { UNITY_BEGIN(); @@ -76,5 +95,6 @@ int main(void) RUN_TEST(test_empty_list_self_evals); RUN_TEST(test_prim_proc_self_evals); RUN_TEST(test_foo_evals_to_42_when_set_in_env); + RUN_TEST(test_add_1_2_3_evals_to_6); return UNITY_END(); }