Make AM registers into an array

This commit is contained in:
2025-08-10 20:30:07 +01:00
parent 52a42d2937
commit 57c39fd00b
14 changed files with 311 additions and 288 deletions

View File

@@ -17,22 +17,22 @@ void am_init(am_t *am)
void am_push(am_t *am) void am_push(am_t *am)
{ {
assert(am->sp >= am->stack); assert(am->sp >= am->stack);
*am->sp-- = am->expr; *am->sp-- = AM_EXPR(am);
} }
void am_pop(am_t *am) void am_pop(am_t *am)
{ {
assert(am->sp < am->stack + AM_STACK_SIZE - 1); assert(am->sp < am->stack + AM_STACK_SIZE - 1);
am->expr = *++am->sp; AM_EXPR(am) = *++am->sp;
} }
void am_append_arg(am_t *am) void am_append_arg(am_t *am)
{ {
expr_t *list = am->argl; expr_t *list = AM_ARGL(am);
while (!list->is_atom) while (!list->is_atom)
list = list->pair.cdr; list = list->pair.cdr;
list->is_atom = false; list->is_atom = false;
list->pair.car = am->val; list->pair.car = AM_VAL(am);
list->pair.cdr = expr_empty_list(am); list->pair.cdr = expr_empty_list(am);
} }

View File

