mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Implemented some tests, not finished yet
* parser compounds * routine keyword assert
This commit is contained in:
@@ -456,7 +456,112 @@ int test_binary(Toy_Bucket** bucketHandle) {
|
||||
}
|
||||
|
||||
int test_compound(Toy_Bucket** bucketHandle) {
|
||||
//TODO: implement test_compound()
|
||||
//test collections (do it first, because it's used below)
|
||||
{
|
||||
char* source = "1, 2, 3;";
|
||||
Toy_Ast* ast = makeAstFromSource(bucketHandle, source);
|
||||
|
||||
//check if it worked
|
||||
if (
|
||||
ast == NULL ||
|
||||
ast->type != TOY_AST_BLOCK ||
|
||||
ast->block.child == NULL ||
|
||||
|
||||
ast->block.child->type != TOY_AST_COMPOUND ||
|
||||
ast->block.child->compound.flag != TOY_AST_FLAG_COMPOUND_COLLECTION ||
|
||||
|
||||
ast->block.child->compound.left == NULL ||
|
||||
ast->block.child->compound.left->type != TOY_AST_VALUE ||
|
||||
TOY_VALUE_IS_INTEGER(ast->block.child->compound.left->value.value) != true ||
|
||||
TOY_VALUE_AS_INTEGER(ast->block.child->compound.left->value.value) != 1 ||
|
||||
|
||||
ast->block.child->compound.right == NULL ||
|
||||
ast->block.child->compound.right->type != TOY_AST_COMPOUND ||
|
||||
ast->block.child->compound.right->compound.flag != TOY_AST_FLAG_COMPOUND_COLLECTION ||
|
||||
|
||||
ast->block.child->compound.right->compound.left == NULL ||
|
||||
ast->block.child->compound.right->compound.left->type != TOY_AST_VALUE ||
|
||||
TOY_VALUE_IS_INTEGER(ast->block.child->compound.right->compound.left->value.value) != true ||
|
||||
TOY_VALUE_AS_INTEGER(ast->block.child->compound.right->compound.left->value.value) != 2 ||
|
||||
|
||||
ast->block.child->compound.right->compound.right == NULL ||
|
||||
ast->block.child->compound.right->compound.right->type != TOY_AST_VALUE ||
|
||||
TOY_VALUE_IS_INTEGER(ast->block.child->compound.right->compound.right->value.value) != true ||
|
||||
TOY_VALUE_AS_INTEGER(ast->block.child->compound.right->compound.right->value.value) != 3 ||
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser, source: %s\n" TOY_CC_RESET, source);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//test index
|
||||
{
|
||||
char* source = "name[0];";
|
||||
Toy_Ast* ast = makeAstFromSource(bucketHandle, source);
|
||||
|
||||
//check if it worked
|
||||
if (
|
||||
ast == NULL ||
|
||||
ast->type != TOY_AST_BLOCK ||
|
||||
ast->block.child == NULL ||
|
||||
|
||||
ast->block.child->type != TOY_AST_COMPOUND ||
|
||||
ast->block.child->compound.flag != TOY_AST_FLAG_COMPOUND_INDEX ||
|
||||
|
||||
ast->block.child->compound.left == NULL ||
|
||||
ast->block.child->compound.left->type != TOY_AST_VAR_ACCESS ||
|
||||
ast->block.child->compound.left->varAccess.name->type != TOY_STRING_NAME ||
|
||||
strcmp(ast->block.child->compound.left->varAccess.name->as.name.data, "name") != 0 ||
|
||||
|
||||
ast->block.child->compound.right->type != TOY_AST_VALUE ||
|
||||
TOY_VALUE_IS_INTEGER(ast->block.child->compound.right->value.value) != true ||
|
||||
TOY_VALUE_AS_INTEGER(ast->block.child->compound.right->value.value) != 0 ||
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser, source: %s\n" TOY_CC_RESET, source);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//test index, length
|
||||
{
|
||||
char* source = "name[0, 1];";
|
||||
Toy_Ast* ast = makeAstFromSource(bucketHandle, source);
|
||||
|
||||
//check if it worked
|
||||
if (
|
||||
ast == NULL ||
|
||||
ast->type != TOY_AST_BLOCK ||
|
||||
ast->block.child == NULL ||
|
||||
|
||||
ast->block.child->type != TOY_AST_COMPOUND ||
|
||||
ast->block.child->compound.flag != TOY_AST_FLAG_COMPOUND_INDEX ||
|
||||
|
||||
ast->block.child->compound.left == NULL ||
|
||||
ast->block.child->compound.left->type != TOY_AST_VAR_ACCESS ||
|
||||
ast->block.child->compound.left->varAccess.name->type != TOY_STRING_NAME ||
|
||||
strcmp(ast->block.child->compound.left->varAccess.name->as.name.data, "name") != 0 ||
|
||||
|
||||
ast->block.child->compound.right->type != TOY_AST_COMPOUND ||
|
||||
ast->block.child->compound.right->compound.flag != TOY_AST_FLAG_COMPOUND_COLLECTION ||
|
||||
ast->block.child->compound.right->compound.left->type != TOY_AST_VALUE ||
|
||||
|
||||
TOY_VALUE_IS_INTEGER(ast->block.child->compound.right->compound.left->value.value) != true ||
|
||||
TOY_VALUE_AS_INTEGER(ast->block.child->compound.right->compound.left->value.value) != 0 ||
|
||||
|
||||
TOY_VALUE_IS_INTEGER(ast->block.child->compound.right->compound.right->value.value) != true ||
|
||||
TOY_VALUE_AS_INTEGER(ast->block.child->compound.right->compound.right->value.value) != 1 ||
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to run the parser, source: %s\n" TOY_CC_RESET, source);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -719,9 +719,131 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
}
|
||||
|
||||
int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
//TODO: implement assert
|
||||
//TODO: implement if-then
|
||||
//TODO: implement if-then-else
|
||||
//assert
|
||||
{
|
||||
//setup
|
||||
const char* source = "assert true;";
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
|
||||
Toy_bindLexer(&lexer, source);
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
void* buffer = Toy_compileRoutine(ast);
|
||||
int len = ((int*)buffer)[0];
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 36 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //data count
|
||||
(ptr++)[0] != 0) //subs count
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check code
|
||||
if (*((unsigned char*)(buffer + 24)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(buffer + 25)) != TOY_VALUE_BOOLEAN ||
|
||||
*((bool*)(buffer + 26)) != true || //bools are packed
|
||||
*((unsigned char*)(buffer + 27)) != 0 ||
|
||||
|
||||
*((unsigned char*)(buffer + 28)) != TOY_OPCODE_ASSERT ||
|
||||
*((unsigned char*)(buffer + 29)) != 1 || //one parameter
|
||||
*((unsigned char*)(buffer + 30)) != 0 ||
|
||||
*((unsigned char*)(buffer + 31)) != 0 ||
|
||||
|
||||
*((unsigned char*)(buffer + 32)) != TOY_OPCODE_RETURN ||
|
||||
*((unsigned char*)(buffer + 33)) != 0 ||
|
||||
*((unsigned char*)(buffer + 34)) != 0 ||
|
||||
*((unsigned char*)(buffer + 35)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//assert (with message)
|
||||
{
|
||||
//setup
|
||||
const char* source = "assert true, false;";
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
|
||||
Toy_bindLexer(&lexer, source);
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
void* buffer = Toy_compileRoutine(ast);
|
||||
int len = ((int*)buffer)[0];
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 40 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //data count
|
||||
(ptr++)[0] != 0) //subs count
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check code
|
||||
if (*((unsigned char*)(buffer + 24)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(buffer + 25)) != TOY_VALUE_BOOLEAN ||
|
||||
*((bool*)(buffer + 26)) != true || //bools are packed
|
||||
*((unsigned char*)(buffer + 27)) != 0 ||
|
||||
|
||||
*((unsigned char*)(buffer + 28)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(buffer + 29)) != TOY_VALUE_BOOLEAN ||
|
||||
*((bool*)(buffer + 30)) != false || //bools are packed
|
||||
*((unsigned char*)(buffer + 31)) != 0 ||
|
||||
|
||||
*((unsigned char*)(buffer + 32)) != TOY_OPCODE_ASSERT ||
|
||||
*((unsigned char*)(buffer + 33)) != 2 || //two parameters
|
||||
*((unsigned char*)(buffer + 34)) != 0 ||
|
||||
*((unsigned char*)(buffer + 35)) != 0 ||
|
||||
|
||||
*((unsigned char*)(buffer + 36)) != TOY_OPCODE_RETURN ||
|
||||
*((unsigned char*)(buffer + 37)) != 0 ||
|
||||
*((unsigned char*)(buffer + 38)) != 0 ||
|
||||
*((unsigned char*)(buffer + 39)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//TODO: implement test if-then
|
||||
//TODO: implement test if-then-else
|
||||
|
||||
//print
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user