Compare commits
8 Commits
6077cf571d
...
426d270318
| Author | SHA1 | Date | |
|---|---|---|---|
| 426d270318 | |||
| eaef6f3cd3 | |||
| 76efcef953 | |||
| 57c39fd00b | |||
| 52a42d2937 | |||
| ba0a543a4c | |||
| 662b99a40f | |||
| 624311d04f |
36
lib/am.c
36
lib/am.c
@@ -14,14 +14,42 @@ void am_init(am_t *am)
|
|||||||
env_init(am);
|
env_init(am);
|
||||||
}
|
}
|
||||||
|
|
||||||
void am_push(am_t *am)
|
void am_push(am_t *am, am_reg_t reg)
|
||||||
{
|
{
|
||||||
assert(am->sp >= am->stack);
|
assert(am->sp >= am->stack);
|
||||||
*am->sp-- = am->expr;
|
*am->sp-- = am->regs[reg];
|
||||||
}
|
}
|
||||||
|
|
||||||
void am_pop(am_t *am)
|
void am_pop(am_t *am, am_reg_t reg)
|
||||||
{
|
{
|
||||||
assert(am->sp < am->stack + AM_STACK_SIZE - 1);
|
assert(am->sp < am->stack + AM_STACK_SIZE - 1);
|
||||||
am->expr = *++am->sp;
|
am->regs[reg] = *++am->sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void am_append(am_t *am, am_reg_t list_reg, am_reg_t item_reg)
|
||||||
|
{
|
||||||
|
expr_t *list = am->regs[list_reg];
|
||||||
|
while (!list->is_atom)
|
||||||
|
list = list->pair.cdr;
|
||||||
|
|
||||||
|
list->is_atom = false;
|
||||||
|
list->pair.car = am->regs[item_reg];
|
||||||
|
list->pair.cdr = expr_empty_list(am);
|
||||||
|
}
|
||||||
|
|
||||||
|
void am_car(am_t *am, am_reg_t dest, am_reg_t src)
|
||||||
|
{
|
||||||
|
assert(!am->regs[src]->is_atom);
|
||||||
|
am->regs[dest] = am->regs[src]->pair.car;
|
||||||
|
}
|
||||||
|
|
||||||
|
void am_cdr(am_t *am, am_reg_t dest, am_reg_t src)
|
||||||
|
{
|
||||||
|
assert(!am->regs[src]->is_atom);
|
||||||
|
am->regs[dest] = am->regs[src]->pair.cdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void am_assign(am_t *am, am_reg_t dest, am_reg_t src)
|
||||||
|
{
|
||||||
|
am->regs[dest] = am->regs[src];
|
||||||
}
|
}
|
||||||
|
|||||||
24
lib/env.c
24
lib/env.c
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
lib/eval.c
40
lib/eval.c
@@ -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_assign(am, VAL, EXPR);
|
||||||
break;
|
break;
|
||||||
case ATOM_TYPE_SYMBOL:
|
case ATOM_TYPE_SYMBOL:
|
||||||
env_fetch(am);
|
env_fetch(am);
|
||||||
@@ -20,22 +20,40 @@ static void eval_atom(am_t *am)
|
|||||||
|
|
||||||
static void eval_list(am_t *am)
|
static void eval_list(am_t *am)
|
||||||
{
|
{
|
||||||
am->argl = am->expr->pair.cdr;
|
AM_ARGL(am) = expr_empty_list(am);
|
||||||
am->expr = am->expr->pair.car;
|
am_cdr(am, UNEV, EXPR);
|
||||||
|
am_car(am, EXPR, EXPR);
|
||||||
|
|
||||||
assert(am->expr->is_atom);
|
while (!AM_UNEV(am)->is_atom) {
|
||||||
assert(am->expr->atom.type == ATOM_TYPE_SYMBOL);
|
am_push(am, EXPR);
|
||||||
|
am_push(am, ARGL);
|
||||||
|
|
||||||
|
am_car(am, EXPR, UNEV);
|
||||||
|
am_cdr(am, UNEV, UNEV);
|
||||||
|
am_push(am, UNEV);
|
||||||
|
|
||||||
|
eval(am);
|
||||||
|
|
||||||
|
am_pop(am, UNEV);
|
||||||
|
am_pop(am, ARGL);
|
||||||
|
am_pop(am, EXPR);
|
||||||
|
|
||||||
|
am_append(am, ARGL, VAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(AM_EXPR(am)->is_atom);
|
||||||
|
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);
|
||||||
|
|||||||
@@ -6,14 +6,34 @@
|
|||||||
|
|
||||||
#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, *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;
|
||||||
|
|
||||||
void am_init(am_t *am);
|
void am_init(am_t *am);
|
||||||
void am_push(am_t *am);
|
void am_push(am_t *am, am_reg_t reg);
|
||||||
void am_pop(am_t *am);
|
void am_pop(am_t *am, am_reg_t reg);
|
||||||
|
void am_append(am_t *am, am_reg_t list_reg, am_reg_t item_reg);
|
||||||
|
void am_car(am_t *am, am_reg_t dest, am_reg_t src);
|
||||||
|
void am_cdr(am_t *am, am_reg_t dest, am_reg_t src);
|
||||||
|
void am_assign(am_t *am, am_reg_t dest, am_reg_t src);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
34
lib/parse.c
34
lib/parse.c
@@ -22,34 +22,22 @@ static parse_state_t pop_state(parse_ctx_t *ctx)
|
|||||||
return *++ctx->sp;
|
return *++ctx->sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append(parse_ctx_t *ctx, expr_t *expr)
|
|
||||||
{
|
|
||||||
expr_t *list = ctx->am->expr;
|
|
||||||
while (!list->is_atom)
|
|
||||||
list = list->pair.cdr;
|
|
||||||
assert(list->atom.type == ATOM_TYPE_EMPTY_LIST);
|
|
||||||
|
|
||||||
list->is_atom = false;
|
|
||||||
list->pair.car = expr;
|
|
||||||
list->pair.cdr = expr_empty_list(ctx->am);
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_state_t parse_proc(parse_ctx_t *ctx, const token_t *token)
|
parse_state_t parse_proc(parse_ctx_t *ctx, const token_t *token)
|
||||||
{
|
{
|
||||||
switch (ctx->state) {
|
switch (ctx->state) {
|
||||||
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:
|
||||||
@@ -61,23 +49,25 @@ parse_state_t parse_proc(parse_ctx_t *ctx, const token_t *token)
|
|||||||
case PARSE_STATE_LIST:
|
case PARSE_STATE_LIST:
|
||||||
switch (token->type) {
|
switch (token->type) {
|
||||||
case TOKEN_TYPE_INTEGER:
|
case TOKEN_TYPE_INTEGER:
|
||||||
append(ctx, expr_integer(ctx->am, token->integer));
|
AM_VAL(ctx->am) = expr_integer(ctx->am, token->integer);
|
||||||
|
am_append(ctx->am, EXPR, VAL);
|
||||||
break;
|
break;
|
||||||
case TOKEN_TYPE_SYMBOL:
|
case TOKEN_TYPE_SYMBOL:
|
||||||
append(ctx, expr_symbol(ctx->am, &token->symbol));
|
AM_VAL(ctx->am) = expr_symbol(ctx->am, &token->symbol);
|
||||||
|
am_append(ctx->am, EXPR, VAL);
|
||||||
break;
|
break;
|
||||||
case TOKEN_TYPE_OPEN_PAREN:
|
case TOKEN_TYPE_OPEN_PAREN:
|
||||||
am_push(ctx->am);
|
am_push(ctx->am, EXPR);
|
||||||
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;
|
AM_VAL(ctx->am) = AM_EXPR(ctx->am);
|
||||||
am_pop(ctx->am);
|
am_pop(ctx->am, EXPR);
|
||||||
append(ctx, expr);
|
am_append(ctx->am, EXPR, VAL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
32
lib/prim.c
32
lib/prim.c
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
lib/print.c
14
lib/print.c
@@ -4,15 +4,21 @@
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
int64_t value = AM_VAL(am)->atom.integer;
|
||||||
|
if (value < 0) {
|
||||||
|
buffer[i++] = '-';
|
||||||
|
value *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t value = am->val->atom.integer;
|
|
||||||
int divisor = 10;
|
int divisor = 10;
|
||||||
while (divisor <= value)
|
while (divisor <= value)
|
||||||
divisor *= 10;
|
divisor *= 10;
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
do {
|
do {
|
||||||
divisor /= 10;
|
divisor /= 10;
|
||||||
const int digit = value / divisor;
|
const int digit = value / divisor;
|
||||||
|
|||||||
110
tests/am_tests.c
110
tests/am_tests.c
@@ -1,6 +1,10 @@
|
|||||||
#include "am.h"
|
#include "am.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
|
||||||
|
#define CAR(expr) (expr->pair.car)
|
||||||
|
#define CDR(expr) (expr->pair.cdr)
|
||||||
|
#define CADR(expr) CAR(CDR(expr))
|
||||||
|
|
||||||
static am_t am;
|
static am_t am;
|
||||||
|
|
||||||
void setUp(void)
|
void setUp(void)
|
||||||
@@ -15,16 +19,112 @@ 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_push(&am);
|
am.regs[EXPR] = &a;
|
||||||
am.expr = &b;
|
am_push(&am, EXPR);
|
||||||
am_pop(&am);
|
am.regs[EXPR] = &b;
|
||||||
TEST_ASSERT_EQUAL(&a, am.expr);
|
am_pop(&am, EXPR);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(&a, am.regs[EXPR]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_argl_value_restored_after_push_modify_pop(void)
|
||||||
|
{
|
||||||
|
expr_t a, b;
|
||||||
|
|
||||||
|
am.regs[ARGL] = &a;
|
||||||
|
am_push(&am, ARGL);
|
||||||
|
am.regs[ARGL] = &b;
|
||||||
|
am_pop(&am, ARGL);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(&a, am.regs[ARGL]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_append_val_42_to_empty_argl(void)
|
||||||
|
{
|
||||||
|
am.regs[ARGL] = expr_empty_list(&am);
|
||||||
|
am.regs[VAL] = expr_integer(&am, 42);
|
||||||
|
am_append(&am, ARGL, VAL);
|
||||||
|
|
||||||
|
TEST_ASSERT_FALSE(am.regs[ARGL]->is_atom);
|
||||||
|
TEST_ASSERT_NOT_NULL(CAR(am.regs[ARGL]));
|
||||||
|
|
||||||
|
TEST_ASSERT_TRUE(CAR(am.regs[ARGL])->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CAR(am.regs[ARGL])->atom.type);
|
||||||
|
TEST_ASSERT_EQUAL(42, CAR(am.regs[ARGL])->atom.integer);
|
||||||
|
|
||||||
|
TEST_ASSERT_TRUE(CDR(am.regs[ARGL])->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_EMPTY_LIST, CDR(am.regs[ARGL])->atom.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_append_unev_2_to_expr_list_1(void)
|
||||||
|
{
|
||||||
|
am.regs[EXPR]
|
||||||
|
= expr_pair(&am, expr_integer(&am, 1), expr_empty_list(&am));
|
||||||
|
am.regs[UNEV] = expr_integer(&am, 2);
|
||||||
|
am_append(&am, EXPR, UNEV);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
|
||||||
|
TEST_ASSERT_FALSE(am.regs[EXPR]->is_atom);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(CAR(am.regs[EXPR]));
|
||||||
|
TEST_ASSERT_TRUE(CAR(am.regs[EXPR])->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CAR(am.regs[EXPR])->atom.type);
|
||||||
|
TEST_ASSERT_EQUAL(1, CAR(am.regs[EXPR])->atom.integer);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(CDR(am.regs[EXPR]));
|
||||||
|
TEST_ASSERT_FALSE(CDR(am.regs[EXPR])->is_atom);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(CADR(am.regs[EXPR]));
|
||||||
|
TEST_ASSERT_TRUE(CADR(am.regs[EXPR])->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, CADR(am.regs[EXPR])->atom.type);
|
||||||
|
TEST_ASSERT_EQUAL(2, CADR(am.regs[EXPR])->atom.integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_car_of_expr_pair_1_2(void)
|
||||||
|
{
|
||||||
|
am.regs[EXPR]
|
||||||
|
= expr_pair(&am, expr_integer(&am, 1), expr_integer(&am, 2));
|
||||||
|
am_car(&am, EXPR, EXPR);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
|
||||||
|
TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[EXPR]->atom.type);
|
||||||
|
TEST_ASSERT_EQUAL(1, am.regs[EXPR]->atom.integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_cdr_of_expr_pair_1_2(void)
|
||||||
|
{
|
||||||
|
am.regs[EXPR]
|
||||||
|
= expr_pair(&am, expr_integer(&am, 1), expr_integer(&am, 2));
|
||||||
|
am_cdr(&am, EXPR, EXPR);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
|
||||||
|
TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[EXPR]->atom.type);
|
||||||
|
TEST_ASSERT_EQUAL(2, am.regs[EXPR]->atom.integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_assign_expr_to_val(void)
|
||||||
|
{
|
||||||
|
am.regs[EXPR] = expr_integer(&am, 42);
|
||||||
|
am_assign(&am, VAL, EXPR);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(am.regs[EXPR]);
|
||||||
|
TEST_ASSERT_TRUE(am.regs[EXPR]->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[EXPR]->atom.type);
|
||||||
|
TEST_ASSERT_EQUAL(42, am.regs[EXPR]->atom.integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
RUN_TEST(test_expr_value_restored_after_push_modify_pop);
|
RUN_TEST(test_expr_value_restored_after_push_modify_pop);
|
||||||
|
RUN_TEST(test_argl_value_restored_after_push_modify_pop);
|
||||||
|
RUN_TEST(test_append_val_42_to_empty_argl);
|
||||||
|
RUN_TEST(test_append_unev_2_to_expr_list_1);
|
||||||
|
RUN_TEST(test_car_of_expr_pair_1_2);
|
||||||
|
RUN_TEST(test_cdr_of_expr_pair_1_2);
|
||||||
|
RUN_TEST(test_assign_expr_to_val);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,10 +82,35 @@ 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)
|
||||||
|
{
|
||||||
|
am.regs[EXPR] = expr_pair(
|
||||||
|
&am, expr_str_symbol(&am, "+"),
|
||||||
|
expr_pair(
|
||||||
|
&am, expr_integer(&am, 1),
|
||||||
|
expr_pair(
|
||||||
|
&am,
|
||||||
|
expr_pair(
|
||||||
|
&am, expr_str_symbol(&am, "*"),
|
||||||
|
expr_pair(
|
||||||
|
&am, expr_integer(&am, 2),
|
||||||
|
expr_pair(
|
||||||
|
&am, expr_integer(&am, 3),
|
||||||
|
expr_empty_list(&am)))),
|
||||||
|
expr_empty_list(&am))));
|
||||||
|
|
||||||
|
eval(&am);
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(am.regs[VAL]);
|
||||||
|
TEST_ASSERT_TRUE(am.regs[VAL]->is_atom);
|
||||||
|
TEST_ASSERT_EQUAL(ATOM_TYPE_INTEGER, am.regs[VAL]->atom.type);
|
||||||
|
TEST_ASSERT_EQUAL(7, am.regs[VAL]->atom.integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
@@ -96,5 +121,6 @@ int main(void)
|
|||||||
RUN_TEST(test_prim_proc_self_evals);
|
RUN_TEST(test_prim_proc_self_evals);
|
||||||
RUN_TEST(test_foo_evals_to_42_when_set_in_env);
|
RUN_TEST(test_foo_evals_to_42_when_set_in_env);
|
||||||
RUN_TEST(test_add_1_2_3_evals_to_6);
|
RUN_TEST(test_add_1_2_3_evals_to_6);
|
||||||
|
RUN_TEST(test_add_1_mul_2_3_evals_to_7);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,9 +40,16 @@ static void test_unnested_arithmetic(void)
|
|||||||
TEST_ASSERT_EQUAL_STRING("64", read_eval_print("(- 100 36)"));
|
TEST_ASSERT_EQUAL_STRING("64", read_eval_print("(- 100 36)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_nested_arithmetic(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_EQUAL_STRING("20", read_eval_print("(+ 1 (* 2 (+ 3 4)) 5)"));
|
||||||
|
TEST_ASSERT_EQUAL_STRING("-6", read_eval_print("(+ 1 (* 2 2 (- 3)) 5)"));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
RUN_TEST(test_unnested_arithmetic);
|
RUN_TEST(test_unnested_arithmetic);
|
||||||
|
RUN_TEST(test_nested_arithmetic);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,12 +44,20 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_integer_minus_4321(void)
|
||||||
|
{
|
||||||
|
am.regs[VAL] = expr_integer(&am, -4321);
|
||||||
|
const size_t len = print(&am, buffer, BUFFER_SIZE);
|
||||||
|
TEST_ASSERT_EQUAL(5, len);
|
||||||
|
TEST_ASSERT_EQUAL_MEMORY("-4321", buffer, 5);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@@ -57,5 +65,6 @@ int main(void)
|
|||||||
RUN_TEST(test_integer_1234);
|
RUN_TEST(test_integer_1234);
|
||||||
RUN_TEST(test_integer_0);
|
RUN_TEST(test_integer_0);
|
||||||
RUN_TEST(test_integer_10);
|
RUN_TEST(test_integer_10);
|
||||||
|
RUN_TEST(test_integer_minus_4321);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user