@@ -12,18 +12,18 @@ static bool symbol_eq(symbol_t *s, symbol_t *t)
static expr_t **lookup(am_t *am, bool *found) static expr_t **lookup(am_t *am, bool *found)
{ {
assert(am->expr != NULL); assert(AM_EXPR(am) != NULL);
assert(am->expr->is_atom); assert(AM_EXPR(am)->is_atom);
assert(am->expr->atom.type == ATOM_TYPE_SYMBOL); assert(AM_EXPR(am)->atom.type == ATOM_TYPE_SYMBOL);
if (am->env->is_atom) { if (AM_ENV(am)->is_atom) {
assert(am->env->atom.type == ATOM_TYPE_EMPTY_LIST); assert(AM_ENV(am)->atom.type == ATOM_TYPE_EMPTY_LIST);
*found = false; *found = false;
return &am->env; return &AM_ENV(am);
} }
expr_t *prev; expr_t *prev;
for (expr_t *list = am->env; !list->is_atom; list = list->pair.cdr) { for (expr_t *list = AM_ENV(am); !list->is_atom; list = list->pair.cdr) {
assert(list != NULL); assert(list != NULL);
expr_t *entry = list->pair.car; expr_t *entry = list->pair.car;
@@ -34,7 +34,7 @@ static expr_t **lookup(am_t *am, bool *found)
assert(key->is_atom); assert(key->is_atom);
assert(key->atom.type == ATOM_TYPE_SYMBOL); assert(key->atom.type == ATOM_TYPE_SYMBOL);
if (symbol_eq(&am->expr->atom.symbol, &key->atom.symbol)) { if (symbol_eq(&AM_EXPR(am)->atom.symbol, &key->atom.symbol)) {
*found = true; *found = true;
return &entry->pair.cdr; return &entry->pair.cdr;
} }
@@ -51,7 +51,7 @@ static expr_t **lookup(am_t *am, bool *found)
void env_init(am_t *am) void env_init(am_t *am)
{ {
am->env = expr_empty_list(am); AM_ENV(am) = expr_empty_list(am);
prim_load(am); prim_load(am);
} }
@@ -59,7 +59,7 @@ void env_fetch(am_t *am)
{ {
bool found; bool found;
expr_t *val = *lookup(am, &found); expr_t *val = *lookup(am, &found);
am->val = found ? val : NULL; AM_VAL(am) = found ? val : NULL;
} }
void env_set(am_t *am) void env_set(am_t *am)
@@ -67,10 +67,10 @@ void env_set(am_t *am)
bool found; bool found;
expr_t **loc = lookup(am, &found); expr_t **loc = lookup(am, &found);
if (found) { if (found) {
*loc = am->val; *loc = AM_VAL(am);
} else { } else {
(*loc)->is_atom = false; (*loc)->is_atom = false;
(*loc)->pair.cdr = expr_empty_list(am); (*loc)->pair.cdr = expr_empty_list(am);
(*loc)->pair.car = expr_pair(am, am->expr, am->val); (*loc)->pair.car = expr_pair(am, AM_EXPR(am), AM_VAL(am));
} }
} }

View File

@@ -6,11 +6,11 @@
static void eval_atom(am_t *am) static void eval_atom(am_t *am)
{ {
switch (am->expr->atom.type) { switch (AM_EXPR(am)->atom.type) {
case ATOM_TYPE_EMPTY_LIST: case ATOM_TYPE_EMPTY_LIST:
case ATOM_TYPE_INTEGER: case ATOM_TYPE_INTEGER:
case ATOM_TYPE_PRIM_PROC: case ATOM_TYPE_PRIM_PROC:
am->val = am->expr; AM_VAL(am) = AM_EXPR(am);
break; break;
case ATOM_TYPE_SYMBOL: case ATOM_TYPE_SYMBOL:
env_fetch(am); env_fetch(am);
@@ -20,42 +20,42 @@ static void eval_atom(am_t *am)
static void eval_list(am_t *am) static void eval_list(am_t *am)
{ {
am->argl = expr_empty_list(am); AM_ARGL(am) = expr_empty_list(am);
am->unev = am->expr->pair.cdr; AM_UNEV(am) = AM_EXPR(am)->pair.cdr;
am->expr = am->expr->pair.car; AM_EXPR(am) = AM_EXPR(am)->pair.car;
while (!am->unev->is_atom) { while (!AM_UNEV(am)->is_atom) {
am_push(am); am_push(am);
am->expr = am->unev->pair.cdr; AM_EXPR(am) = AM_UNEV(am)->pair.cdr;
am_push(am); am_push(am);
am->expr = am->argl; AM_EXPR(am) = AM_ARGL(am);
am_push(am); am_push(am);
am->expr = am->unev->pair.car; AM_EXPR(am) = AM_UNEV(am)->pair.car;
eval(am); eval(am);
am_pop(am); am_pop(am);
am->argl = am->expr; AM_ARGL(am) = AM_EXPR(am);
am_append_arg(am); am_append_arg(am);
am_pop(am); am_pop(am);
am->unev = am->expr; AM_UNEV(am) = AM_EXPR(am);
am_pop(am); am_pop(am);
} }
assert(am->expr->is_atom); assert(AM_EXPR(am)->is_atom);
assert(am->expr->atom.type == ATOM_TYPE_SYMBOL); assert(AM_EXPR(am)->atom.type == ATOM_TYPE_SYMBOL);
env_fetch(am); env_fetch(am);
assert(am->val->is_atom); assert(AM_VAL(am)->is_atom);
assert(am->val->atom.type == ATOM_TYPE_PRIM_PROC); assert(AM_VAL(am)->atom.type == ATOM_TYPE_PRIM_PROC);
assert(am->val->atom.prim_proc != NULL); assert(AM_VAL(am)->atom.prim_proc != NULL);
am->val->atom.prim_proc(am); AM_VAL(am)->atom.prim_proc(am);
} }
void eval(am_t *am) void eval(am_t *am)
{ {
if (am->expr->is_atom) if (AM_EXPR(am)->is_atom)
eval_atom(am); eval_atom(am);
else else
eval_list(am); eval_list(am);

View File

@@ -6,8 +6,24 @@
#define AM_STACK_SIZE 128U #define AM_STACK_SIZE 128U
#define AM_ARGL(am) am->regs[ARGL]
#define AM_ENV(am) am->regs[ENV]
#define AM_EXPR(am) am->regs[EXPR]
#define AM_UNEV(am) am->regs[UNEV]
#define AM_VAL(am) am->regs[VAL]
typedef enum {
ARGL,
ENV,
EXPR,
UNEV,
VAL,
AM_REG_COUNT,
} am_reg_t;
typedef struct am { typedef struct am {
expr_t *argl, *env, *expr, *unev, *val; expr_t *regs[AM_REG_COUNT];
expr_t **sp, *stack[AM_STACK_SIZE]; expr_t **sp, *stack[AM_STACK_SIZE];
store_t store; store_t store;
} am_t; } am_t;

View File

@@ -24,7 +24,7 @@ static parse_state_t pop_state(parse_ctx_t *ctx)
static void append(parse_ctx_t *ctx, expr_t *expr) static void append(parse_ctx_t *ctx, expr_t *expr)
{ {
expr_t *list = ctx->am->expr; expr_t *list = AM_EXPR(ctx->am);
while (!list->is_atom) while (!list->is_atom)
list = list->pair.cdr; list = list->pair.cdr;
assert(list->atom.type == ATOM_TYPE_EMPTY_LIST); assert(list->atom.type == ATOM_TYPE_EMPTY_LIST);
@@ -40,16 +40,16 @@ parse_state_t parse_proc(parse_ctx_t *ctx, const token_t *token)
case PARSE_STATE_INIT: case PARSE_STATE_INIT:
switch (token->type) { switch (token->type) {
case TOKEN_TYPE_INTEGER: case TOKEN_TYPE_INTEGER:
ctx->am->expr = expr_integer(ctx->am, token->integer); AM_EXPR(ctx->am) = expr_integer(ctx->am, token->integer);
ctx->state = PARSE_STATE_DONE; ctx->state = PARSE_STATE_DONE;
break; break;
case TOKEN_TYPE_SYMBOL: case TOKEN_TYPE_SYMBOL:
ctx->am->expr = expr_symbol(ctx->am, &token->symbol); AM_EXPR(ctx->am) = expr_symbol(ctx->am, &token->symbol);
ctx->state = PARSE_STATE_DONE; ctx->state = PARSE_STATE_DONE;
break; break;
case TOKEN_TYPE_OPEN_PAREN: case TOKEN_TYPE_OPEN_PAREN:
push_state(ctx, PARSE_STATE_DONE); push_state(ctx, PARSE_STATE_DONE);
ctx->am->expr = expr_empty_list(ctx->am); AM_EXPR(ctx->am) = expr_empty_list(ctx->am);
ctx->state = PARSE_STATE_LIST; ctx->state = PARSE_STATE_LIST;
break; break;
case TOKEN_TYPE_CLOSE_PAREN: case TOKEN_TYPE_CLOSE_PAREN:
@@ -69,13 +69,13 @@ parse_state_t parse_proc(parse_ctx_t *ctx, const token_t *token)
case TOKEN_TYPE_OPEN_PAREN: case TOKEN_TYPE_OPEN_PAREN:
am_push(ctx->am); am_push(ctx->am);
push_state(ctx, PARSE_STATE_LIST); push_state(ctx, PARSE_STATE_LIST);
ctx->am->expr = expr_empty_list(ctx->am); AM_EXPR(ctx->am) = expr_empty_list(ctx->am);
ctx->state = PARSE_STATE_LIST; ctx->state = PARSE_STATE_LIST;
break; break;
case TOKEN_TYPE_CLOSE_PAREN: case TOKEN_TYPE_CLOSE_PAREN:
ctx->state = pop_state(ctx); ctx->state = pop_state(ctx);
if (ctx->state == PARSE_STATE_LIST) { if (ctx->state == PARSE_STATE_LIST) {
expr_t *expr = ctx->am->expr; expr_t *expr = AM_EXPR(ctx->am);
am_pop(ctx->am); am_pop(ctx->am);
append(ctx, expr); append(ctx, expr);
} }

View File

@@ -13,49 +13,49 @@ typedef struct {
static void add(am_t *am) static void add(am_t *am)
{ {
assert(am->argl); assert(AM_ARGL(am));
int64_t total = 0; int64_t total = 0;
for (expr_t *list = am->argl; !list->is_atom; list = list->pair.cdr) { for (expr_t *list = AM_ARGL(am); !list->is_atom; list = list->pair.cdr) {
assert(list->pair.car->is_atom); assert(list->pair.car->is_atom);
assert(list->pair.car->atom.type == ATOM_TYPE_INTEGER); assert(list->pair.car->atom.type == ATOM_TYPE_INTEGER);
total += list->pair.car->atom.integer; total += list->pair.car->atom.integer;
} }
am->val = expr_integer(am, total); AM_VAL(am) = expr_integer(am, total);
} }
static void mul(am_t *am) static void mul(am_t *am)
{ {
assert(am->argl); assert(AM_ARGL(am));
int64_t total = 1; int64_t total = 1;
for (expr_t *list = am->argl; !list->is_atom; list = list->pair.cdr) { for (expr_t *list = AM_ARGL(am); !list->is_atom; list = list->pair.cdr) {
assert(list->pair.car->is_atom); assert(list->pair.car->is_atom);
assert(list->pair.car->atom.type == ATOM_TYPE_INTEGER); assert(list->pair.car->atom.type == ATOM_TYPE_INTEGER);
total *= list->pair.car->atom.integer; total *= list->pair.car->atom.integer;
} }
am->val = expr_integer(am, total); AM_VAL(am) = expr_integer(am, total);
} }
static void sub(am_t *am) static void sub(am_t *am)
{ {
assert(am->argl); assert(AM_ARGL(am));
assert(!am->argl->is_atom); assert(!AM_ARGL(am)->is_atom);
assert(am->argl->pair.car->is_atom); assert(AM_ARGL(am)->pair.car->is_atom);
assert(am->argl->pair.car->atom.type == ATOM_TYPE_INTEGER); assert(AM_ARGL(am)->pair.car->atom.type == ATOM_TYPE_INTEGER);
int64_t total = am->argl->pair.car->atom.integer; int64_t total = AM_ARGL(am)->pair.car->atom.integer;
if (!am->argl->is_atom && am->argl->pair.cdr->is_atom) { if (!AM_ARGL(am)->is_atom && AM_ARGL(am)->pair.cdr->is_atom) {
total *= -1; total *= -1;
} else { } else {
for (expr_t *list = am->argl->pair.cdr; !list->is_atom; for (expr_t *list = AM_ARGL(am)->pair.cdr; !list->is_atom;
list = list->pair.cdr) { list = list->pair.cdr) {
assert(list->pair.car->is_atom); assert(list->pair.car->is_atom);
assert(list->pair.car->atom.type == ATOM_TYPE_INTEGER); assert(list->pair.car->atom.type == ATOM_TYPE_INTEGER);
total -= list->pair.car->atom.integer; total -= list->pair.car->atom.integer;
} }
} }
am->val = expr_integer(am, total); AM_VAL(am) = expr_integer(am, total);
} }
static const prim_table_entry_t prim_table[] = { static const prim_table_entry_t prim_table[] = {
@@ -67,8 +67,8 @@ static const prim_table_entry_t prim_table[] = {
void prim_load(am_t *am) void prim_load(am_t *am)
{ {
for (unsigned i = 0; i < NELEMS(prim_table); ++i) { for (unsigned i = 0; i < NELEMS(prim_table); ++i) {
am->expr = expr_str_symbol(am, prim_table[i].name); AM_EXPR(am) = expr_str_symbol(am, prim_table[i].name);
am->val = expr_prim_proc(am, prim_table[i].prim_proc); AM_VAL(am) = expr_prim_proc(am, prim_table[i].prim_proc);
env_set(am); env_set(am);
} }
} }

View File

@@ -4,12 +4,12 @@
size_t print(am_t *am, char *buffer, size_t buffer_size) size_t print(am_t *am, char *buffer, size_t buffer_size)
{ {
assert(am->val->is_atom); assert(AM_VAL(am)->is_atom);
assert(am->val->atom.type == ATOM_TYPE_INTEGER); assert(AM_VAL(am)->atom.type == ATOM_TYPE_INTEGER);
size_t i = 0; size_t i = 0;
int64_t value = am->val->atom.integer; int64_t value = AM_VAL(am)->atom.integer;
if (value < 0) { if (value < 0) {
buffer[i++] = '-'; buffer[i++] = '-';
value *= -1; value *= -1;

View File

@@ -18,28 +18,30 @@ void tearDown(void)
static void test_expr_value_restored_after_push_modify_pop(void) static void test_expr_value_restored_after_push_modify_pop(void)
{ {
expr_t a, b; expr_t a, b;
am.expr = &a;
am.regs[EXPR] = &a;
am_push(&am); am_push(&am);
am.expr = &b; am.regs[EXPR] = &b;
am_pop(&am); am_pop(&am);
TEST_ASSERT_EQUAL(&a, am.expr);
TEST_ASSERT_EQUAL(&a, am.regs[EXPR]);
} }
static void test_append_arg_42_with_empty_argl(void) static void test_append_arg_42_with_empty_argl(void)
{ {
am.argl = expr_empty_list(&am); am.regs[ARGL] = expr_empty_list(&am);
am.val = expr_integer(&am, 42); am.regs[VAL] = expr_integer(&am, 42);
am_append_arg(&am); am_append_arg(&am);
TEST_ASSERT_FALSE(am.argl->is_atom); TEST_ASSERT_FALSE(am.regs[ARGL]->is_atom);
TEST_ASSERT_NOT_NULL(CAR(am.argl)); TEST_ASSERT_NOT_NULL(CAR(am.regs[ARGL]));
TEST_ASSERT_TRUE(CAR(am.argl)->is_atom); TEST_ASSERT_TRUE(CAR(am.regs[ARGL])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CAR(am.argl)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CAR(am.regs[ARGL])->atom.type);
TEST_ASSERT_EQUAL(42, CAR(am.argl)->atom.integer); TEST_ASSERT_EQUAL(42, CAR(am.regs[ARGL])->atom.integer);
TEST_ASSERT_TRUE(CDR(am.argl)->is_atom); TEST_ASSERT_TRUE(CDR(am.regs[ARGL])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, CDR(am.argl)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, CDR(am.regs[ARGL])->atom.type);
} }
int main(void) int main(void)

View File

@@ -16,36 +16,36 @@ void tearDown(void)
static void test_set_foo_to_42_then_fetch(void) static void test_set_foo_to_42_then_fetch(void)
{ {
am.expr = expr_str_symbol(&am, "foo"); am.regs[EXPR] = expr_str_symbol(&am, "foo");
am.val = expr_integer(&am, 42); am.regs[VAL] = expr_integer(&am, 42);
env_set(&am); env_set(&am);
am.expr = expr_str_symbol(&am, "foo"); am.regs[EXPR] = expr_str_symbol(&am, "foo");
am.val = NULL; am.regs[VAL] = NULL;
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(42, am.val->atom.integer); TEST_ASSERT_EQUAL(42, am.regs[VAL]->atom.integer);
} }
static void test_update_foo_from_123_to_456_then_fetch(void) static void test_update_foo_from_123_to_456_then_fetch(void)
{ {
am.expr = expr_str_symbol(&am, "foo"); am.regs[EXPR] = expr_str_symbol(&am, "foo");
am.val = expr_integer(&am, 123); am.regs[VAL] = expr_integer(&am, 123);
env_set(&am); env_set(&am);
am.val = expr_integer(&am, 456); am.regs[VAL] = expr_integer(&am, 456);
env_set(&am); env_set(&am);
am.expr = expr_str_symbol(&am, "foo"); am.regs[EXPR] = expr_str_symbol(&am, "foo");
am.val = NULL; am.regs[VAL] = NULL;
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(456, am.val->atom.integer); TEST_ASSERT_EQUAL(456, am.regs[VAL]->atom.integer);
} }
int main(void) int main(void)

View File

@@ -21,57 +21,57 @@ void tearDown(void)
static void test_42_self_evals(void) static void test_42_self_evals(void)
{ {
am.expr = expr_integer(&am, 42); am.regs[EXPR] = expr_integer(&am, 42);
eval(&am); eval(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(42, am.val->atom.integer); TEST_ASSERT_EQUAL(42, am.regs[VAL]->atom.integer);
} }
static void test_empty_list_self_evals(void) static void test_empty_list_self_evals(void)
{ {
am.expr = expr_empty_list(&am); am.regs[EXPR] = expr_empty_list(&am);
eval(&am); eval(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, am.regs[VAL]->atom.type);
} }
static void test_prim_proc_self_evals(void) static void test_prim_proc_self_evals(void)
{ {
am.expr = expr_prim_proc(&am, test_prim_proc); am.regs[EXPR] = expr_prim_proc(&am, test_prim_proc);
eval(&am); eval(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(test_prim_proc, am.val->atom.prim_proc); TEST_ASSERT_EQUAL(test_prim_proc, am.regs[VAL]->atom.prim_proc);
} }
static void test_foo_evals_to_42_when_set_in_env(void) static void test_foo_evals_to_42_when_set_in_env(void)
{ {
am.expr = expr_str_symbol(&am, "foo"); am.regs[EXPR] = expr_str_symbol(&am, "foo");
am.val = expr_integer(&am, 42); am.regs[VAL] = expr_integer(&am, 42);
env_set(&am); env_set(&am);
am.val = NULL; am.regs[VAL] = NULL;
eval(&am); eval(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(42, am.val->atom.integer); TEST_ASSERT_EQUAL(42, am.regs[VAL]->atom.integer);
} }
static void test_add_1_2_3_evals_to_6(void) static void test_add_1_2_3_evals_to_6(void)
{ {
am.expr = expr_pair( am.regs[EXPR] = expr_pair(
&am, expr_str_symbol(&am, "+"), &am, expr_str_symbol(&am, "+"),
expr_pair( expr_pair(
&am, expr_integer(&am, 1), &am, expr_integer(&am, 1),
@@ -82,15 +82,15 @@ static void test_add_1_2_3_evals_to_6(void)
eval(&am); eval(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(6, am.val->atom.integer); TEST_ASSERT_EQUAL(6, am.regs[VAL]->atom.integer);
} }
static void test_add_1_mul_2_3_evals_to_7(void) static void test_add_1_mul_2_3_evals_to_7(void)
{ {
am.expr = expr_pair( am.regs[EXPR] = expr_pair(
&am, expr_str_symbol(&am, "+"), &am, expr_str_symbol(&am, "+"),
expr_pair( expr_pair(
&am, expr_integer(&am, 1), &am, expr_integer(&am, 1),
@@ -107,10 +107,10 @@ static void test_add_1_mul_2_3_evals_to_7(void)
eval(&am); eval(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(7, am.val->atom.integer); TEST_ASSERT_EQUAL(7, am.regs[VAL]->atom.integer);
} }
int main(void) int main(void)

View File

@@ -23,10 +23,10 @@ static void test_integer_123(void)
const parse_state_t state = parse_proc(&ctx, &token); const parse_state_t state = parse_proc(&ctx, &token);
TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state); TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_TRUE(am.expr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.expr->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[EXPR]->atom.type);
TEST_ASSERT_EQUAL(123, am.expr->atom.integer); TEST_ASSERT_EQUAL(123, am.regs[EXPR]->atom.integer);
} }
static void test_integer_321(void) static void test_integer_321(void)
@@ -36,10 +36,10 @@ static void test_integer_321(void)
const parse_state_t state = parse_proc(&ctx, &token); const parse_state_t state = parse_proc(&ctx, &token);
TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state); TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_TRUE(am.expr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.expr->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[EXPR]->atom.type);
TEST_ASSERT_EQUAL(321, am.expr->atom.integer); TEST_ASSERT_EQUAL(321, am.regs[EXPR]->atom.integer);
} }
static void test_symbol_foo(void) static void test_symbol_foo(void)
@@ -52,11 +52,11 @@ static void test_symbol_foo(void)
const parse_state_t state = parse_proc(&ctx, &token); const parse_state_t state = parse_proc(&ctx, &token);
TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state); TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_TRUE(am.expr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, am.expr->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, am.regs[EXPR]->atom.type);
TEST_ASSERT_EQUAL(3, am.expr->atom.symbol.len); TEST_ASSERT_EQUAL(3, am.regs[EXPR]->atom.symbol.len);
TEST_ASSERT_EQUAL_MEMORY("foo", am.expr->atom.symbol.buf, 3); TEST_ASSERT_EQUAL_MEMORY("foo", am.regs[EXPR]->atom.symbol.buf, 3);
} }
static void test_symbol_quux(void) static void test_symbol_quux(void)
@@ -69,11 +69,11 @@ static void test_symbol_quux(void)
const parse_state_t state = parse_proc(&ctx, &token); const parse_state_t state = parse_proc(&ctx, &token);
TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state); TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_TRUE(am.expr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, am.expr->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, am.regs[EXPR]->atom.type);
TEST_ASSERT_EQUAL(4, am.expr->atom.symbol.len); TEST_ASSERT_EQUAL(4, am.regs[EXPR]->atom.symbol.len);
TEST_ASSERT_EQUAL_MEMORY("quux", am.expr->atom.symbol.buf, 4); TEST_ASSERT_EQUAL_MEMORY("quux", am.regs[EXPR]->atom.symbol.buf, 4);
} }
static void test_open_paren_close_paren(void) static void test_open_paren_close_paren(void)
@@ -90,9 +90,9 @@ static void test_open_paren_close_paren(void)
state = parse_proc(&ctx, tokens + 1); state = parse_proc(&ctx, tokens + 1);
TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state); TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_TRUE(am.expr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, am.expr->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, am.regs[EXPR]->atom.type);
} }
static void test_open_paren_foo_42_close_paren(void) static void test_open_paren_foo_42_close_paren(void)
@@ -116,28 +116,29 @@ static void test_open_paren_foo_42_close_paren(void)
state = parse_proc(&ctx, tokens + NELEMS(tokens) - 1); state = parse_proc(&ctx, tokens + NELEMS(tokens) - 1);
TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state); TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_FALSE(am.expr->is_atom); TEST_ASSERT_FALSE(am.regs[EXPR]->is_atom);
TEST_ASSERT_NOT_NULL(am.expr->pair.car); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.car);
TEST_ASSERT_TRUE(am.expr->pair.car->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.car->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, am.expr->pair.car->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, am.regs[EXPR]->pair.car->atom.type);
TEST_ASSERT_EQUAL(3, am.expr->pair.car->atom.symbol.len); TEST_ASSERT_EQUAL(3, am.regs[EXPR]->pair.car->atom.symbol.len);
TEST_ASSERT_EQUAL_MEMORY("foo", am.expr->pair.car->atom.symbol.buf, 3); TEST_ASSERT_EQUAL_MEMORY(
"foo", am.regs[EXPR]->pair.car->atom.symbol.buf, 3);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr);
TEST_ASSERT_FALSE(am.expr->pair.cdr->is_atom); TEST_ASSERT_FALSE(am.regs[EXPR]->pair.cdr->is_atom);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.car); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.car);
TEST_ASSERT_TRUE(am.expr->pair.cdr->pair.car->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.cdr->pair.car->is_atom);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
ATOM_TYPE_INTEGER, am.expr->pair.cdr->pair.car->atom.type); ATOM_TYPE_INTEGER, am.regs[EXPR]->pair.cdr->pair.car->atom.type);
TEST_ASSERT_EQUAL(42, am.expr->pair.cdr->pair.car->atom.integer); TEST_ASSERT_EQUAL(42, am.regs[EXPR]->pair.cdr->pair.car->atom.integer);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.cdr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.cdr);
TEST_ASSERT_TRUE(am.expr->pair.cdr->pair.cdr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.cdr->pair.cdr->is_atom);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
ATOM_TYPE_EMPTY_LIST, am.expr->pair.cdr->pair.cdr->atom.type); ATOM_TYPE_EMPTY_LIST, am.regs[EXPR]->pair.cdr->pair.cdr->atom.type);
} }
static void test_open_paren_1_open_paren_2_close_paren_3_close_paren(void) static void test_open_paren_1_open_paren_2_close_paren_3_close_paren(void)
@@ -161,48 +162,50 @@ static void test_open_paren_1_open_paren_2_close_paren_3_close_paren(void)
state = parse_proc(&ctx, tokens + NELEMS(tokens) - 1); state = parse_proc(&ctx, tokens + NELEMS(tokens) - 1);
TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state); TEST_ASSERT_EQUAL(PARSE_STATE_DONE, state);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_FALSE(am.expr->is_atom); TEST_ASSERT_FALSE(am.regs[EXPR]->is_atom);
TEST_ASSERT_NOT_NULL(am.expr->pair.car); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.car);
TEST_ASSERT_TRUE(am.expr->pair.car->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.car->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.expr->pair.car->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[EXPR]->pair.car->atom.type);
TEST_ASSERT_EQUAL(1, am.expr->pair.car->atom.integer); TEST_ASSERT_EQUAL(1, am.regs[EXPR]->pair.car->atom.integer);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr);
TEST_ASSERT_FALSE(am.expr->pair.cdr->is_atom); TEST_ASSERT_FALSE(am.regs[EXPR]->pair.cdr->is_atom);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.car); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.car);
TEST_ASSERT_FALSE(am.expr->pair.cdr->pair.car->is_atom); TEST_ASSERT_FALSE(am.regs[EXPR]->pair.cdr->pair.car->is_atom);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.car->pair.car); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.car->pair.car);
TEST_ASSERT_TRUE(am.expr->pair.cdr->pair.car->pair.car->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.cdr->pair.car->pair.car->is_atom);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
ATOM_TYPE_INTEGER, am.expr->pair.cdr->pair.car->pair.car->atom.type); ATOM_TYPE_INTEGER,
am.regs[EXPR]->pair.cdr->pair.car->pair.car->atom.type);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
2, am.expr->pair.cdr->pair.car->pair.car->atom.integer); 2, am.regs[EXPR]->pair.cdr->pair.car->pair.car->atom.integer);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.car->pair.cdr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.car->pair.cdr);
TEST_ASSERT_TRUE(am.expr->pair.cdr->pair.car->pair.cdr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.cdr->pair.car->pair.cdr->is_atom);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
ATOM_TYPE_EMPTY_LIST, ATOM_TYPE_EMPTY_LIST,
am.expr->pair.cdr->pair.car->pair.cdr->atom.type); am.regs[EXPR]->pair.cdr->pair.car->pair.cdr->atom.type);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.cdr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.cdr);
TEST_ASSERT_FALSE(am.expr->pair.cdr->pair.cdr->is_atom); TEST_ASSERT_FALSE(am.regs[EXPR]->pair.cdr->pair.cdr->is_atom);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.cdr->pair.car); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.cdr->pair.car);
TEST_ASSERT_TRUE(am.expr->pair.cdr->pair.cdr->pair.car->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.cdr->pair.cdr->pair.car->is_atom);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
ATOM_TYPE_INTEGER, am.expr->pair.cdr->pair.cdr->pair.car->atom.type); ATOM_TYPE_INTEGER,
am.regs[EXPR]->pair.cdr->pair.cdr->pair.car->atom.type);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
3, am.expr->pair.cdr->pair.cdr->pair.car->atom.integer); 3, am.regs[EXPR]->pair.cdr->pair.cdr->pair.car->atom.integer);
TEST_ASSERT_NOT_NULL(am.expr->pair.cdr->pair.cdr->pair.cdr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]->pair.cdr->pair.cdr->pair.cdr);
TEST_ASSERT_TRUE(am.expr->pair.cdr->pair.cdr->pair.cdr->is_atom); TEST_ASSERT_TRUE(am.regs[EXPR]->pair.cdr->pair.cdr->pair.cdr->is_atom);
TEST_ASSERT_EQUAL( TEST_ASSERT_EQUAL(
ATOM_TYPE_EMPTY_LIST, ATOM_TYPE_EMPTY_LIST,
am.expr->pair.cdr->pair.cdr->pair.cdr->atom.type); am.regs[EXPR]->pair.cdr->pair.cdr->pair.cdr->atom.type);
} }
static void test_close_paren(void) static void test_close_paren(void)

