|
|
|
@@ -54,6 +54,13 @@ |
|
|
|
return fail; \ |
|
|
|
} |
|
|
|
|
|
|
|
#define assert_equal_type(node, _type) \ |
|
|
|
if (node->type != _type) { \ |
|
|
|
print_assert_equal_fail( \ |
|
|
|
Ast_Node_Type_to_string(node->type), \ |
|
|
|
Ast_Node_Type_to_string(_type), char*, "%s"); \ |
|
|
|
return fail; \ |
|
|
|
} \ |
|
|
|
|
|
|
|
#define assert_null(variable) \ |
|
|
|
assert_equal_int(variable, nullptr) |
|
|
|
@@ -61,7 +68,6 @@ |
|
|
|
#define assert_not_null(variable) \ |
|
|
|
assert_not_equal_int(variable, nullptr) |
|
|
|
|
|
|
|
|
|
|
|
#define invoke_test(name) \ |
|
|
|
printf("" #name ":"); \ |
|
|
|
if (name() == pass) { \ |
|
|
|
@@ -88,26 +94,26 @@ testresult test_eval_operands() { |
|
|
|
assert_no_error(error); |
|
|
|
assert_equal_int(list_length(operands), 4); |
|
|
|
|
|
|
|
assert_equal_int(operands->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(operands->value.pair->first->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_int(operands->value.pair->first->value.number->value, 1); |
|
|
|
assert_equal_type(operands, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(operands->value.pair->first->value.number->value, 1); |
|
|
|
|
|
|
|
operands = operands->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(operands->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(operands->value.pair->first->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_int(operands->value.pair->first->value.number->value, 3); |
|
|
|
assert_equal_type(operands, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(operands->value.pair->first->value.number->value, 3); |
|
|
|
|
|
|
|
operands = operands->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(operands->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(operands->value.pair->first->type, Ast_Node_Type_String); |
|
|
|
assert_equal_type(operands, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(operands->value.pair->first, Ast_Node_Type_String); |
|
|
|
assert_equal_string(operands->value.pair->first->value.string->value, "okay"); |
|
|
|
|
|
|
|
operands = operands->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(operands->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(operands->value.pair->first->type, Ast_Node_Type_Keyword); |
|
|
|
assert_equal_type(operands, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(operands->value.pair->first, Ast_Node_Type_Keyword); |
|
|
|
assert_equal_string(operands->value.pair->first->value.keyword->identifier, "haha"); |
|
|
|
|
|
|
|
return pass; |
|
|
|
@@ -123,46 +129,47 @@ testresult test_parse_atom() { |
|
|
|
|
|
|
|
// test numbers |
|
|
|
Ast_Node* result = parse_atom(string, &index_in_text); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
|
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 123); |
|
|
|
|
|
|
|
++index_in_text; |
|
|
|
|
|
|
|
result = parse_atom(string, &index_in_text); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, -1.23e-2); |
|
|
|
|
|
|
|
// test strings |
|
|
|
++index_in_text; |
|
|
|
|
|
|
|
result = parse_atom(string, &index_in_text); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_String); |
|
|
|
assert_equal_type(result, Ast_Node_Type_String); |
|
|
|
assert_equal_string(result->value.string->value, "asd"); |
|
|
|
|
|
|
|
// test keywords |
|
|
|
++index_in_text; |
|
|
|
|
|
|
|
result = parse_atom(string, &index_in_text); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Keyword); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Keyword); |
|
|
|
assert_equal_string(result->value.keyword->identifier, "key1"); |
|
|
|
|
|
|
|
++index_in_text; |
|
|
|
|
|
|
|
result = parse_atom(string, &index_in_text); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Keyword); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Keyword); |
|
|
|
assert_equal_string(result->value.keyword->identifier, "key:2"); |
|
|
|
|
|
|
|
// test symbols |
|
|
|
++index_in_text; |
|
|
|
|
|
|
|
result = parse_atom(string, &index_in_text); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_string(result->value.symbol->identifier, "sym"); |
|
|
|
|
|
|
|
++index_in_text; |
|
|
|
|
|
|
|
result = parse_atom(string, &index_in_text); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_string(result->value.symbol->identifier, "+"); |
|
|
|
|
|
|
|
return pass; |
|
|
|
@@ -175,25 +182,25 @@ testresult test_parse_expression() { |
|
|
|
Ast_Node* result = parse_expression(string, &index_in_text); |
|
|
|
assert_no_error(error); |
|
|
|
|
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(result->value.pair->first->type, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); |
|
|
|
|
|
|
|
result = result->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(result->value.pair->first->type, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_string(result->value.pair->first->value.symbol->identifier, "+"); |
|
|
|
|
|
|
|
result = result->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(result->value.pair->first->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(result->value.pair->first, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.pair->first->value.number->value, 12); |
|
|
|
|
|
|
|
result = result->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Nil); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Nil); |
|
|
|
|
|
|
|
char string2[] = "(define fun (lambda (x) (+ 5 (* x x ))))"; |
|
|
|
index_in_text = 0; |
|
|
|
@@ -201,26 +208,25 @@ testresult test_parse_expression() { |
|
|
|
result = parse_expression(string2, &index_in_text); |
|
|
|
assert_no_error(error); |
|
|
|
|
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(result->value.pair->first->type, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_string(result->value.pair->first->value.symbol->identifier, "define"); |
|
|
|
|
|
|
|
result = result->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(result->value.pair->first->type, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); |
|
|
|
|
|
|
|
result = result->value.pair->rest; |
|
|
|
|
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(result->value.pair->first->type, Ast_Node_Type_Pair); |
|
|
|
assert_equal_int(result->value.pair->first->value.pair->first->type, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(result->value.pair->first, Ast_Node_Type_Pair); |
|
|
|
assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_Type_Symbol); |
|
|
|
assert_equal_string(result->value.pair->first->value.pair->first->value.symbol->identifier, "lambda"); |
|
|
|
|
|
|
|
result = result->value.pair->rest; |
|
|
|
|
|
|
|
|
|
|
|
return pass; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -231,7 +237,7 @@ testresult test_built_in_add() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 14); |
|
|
|
|
|
|
|
return pass; |
|
|
|
@@ -244,7 +250,7 @@ testresult test_built_in_substract() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 6); |
|
|
|
|
|
|
|
return pass; |
|
|
|
@@ -258,7 +264,7 @@ testresult test_built_in_multiply() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 40); |
|
|
|
|
|
|
|
return pass; |
|
|
|
@@ -272,7 +278,7 @@ testresult test_built_in_divide() { |
|
|
|
|
|
|
|
assert_null(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 5); |
|
|
|
|
|
|
|
return pass; |
|
|
|
@@ -286,7 +292,7 @@ testresult test_built_in_if() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 4); |
|
|
|
|
|
|
|
char exp_string2[] = "(if () 4 5)"; |
|
|
|
@@ -295,7 +301,7 @@ testresult test_built_in_if() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 5); |
|
|
|
|
|
|
|
return pass; |
|
|
|
@@ -308,7 +314,7 @@ testresult test_built_in_and() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 1); |
|
|
|
|
|
|
|
// a false case |
|
|
|
@@ -318,7 +324,7 @@ testresult test_built_in_and() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Nil); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Nil); |
|
|
|
|
|
|
|
return pass; |
|
|
|
} |
|
|
|
@@ -330,7 +336,7 @@ testresult test_built_in_or() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 1); |
|
|
|
|
|
|
|
// a false case |
|
|
|
@@ -340,7 +346,7 @@ testresult test_built_in_or() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Nil); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Nil); |
|
|
|
|
|
|
|
return pass; |
|
|
|
} |
|
|
|
@@ -354,7 +360,7 @@ testresult test_built_in_not() { |
|
|
|
// a true case |
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Number); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Number); |
|
|
|
assert_equal_double(result->value.number->value, 1); |
|
|
|
|
|
|
|
// a false case |
|
|
|
@@ -364,7 +370,7 @@ testresult test_built_in_not() { |
|
|
|
|
|
|
|
assert_no_error(error); |
|
|
|
assert_not_null(result); |
|
|
|
assert_equal_int(result->type, Ast_Node_Type_Nil); |
|
|
|
assert_equal_type(result, Ast_Node_Type_Nil); |
|
|
|
|
|
|
|
return pass; |
|
|
|
} |
|
|
|
@@ -389,5 +395,4 @@ void run_all_tests() { |
|
|
|
invoke_test(test_built_in_or); |
|
|
|
invoke_test(test_built_in_not); |
|
|
|
|
|
|
|
|
|
|
|
} |