Minor refactor to parsing and testing cleanup
This commit is contained in:
33
src/parse.c
33
src/parse.c
@@ -57,7 +57,7 @@ struct ucl_object *ucl_token_next(const char **curr_src) {
|
|||||||
str[0] = **curr_src;
|
str[0] = **curr_src;
|
||||||
str[1] = '\0';
|
str[1] = '\0';
|
||||||
(*curr_src)++;
|
(*curr_src)++;
|
||||||
return ucl_cell_create(ucl_symbol_create(str), NULL);
|
return ucl_symbol_create(str);
|
||||||
case QUOTE_CHAR:
|
case QUOTE_CHAR:
|
||||||
// skip beginning quote
|
// skip beginning quote
|
||||||
(*curr_src)++;
|
(*curr_src)++;
|
||||||
@@ -69,20 +69,22 @@ struct ucl_object *ucl_token_next(const char **curr_src) {
|
|||||||
(*curr_src)++;
|
(*curr_src)++;
|
||||||
// -2 for removing start/end quotes
|
// -2 for removing start/end quotes
|
||||||
str = strndup(start + 1, *curr_src - start - 2);
|
str = strndup(start + 1, *curr_src - start - 2);
|
||||||
return ucl_cell_create(ucl_string_create(str), NULL);
|
// TODO: free
|
||||||
|
return ucl_string_create(str);
|
||||||
case '0'...'9': {
|
case '0'...'9': {
|
||||||
// TODO: Add support for negative integers
|
// TODO: Add support for negative integers
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
long value = strtol(*curr_src, &end, 0);
|
long value = strtol(*curr_src, &end, 0);
|
||||||
*curr_src = end;
|
*curr_src = end;
|
||||||
return ucl_cell_create(ucl_int_create(value), NULL);
|
return ucl_int_create(value);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
while (!ucl_is_delimiter(**curr_src)) {
|
while (!ucl_is_delimiter(**curr_src)) {
|
||||||
(*curr_src)++;
|
(*curr_src)++;
|
||||||
}
|
}
|
||||||
|
// TODO: Free
|
||||||
str = strndup(start, *curr_src - start);
|
str = strndup(start, *curr_src - start);
|
||||||
return ucl_cell_create(ucl_symbol_create(str), NULL);
|
return ucl_symbol_create(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,12 +94,12 @@ struct ucl_object *ucl_token_next(const char **curr_src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ucl_object *ucl_tokenize(const char *source) {
|
struct ucl_object *ucl_tokenize(const char *source) {
|
||||||
struct ucl_object *tokens = NULL, *curr_token = NULL, **next_token = &tokens;
|
struct ucl_object *tokens = ucl_nil_create();
|
||||||
|
struct ucl_object *curr_token = NULL;
|
||||||
const char *curr_src = source;
|
const char *curr_src = source;
|
||||||
|
|
||||||
while ((curr_token = ucl_token_next(&curr_src)) != NULL) {
|
while ((curr_token = ucl_token_next(&curr_src)) != NULL) {
|
||||||
*next_token = curr_token;
|
ucl_list_append(tokens, curr_token);
|
||||||
next_token = &curr_token->cell.cdr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokens;
|
return tokens;
|
||||||
@@ -197,9 +199,9 @@ static struct ucl_object *ucl_parse_tokens_recursive(struct ucl_object **token_i
|
|||||||
// parse_tokens_recursive -> error on EOF)
|
// parse_tokens_recursive -> error on EOF)
|
||||||
|
|
||||||
struct ucl_object *ucl_parse_tokens(struct ucl_object *tokens) {
|
struct ucl_object *ucl_parse_tokens(struct ucl_object *tokens) {
|
||||||
struct ucl_object* resultl = NULL;
|
struct ucl_object* result = ucl_nil_create();
|
||||||
|
struct ucl_object* result_tail = result;
|
||||||
struct ucl_object** token_iter = &tokens;
|
struct ucl_object** token_iter = &tokens;
|
||||||
struct ucl_object** next_cell = &resultl;
|
|
||||||
|
|
||||||
while (*token_iter != NULL) {
|
while (*token_iter != NULL) {
|
||||||
struct ucl_object *new_sexp = ucl_parse_tokens_recursive(token_iter);
|
struct ucl_object *new_sexp = ucl_parse_tokens_recursive(token_iter);
|
||||||
@@ -207,25 +209,18 @@ struct ucl_object *ucl_parse_tokens(struct ucl_object *tokens) {
|
|||||||
return new_sexp;
|
return new_sexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
*next_cell = ucl_cell_create(new_sexp, NULL);
|
ucl_list_append(result_tail, new_sexp);
|
||||||
next_cell = &(*next_cell)->cell.cdr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultl == NULL) {
|
return result;
|
||||||
return ucl_cell_create(NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should the parse a single sexp (return the last-parsed position), or
|
// TODO: Should the parse a single sexp (return the last-parsed position), or
|
||||||
// all sexps in the source (return a list of sexps)?
|
// all sexps in the source (return a list of sexps)?
|
||||||
struct ucl_object *ucl_parse(const char *source) {
|
struct ucl_object *ucl_parse(const char *source) {
|
||||||
struct ucl_object *tokens = ucl_tokenize(source);
|
struct ucl_object *tokens = ucl_tokenize(source);
|
||||||
if (tokens == NULL) {
|
|
||||||
tokens = ucl_nil_create();
|
|
||||||
}
|
|
||||||
UCL_RET_IF_ERROR(tokens);
|
UCL_RET_IF_ERROR(tokens);
|
||||||
|
|
||||||
struct ucl_object *sexp = ucl_parse_tokens(tokens);
|
struct ucl_object *sexp = ucl_parse_tokens(tokens);
|
||||||
if (sexp == NULL) {
|
if (sexp == NULL) {
|
||||||
return ucl_nil_create();
|
return ucl_nil_create();
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ struct ucl_object *ucl_list_append(struct ucl_object *list, struct ucl_object *o
|
|||||||
|
|
||||||
if (list->cell.car == NULL) {
|
if (list->cell.car == NULL) {
|
||||||
list->cell.car = obj;
|
list->cell.car = obj;
|
||||||
return list;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (iter->cell.cdr != NULL) {
|
while (iter->cell.cdr != NULL) {
|
||||||
@@ -124,7 +124,7 @@ struct ucl_object *ucl_list_append(struct ucl_object *list, struct ucl_object *o
|
|||||||
}
|
}
|
||||||
iter->cell.cdr = ucl_cell_create(obj, NULL);
|
iter->cell.cdr = ucl_cell_create(obj, NULL);
|
||||||
|
|
||||||
return list;
|
return iter->cell.cdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ucl_print_obj(struct ucl_object *obj) {
|
void ucl_print_obj(struct ucl_object *obj) {
|
||||||
|
|||||||
@@ -42,23 +42,19 @@ void tearDown(void) {
|
|||||||
scope = NULL;
|
scope = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct ucl_object *eval (const char *code) {
|
static struct ucl_object *eval (const char *code) {
|
||||||
struct ucl_object *sexp = ucl_parse(code);
|
struct ucl_object *sexp = ucl_parse(code);
|
||||||
return ucl_evaluate(scope, ucl_car(sexp));
|
return ucl_evaluate(scope, ucl_car(sexp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_simple_add(void) {
|
void test_simple_add(void) {
|
||||||
ucl_scope_put(scope, "+", ucl_builtin_create(ucl_builtin_add));
|
|
||||||
response = eval("(+ 2 3)");
|
response = eval("(+ 2 3)");
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 5);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_simple_let(void) {
|
void test_simple_let(void) {
|
||||||
response = eval("(let ((x 2)) (+ x 3))");
|
response = eval("(let ((x 2)) (+ x 3))");
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 5);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_let_assignment_error(void) {
|
void test_let_assignment_error(void) {
|
||||||
@@ -68,8 +64,7 @@ void test_let_assignment_error(void) {
|
|||||||
|
|
||||||
void test_nested_let(void) {
|
void test_nested_let(void) {
|
||||||
response = eval("(let ((x 2)) (let ((y 5)) (+ x y)))");
|
response = eval("(let ((x 2)) (let ((y 5)) (+ x y)))");
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 7);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nested_let_scope(void) {
|
void test_nested_let_scope(void) {
|
||||||
@@ -79,33 +74,28 @@ void test_nested_let_scope(void) {
|
|||||||
|
|
||||||
void test_multi_let(void) {
|
void test_multi_let(void) {
|
||||||
response = eval("(let ((x 2)(y 5)) (+ x y))");
|
response = eval("(let ((x 2)(y 5)) (+ x y))");
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 7);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_let_return_sym(void) {
|
void test_let_return_sym(void) {
|
||||||
response = eval("(let ((x 2)) x)");
|
response = eval("(let ((x 2)) x)");
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 2);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_eval_int(void) {
|
void test_eval_int(void) {
|
||||||
response = eval("2");
|
response = eval("2");
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 2);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_eval_string(void) {
|
void test_eval_string(void) {
|
||||||
response = eval("\"foo\"");
|
response = eval("\"foo\"");
|
||||||
TEST_ASSERT_OBJ_STRING(response);
|
TEST_ASSERT_OBJ_STRING_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL_STRING(response->string, "foo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_eval_sym_defined(void) {
|
void test_eval_sym_defined(void) {
|
||||||
ucl_scope_put(scope, "foo", ucl_int_create(2));
|
ucl_scope_put(scope, "foo", ucl_int_create(2));
|
||||||
response = eval("foo");
|
response = eval("foo");
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 2);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_eval_sym_undefined(void) {
|
void test_eval_sym_undefined(void) {
|
||||||
@@ -133,8 +123,7 @@ void test_eval_list(void) {
|
|||||||
void test_eval_defun(void) {
|
void test_eval_defun(void) {
|
||||||
response = eval("(defun foo (a b) (+ a b))");
|
response = eval("(defun foo (a b) (+ a b))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_SYMBOL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL_STRING(response->symbol, "foo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_call_function(void) {
|
void test_call_function(void) {
|
||||||
@@ -152,44 +141,37 @@ void test_call_function(void) {
|
|||||||
void test_setq(void) {
|
void test_setq(void) {
|
||||||
response = eval("(setq bar 123)");
|
response = eval("(setq bar 123)");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 123);
|
||||||
TEST_ASSERT_EQUAL(response->symbol, 123);
|
|
||||||
|
|
||||||
response = eval("bar");
|
response = eval("bar");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 123);
|
||||||
TEST_ASSERT_EQUAL(response->symbol, 123);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_setq_from_function(void) {
|
void test_setq_from_function(void) {
|
||||||
response = eval("(defun foo (a) (setq bar a))");
|
response = eval("(defun foo (a) (setq bar a))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_SYMBOL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL_STRING(response->symbol, "foo");
|
|
||||||
|
|
||||||
response = eval("(foo 2)");
|
response = eval("(foo 2)");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 2);
|
||||||
TEST_ASSERT_EQUAL(response->symbol, 2);
|
|
||||||
|
|
||||||
response = eval("bar");
|
response = eval("bar");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 2);
|
||||||
TEST_ASSERT_EQUAL(response->symbol, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_lambda(void) {
|
void test_lambda(void) {
|
||||||
response = eval("((lambda (x) (+ x 2)) 2)");
|
response = eval("((lambda (x) (+ x 2)) 2)");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 4);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_mapcar_lambda(void) {
|
void test_mapcar_lambda(void) {
|
||||||
response = eval("(car (mapcar (quote (lambda (x) (+ x 2))) (list 5)))");
|
response = eval("(car (mapcar (quote (lambda (x) (+ x 2))) (list 5)))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 7);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_mapcar_function(void) {
|
void test_mapcar_function(void) {
|
||||||
@@ -200,36 +182,31 @@ void test_mapcar_function(void) {
|
|||||||
|
|
||||||
response = eval("(car (mapcar (quote foo) (list 5)))");
|
response = eval("(car (mapcar (quote foo) (list 5)))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 7);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_car(void) {
|
void test_car(void) {
|
||||||
response = eval("(car (list 2 3 4))");
|
response = eval("(car (list 2 3 4))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 2);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_cdr(void) {
|
void test_cdr(void) {
|
||||||
response = eval("(car (cdr (list 2 3 4)))");
|
response = eval("(car (cdr (list 2 3 4)))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 3);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nth_0(void) {
|
void test_nth_0(void) {
|
||||||
response = eval("(nth 0 (list 2 3 4))");
|
response = eval("(nth 0 (list 2 3 4))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 2);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nth_1(void) {
|
void test_nth_1(void) {
|
||||||
response = eval("(nth 1 (list 2 3 4))");
|
response = eval("(nth 1 (list 2 3 4))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 3);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nth_oob(void) {
|
void test_nth_oob(void) {
|
||||||
@@ -241,16 +218,12 @@ void test_nth_oob(void) {
|
|||||||
void test_eval_defun_gc(void) {
|
void test_eval_defun_gc(void) {
|
||||||
response = eval("(defun foo (a b) (+ a b))");
|
response = eval("(defun foo (a b) (+ a b))");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_SYMBOL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL_STRING(response->symbol, "foo");
|
|
||||||
|
|
||||||
ucl_gc();
|
ucl_gc();
|
||||||
|
|
||||||
response = eval("(foo 10 15)");
|
response = eval("(foo 10 15)");
|
||||||
|
|
||||||
TEST_ASSERT_OBJ_INT(response);
|
TEST_ASSERT_OBJ_INT_V(response, 25);
|
||||||
TEST_ASSERT_EQUAL(response->integer, 25);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|||||||
@@ -43,11 +43,7 @@ static void test_token_next_lparen(void) {
|
|||||||
const char *curr = input;
|
const char *curr = input;
|
||||||
|
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
TEST_ASSERT_OBJ_SYMBOL_V(response, "(");
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_SYMBOL, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING("(", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL('\0', *curr);
|
TEST_ASSERT_EQUAL('\0', *curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,10 +53,7 @@ static void test_token_next_rparen(void) {
|
|||||||
|
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, ")");
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_SYMBOL, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING(")", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL('\0', *curr);
|
TEST_ASSERT_EQUAL('\0', *curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,19 +63,12 @@ static void test_token_next_lrparen(void) {
|
|||||||
|
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, "(");
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_SYMBOL, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING("(", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL(')', *curr);
|
|
||||||
|
|
||||||
ucl_object_delete(response);
|
ucl_object_delete(response);
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, ")");
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_SYMBOL, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING(")", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL('\0', *curr);
|
TEST_ASSERT_EQUAL('\0', *curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,10 +78,7 @@ static void test_token_next_string(void) {
|
|||||||
|
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
TEST_ASSERT_OBJ_STRING_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_STRING, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING("foo", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL('\0', *curr);
|
TEST_ASSERT_EQUAL('\0', *curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,10 +88,7 @@ static void test_token_next_string_w_whitespace(void) {
|
|||||||
|
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
TEST_ASSERT_OBJ_STRING_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_STRING, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING("foo", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL_STRING(" ", curr);
|
TEST_ASSERT_EQUAL_STRING(" ", curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +98,7 @@ static void test_token_next_symbol(void) {
|
|||||||
|
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_SYMBOL, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING("foo", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL_STRING("", curr);
|
TEST_ASSERT_EQUAL_STRING("", curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,17 +108,14 @@ static void test_token_next_symbol_w_whitespace(void) {
|
|||||||
|
|
||||||
response = ucl_token_next(&curr);
|
response = ucl_token_next(&curr);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(response);
|
TEST_ASSERT_OBJ_SYMBOL_V(response, "foo");
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_CELL, response->type);
|
|
||||||
TEST_ASSERT_EQUAL(UCL_TYPE_SYMBOL, response->cell.car->type);
|
|
||||||
TEST_ASSERT_EQUAL_STRING("foo", response->cell.car->string);
|
|
||||||
TEST_ASSERT_EQUAL_STRING(" ", curr);
|
TEST_ASSERT_EQUAL_STRING(" ", curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_tokenize_empty_str(void) {
|
static void test_tokenize_empty_str(void) {
|
||||||
response = ucl_tokenize("");
|
response = ucl_tokenize("");
|
||||||
|
|
||||||
TEST_ASSERT_NULL(response);
|
TEST_ASSERT_NIL(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_tokenize_nil(void) {
|
static void test_tokenize_nil(void) {
|
||||||
|
|||||||
@@ -4,26 +4,48 @@
|
|||||||
#include <unity.h>
|
#include <unity.h>
|
||||||
|
|
||||||
#include "uclisp.h"
|
#include "uclisp.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
#define TEST_ASSERT_OBJ_ERROR(obj) \
|
#define TEST_ASSERT_OBJ_ERROR(obj) \
|
||||||
TEST_ASSERT_EQUAL(obj->type, UCL_TYPE_ERROR)
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_ERROR, (obj)->type, "Expected error type")
|
||||||
|
|
||||||
#define TEST_ASSERT_OBJ_SYMBOL(obj) \
|
#define TEST_ASSERT_OBJ_SYMBOL(obj) \
|
||||||
TEST_ASSERT_EQUAL(obj->type, UCL_TYPE_SYMBOL)
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_SYMBOL, (obj)->type, "Expected symbol type")
|
||||||
|
|
||||||
#define TEST_ASSERT_OBJ_STRING(obj) \
|
#define TEST_ASSERT_OBJ_SYMBOL_V(obj, value) \
|
||||||
TEST_ASSERT_EQUAL(obj->type, UCL_TYPE_STRING)
|
do { \
|
||||||
|
TEST_ASSERT_NOT_NULL(obj); \
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_SYMBOL, (obj)->type, "Expected symbol type"); \
|
||||||
|
TEST_ASSERT_EQUAL_STRING((obj)->symbol, value); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define TEST_ASSERT_OBJ_INT(obj) \
|
#define TEST_ASSERT_OBJ_STRING(obj) \
|
||||||
TEST_ASSERT_EQUAL(obj->type, UCL_TYPE_INT)
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_STRING, (obj)->type, "Expected string type")
|
||||||
|
|
||||||
#define TEST_ASSERT_OBJ_LIST(obj) \
|
#define TEST_ASSERT_OBJ_STRING_V(obj, value) \
|
||||||
TEST_ASSERT_EQUAL(obj->type, UCL_TYPE_CELL)
|
do { \
|
||||||
|
TEST_ASSERT_NOT_NULL(obj); \
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_STRING, (obj)->type, "Expected string type"); \
|
||||||
|
TEST_ASSERT_EQUAL_STRING((obj)->string, value); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TEST_ASSERT_OBJ_INT(obj) \
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_INT, (obj)->type, "Expected int type")
|
||||||
|
|
||||||
|
#define TEST_ASSERT_OBJ_INT_V(obj, value) \
|
||||||
|
do { \
|
||||||
|
TEST_ASSERT_NOT_NULL(obj); \
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_INT, (obj)->type, "Expected int type"); \
|
||||||
|
TEST_ASSERT_EQUAL(value, (obj)->integer); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TEST_ASSERT_OBJ_LIST(obj) \
|
||||||
|
TEST_ASSERT_EQUAL_MESSAGE(UCL_TYPE_CELL, obj->type, "Expected cell type")
|
||||||
|
|
||||||
#define TEST_ASSERT_LIST_LEN(list, len) \
|
#define TEST_ASSERT_LIST_LEN(list, len) \
|
||||||
do { \
|
do { \
|
||||||
TEST_ASSERT_OBJ_LIST(list); \
|
TEST_ASSERT_OBJ_LIST(list); \
|
||||||
TEST_ASSERT_EQUAL(ucl_list_length(list)->integer, len); \
|
TEST_ASSERT_EQUAL(len, ucl_list_length(list)->integer); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define TEST_ASSERT_NIL(obj) \
|
#define TEST_ASSERT_NIL(obj) \
|
||||||
|
|||||||
Reference in New Issue
Block a user