View File

@@ -15,116 +15,117 @@ void tearDown(void)
static void test_add_empty_list_is_0(void) static void test_add_empty_list_is_0(void)
{ {
am.expr = expr_str_symbol(&am, "+"); am.regs[EXPR] = expr_str_symbol(&am, "+");
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.regs[VAL]->atom.type);
am.argl = expr_empty_list(&am); am.regs[ARGL] = expr_empty_list(&am);
am.val->atom.prim_proc(&am); am.regs[VAL]->atom.prim_proc(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(0, am.val->atom.integer); TEST_ASSERT_EQUAL(0, am.regs[VAL]->atom.integer);
} }
static void test_add_1_2_3_is_6(void) static void test_add_1_2_3_is_6(void)
{ {
am.expr = expr_str_symbol(&am, "+"); am.regs[EXPR] = expr_str_symbol(&am, "+");
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.regs[VAL]->atom.type);
am.argl = expr_pair( am.regs[ARGL] = expr_pair(
&am, expr_integer(&am, 1), &am, expr_integer(&am, 1),
expr_pair( expr_pair(
&am, expr_integer(&am, 2), &am, expr_integer(&am, 2),
expr_pair(&am, expr_integer(&am, 3), expr_empty_list(&am)))); expr_pair(&am, expr_integer(&am, 3), expr_empty_list(&am))));
am.val->atom.prim_proc(&am); am.regs[VAL]->atom.prim_proc(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(6, am.val->atom.integer); TEST_ASSERT_EQUAL(6, am.regs[VAL]->atom.integer);
} }
static void test_mul_empty_list_is_1(void) static void test_mul_empty_list_is_1(void)
{ {
am.expr = expr_str_symbol(&am, "*"); am.regs[EXPR] = expr_str_symbol(&am, "*");
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.regs[VAL]->atom.type);
am.argl = expr_empty_list(&am); am.regs[ARGL] = expr_empty_list(&am);
am.val->atom.prim_proc(&am); am.regs[VAL]->atom.prim_proc(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(1, am.val->atom.integer); TEST_ASSERT_EQUAL(1, am.regs[VAL]->atom.integer);
} }
static void test_mul_2_3_4_is_24(void) static void test_mul_2_3_4_is_24(void)
{ {
am.expr = expr_str_symbol(&am, "*"); am.regs[EXPR] = expr_str_symbol(&am, "*");
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.regs[VAL]->atom.type);
am.argl = expr_pair( am.regs[ARGL] = expr_pair(
&am, expr_integer(&am, 2), &am, expr_integer(&am, 2),
expr_pair( expr_pair(
&am, expr_integer(&am, 3), &am, expr_integer(&am, 3),
expr_pair(&am, expr_integer(&am, 4), expr_empty_list(&am)))); expr_pair(&am, expr_integer(&am, 4), expr_empty_list(&am))));
am.val->atom.prim_proc(&am); am.regs[VAL]->atom.prim_proc(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(24, am.val->atom.integer); TEST_ASSERT_EQUAL(24, am.regs[VAL]->atom.integer);
} }
static void test_sub_1_is_minus_1(void) static void test_sub_1_is_minus_1(void)
{ {
am.expr = expr_str_symbol(&am, "-"); am.regs[EXPR] = expr_str_symbol(&am, "-");
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.regs[VAL]->atom.type);
am.argl = expr_pair(&am, expr_integer(&am, 1), expr_empty_list(&am)); am.regs[ARGL]
am.val->atom.prim_proc(&am); = expr_pair(&am, expr_integer(&am, 1), expr_empty_list(&am));
am.regs[VAL]->atom.prim_proc(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(-1, am.val->atom.integer); TEST_ASSERT_EQUAL(-1, am.regs[VAL]->atom.integer);
} }
static void test_sub_5_4_3_is_minus_2(void) static void test_sub_5_4_3_is_minus_2(void)
{ {
am.expr = expr_str_symbol(&am, "-"); am.regs[EXPR] = expr_str_symbol(&am, "-");
env_fetch(&am); env_fetch(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_PRIM_PROC, am.regs[VAL]->atom.type);
am.argl = expr_pair( am.regs[ARGL] = expr_pair(
&am, expr_integer(&am, 5), &am, expr_integer(&am, 5),
expr_pair( expr_pair(
&am, expr_integer(&am, 4), &am, expr_integer(&am, 4),
expr_pair(&am, expr_integer(&am, 3), expr_empty_list(&am)))); expr_pair(&am, expr_integer(&am, 3), expr_empty_list(&am))));
am.val->atom.prim_proc(&am); am.regs[VAL]->atom.prim_proc(&am);
TEST_ASSERT_NOT_NULL(am.val); TEST_ASSERT_NOT_NULL(am.regs[VAL]);
TEST_ASSERT_TRUE(am.val->is_atom); TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.val->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
TEST_ASSERT_EQUAL(-2, am.val->atom.integer); TEST_ASSERT_EQUAL(-2, am.regs[VAL]->atom.integer);
} }
int main(void) int main(void)

View File

@@ -20,7 +20,7 @@ void tearDown(void)
static void test_integer_5(void) static void test_integer_5(void)
{ {
am.val = expr_integer(&am, 5); am.regs[VAL] = expr_integer(&am, 5);
const size_t len = print(&am, buffer, BUFFER_SIZE); const size_t len = print(&am, buffer, BUFFER_SIZE);
TEST_ASSERT_EQUAL(1, len); TEST_ASSERT_EQUAL(1, len);
TEST_ASSERT_EQUAL_MEMORY("5", buffer, 1); TEST_ASSERT_EQUAL_MEMORY("5", buffer, 1);
@@ -28,7 +28,7 @@ static void test_integer_5(void)
static void test_integer_1234(void) static void test_integer_1234(void)
{ {
am.val = expr_integer(&am, 1234); am.regs[VAL] = expr_integer(&am, 1234);
const size_t len = print(&am, buffer, BUFFER_SIZE); const size_t len = print(&am, buffer, BUFFER_SIZE);
TEST_ASSERT_EQUAL(4, len); TEST_ASSERT_EQUAL(4, len);
TEST_ASSERT_EQUAL_MEMORY("1234", buffer, 4); TEST_ASSERT_EQUAL_MEMORY("1234", buffer, 4);
@@ -36,7 +36,7 @@ static void test_integer_1234(void)
static void test_integer_0(void) static void test_integer_0(void)
{ {
am.val = expr_integer(&am, 0); am.regs[VAL] = expr_integer(&am, 0);
const size_t len = print(&am, buffer, BUFFER_SIZE); const size_t len = print(&am, buffer, BUFFER_SIZE);
TEST_ASSERT_EQUAL(1, len); TEST_ASSERT_EQUAL(1, len);
TEST_ASSERT_EQUAL_MEMORY("0", buffer, 1); TEST_ASSERT_EQUAL_MEMORY("0", buffer, 1);
@@ -44,7 +44,7 @@ static void test_integer_0(void)
static void test_integer_10(void) static void test_integer_10(void)
{ {
am.val = expr_integer(&am, 10); am.regs[VAL] = expr_integer(&am, 10);
const size_t len = print(&am, buffer, BUFFER_SIZE); const size_t len = print(&am, buffer, BUFFER_SIZE);
TEST_ASSERT_EQUAL(2, len); TEST_ASSERT_EQUAL(2, len);
TEST_ASSERT_EQUAL_MEMORY("10", buffer, 2); TEST_ASSERT_EQUAL_MEMORY("10", buffer, 2);
@@ -52,7 +52,7 @@ static void test_integer_10(void)
static void test_integer_minus_4321(void) static void test_integer_minus_4321(void)
{ {
am.val = expr_integer(&am, -4321); am.regs[VAL] = expr_integer(&am, -4321);
const size_t len = print(&am, buffer, BUFFER_SIZE); const size_t len = print(&am, buffer, BUFFER_SIZE);
TEST_ASSERT_EQUAL(5, len); TEST_ASSERT_EQUAL(5, len);
TEST_ASSERT_EQUAL_MEMORY("-4321", buffer, 5); TEST_ASSERT_EQUAL_MEMORY("-4321", buffer, 5);

View File

@@ -36,58 +36,59 @@ static void test_nested_expression(void)
read(&am, (stream_t *)&stream); read(&am, (stream_t *)&stream);
TEST_ASSERT_NOT_NULL(am.expr); TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
TEST_ASSERT_FALSE(am.expr->is_atom); TEST_ASSERT_FALSE(am.regs[EXPR]->is_atom);
TEST_ASSERT_NOT_NULL(CAR(am.expr)); TEST_ASSERT_NOT_NULL(CAR(am.regs[EXPR]));
TEST_ASSERT_TRUE(CAR(am.expr)->is_atom); TEST_ASSERT_TRUE(CAR(am.regs[EXPR])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, CAR(am.expr)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, CAR(am.regs[EXPR])->atom.type);
TEST_ASSERT_EQUAL(1, CAR(am.expr)->atom.symbol.len); TEST_ASSERT_EQUAL(1, CAR(am.regs[EXPR])->atom.symbol.len);
TEST_ASSERT_EQUAL_MEMORY("+", CAR(am.expr)->atom.symbol.buf, 1); TEST_ASSERT_EQUAL_MEMORY("+", CAR(am.regs[EXPR])->atom.symbol.buf, 1);
TEST_ASSERT_NOT_NULL(CDR(am.expr)); TEST_ASSERT_NOT_NULL(CDR(am.regs[EXPR]));
TEST_ASSERT_FALSE(CDR(am.expr)->is_atom); TEST_ASSERT_FALSE(CDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_NOT_NULL(CADR(am.expr)); TEST_ASSERT_NOT_NULL(CADR(am.regs[EXPR]));
TEST_ASSERT_TRUE(CADR(am.expr)->is_atom); TEST_ASSERT_TRUE(CADR(am.regs[EXPR])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CADR(am.expr)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CADR(am.regs[EXPR])->atom.type);
TEST_ASSERT_EQUAL(1, CADR(am.expr)->atom.integer); TEST_ASSERT_EQUAL(1, CADR(am.regs[EXPR])->atom.integer);
TEST_ASSERT_NOT_NULL(CDDR(am.expr)); TEST_ASSERT_NOT_NULL(CDDR(am.regs[EXPR]));
TEST_ASSERT_FALSE(CDDR(am.expr)->is_atom); TEST_ASSERT_FALSE(CDDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_NOT_NULL(CADDR(am.expr)); TEST_ASSERT_NOT_NULL(CADDR(am.regs[EXPR]));
TEST_ASSERT_FALSE(CADDR(am.expr)->is_atom); TEST_ASSERT_FALSE(CADDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_NOT_NULL(CAADDR(am.expr)); TEST_ASSERT_NOT_NULL(CAADDR(am.regs[EXPR]));
TEST_ASSERT_TRUE(CAADDR(am.expr)->is_atom); TEST_ASSERT_TRUE(CAADDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, CAADDR(am.expr)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_SYMBOL, CAADDR(am.regs[EXPR])->atom.type);
TEST_ASSERT_EQUAL(1, CAADDR(am.expr)->atom.symbol.len); TEST_ASSERT_EQUAL(1, CAADDR(am.regs[EXPR])->atom.symbol.len);
TEST_ASSERT_EQUAL_MEMORY("*", CAADDR(am.expr)->atom.symbol.buf, 1); TEST_ASSERT_EQUAL_MEMORY("*", CAADDR(am.regs[EXPR])->atom.symbol.buf, 1);
TEST_ASSERT_NOT_NULL(CDADDR(am.expr)); TEST_ASSERT_NOT_NULL(CDADDR(am.regs[EXPR]));
TEST_ASSERT_FALSE(CDADDR(am.expr)->is_atom); TEST_ASSERT_FALSE(CDADDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_NOT_NULL(CADADDR(am.expr)); TEST_ASSERT_NOT_NULL(CADADDR(am.regs[EXPR]));
TEST_ASSERT_TRUE(CADADDR(am.expr)->is_atom); TEST_ASSERT_TRUE(CADADDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CADADDR(am.expr)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CADADDR(am.regs[EXPR])->atom.type);
TEST_ASSERT_EQUAL(2, CADADDR(am.expr)->atom.integer); TEST_ASSERT_EQUAL(2, CADADDR(am.regs[EXPR])->atom.integer);
TEST_ASSERT_NOT_NULL(CDDADDR(am.expr)); TEST_ASSERT_NOT_NULL(CDDADDR(am.regs[EXPR]));
TEST_ASSERT_FALSE(CDDADDR(am.expr)->is_atom); TEST_ASSERT_FALSE(CDDADDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_NOT_NULL(CADDADDR(am.expr)); TEST_ASSERT_NOT_NULL(CADDADDR(am.regs[EXPR]));
TEST_ASSERT_TRUE(CADDADDR(am.expr)->is_atom); TEST_ASSERT_TRUE(CADDADDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CADDADDR(am.expr)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CADDADDR(am.regs[EXPR])->atom.type);
TEST_ASSERT_EQUAL(3, CADDADDR(am.expr)->atom.integer); TEST_ASSERT_EQUAL(3, CADDADDR(am.regs[EXPR])->atom.integer);
TEST_ASSERT_NOT_NULL(CDDDADDR(am.expr)); TEST_ASSERT_NOT_NULL(CDDDADDR(am.regs[EXPR]));
TEST_ASSERT_TRUE(CDDDADDR(am.expr)->is_atom); TEST_ASSERT_TRUE(CDDDADDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, CDDDADDR(am.expr)->atom.type); TEST_ASSERT_EQUAL(
ATOM_TYPE_EMPTY_LIST, CDDDADDR(am.regs[EXPR])->atom.type);
TEST_ASSERT_NOT_NULL(CDDDR(am.expr)); TEST_ASSERT_NOT_NULL(CDDDR(am.regs[EXPR]));
TEST_ASSERT_TRUE(CDDDR(am.expr)->is_atom); TEST_ASSERT_TRUE(CDDDR(am.regs[EXPR])->is_atom);
TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, CDDDR(am.expr)->atom.type); TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, CDDDR(am.regs[EXPR])->atom.type);
} }
int main(void) int main(void)