mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Tests are passing, added preserveScope to VM API
This commit is contained in:
@@ -298,6 +298,8 @@ int repl(const char* filepath) {
|
||||
|
||||
printf("%s> ", prompt); //shows the terminal prompt and begin
|
||||
|
||||
unsigned int runCount = 0; //used for initial preserveScope
|
||||
|
||||
//read from the terminal
|
||||
while(fgets(inputBuffer, INPUT_BUFFER_SIZE, stdin)) {
|
||||
//work around fgets() adding a newline
|
||||
@@ -332,13 +334,13 @@ int repl(const char* filepath) {
|
||||
|
||||
void* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
Toy_bindVM(&vm, &module);
|
||||
Toy_bindVM(&vm, &module, runCount++ > 0);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
|
||||
//free the memory, and leave the VM ready for the next loop
|
||||
Toy_resetVM(&vm);
|
||||
Toy_resetVM(&vm, true);
|
||||
free(buffer);
|
||||
|
||||
printf("%s> ", prompt); //shows the terminal prompt
|
||||
@@ -488,7 +490,7 @@ int main(int argc, const char* argv[]) {
|
||||
Toy_initVM(&vm);
|
||||
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
Toy_bindVM(&vm, &module);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
Toy_runVM(&vm);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Toy_Module Toy_parseModule(unsigned char* ptr) {
|
||||
|
||||
//header
|
||||
readUnsignedInt(&ptr);
|
||||
// module.codeCount = readUnsignedInt(&ptr); NOTE: note used
|
||||
|
||||
module.jumpsCount = readUnsignedInt(&ptr);
|
||||
module.paramCount = readUnsignedInt(&ptr);
|
||||
module.dataCount = readUnsignedInt(&ptr);
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
//utils
|
||||
static void expand(Toy_ModuleBundle* bundle, unsigned int amount) {
|
||||
if (bundle->count + amount > bundle->capacity) {
|
||||
bundle->capacity = 0;
|
||||
bundle->capacity = 8; //DON'T bitshift zero
|
||||
|
||||
while (bundle->count + amount > bundle->capacity) { //expand as much as needed
|
||||
bundle->capacity >>= 2;
|
||||
bundle->capacity <<= 2;
|
||||
}
|
||||
|
||||
bundle->ptr = realloc(bundle->ptr, bundle->capacity);
|
||||
|
||||
@@ -12,7 +12,7 @@ typedef struct Toy_ModuleBundle {
|
||||
|
||||
//create a bundle
|
||||
TOY_API void Toy_initModuleBundle(Toy_ModuleBundle* bundle);
|
||||
TOY_API void Toy_appendModuleBundle(Toy_ModuleBundle* bundle, Toy_Ast* ast);
|
||||
TOY_API void Toy_appendModuleBundle(Toy_ModuleBundle* bundle, Toy_Ast* ast); //TODO: raw bytes
|
||||
TOY_API void Toy_freeModuleBundle(Toy_ModuleBundle* bundle);
|
||||
|
||||
//load module bundle with external data (makes an internal copy)
|
||||
|
||||
@@ -939,7 +939,7 @@ static void process(Toy_VM* vm) {
|
||||
}
|
||||
|
||||
//exposed functions
|
||||
void Toy_resetVM(Toy_VM* vm) {
|
||||
void Toy_resetVM(Toy_VM* vm, bool preserveScope) {
|
||||
vm->code = NULL;
|
||||
|
||||
vm->jumpsCount = 0;
|
||||
@@ -957,7 +957,11 @@ void Toy_resetVM(Toy_VM* vm) {
|
||||
|
||||
Toy_resetStack(&vm->stack);
|
||||
|
||||
//NOTE: scope and buckets are not altered during resets
|
||||
if (preserveScope == false) {
|
||||
vm->scope = Toy_popScope(vm->scope);
|
||||
}
|
||||
|
||||
//NOTE: buckets are not altered during resets
|
||||
}
|
||||
|
||||
void Toy_initVM(Toy_VM* vm) {
|
||||
@@ -967,7 +971,7 @@ void Toy_initVM(Toy_VM* vm) {
|
||||
vm->stringBucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
vm->scopeBucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
|
||||
Toy_resetVM(vm);
|
||||
Toy_resetVM(vm, true);
|
||||
}
|
||||
|
||||
void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent) {
|
||||
@@ -979,10 +983,10 @@ void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent) {
|
||||
|
||||
//TODO: parent bucket pointers are updated after function calls
|
||||
|
||||
Toy_resetVM(vm);
|
||||
Toy_resetVM(vm, true);
|
||||
}
|
||||
|
||||
void Toy_bindVM(Toy_VM* vm, Toy_Module* module) {
|
||||
void Toy_bindVM(Toy_VM* vm, Toy_Module* module, bool preserveScope) {
|
||||
vm->code = module->code;
|
||||
|
||||
vm->jumpsCount = module->jumpsCount;
|
||||
@@ -996,7 +1000,9 @@ void Toy_bindVM(Toy_VM* vm, Toy_Module* module) {
|
||||
vm->dataAddr = module->dataAddr;
|
||||
vm->subsAddr = module->subsAddr;
|
||||
|
||||
vm->scope = Toy_pushScope(&vm->scopeBucket, module->scopePtr); //new scope for the upcoming run
|
||||
if (preserveScope == false) {
|
||||
vm->scope = Toy_pushScope(&vm->scopeBucket, module->scopePtr);
|
||||
}
|
||||
}
|
||||
|
||||
void Toy_runVM(Toy_VM* vm) {
|
||||
@@ -1017,9 +1023,7 @@ void Toy_runVM(Toy_VM* vm) {
|
||||
}
|
||||
|
||||
void Toy_freeVM(Toy_VM* vm) {
|
||||
Toy_resetVM(vm);
|
||||
|
||||
Toy_popScope(vm->scope);
|
||||
Toy_resetVM(vm, false);
|
||||
|
||||
//clear the persistent memory
|
||||
Toy_freeStack(vm->stack);
|
||||
|
||||
@@ -42,12 +42,12 @@ typedef struct Toy_VM {
|
||||
Toy_Bucket* scopeBucket; //stores the scope instances TODO: is this separation needed?
|
||||
} Toy_VM;
|
||||
|
||||
TOY_API void Toy_resetVM(Toy_VM* vm); //persists memory
|
||||
TOY_API void Toy_resetVM(Toy_VM* vm, bool preserveScope);
|
||||
|
||||
TOY_API void Toy_initVM(Toy_VM* vm); //creates memory
|
||||
TOY_API void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent); //inherits memory
|
||||
|
||||
TOY_API void Toy_bindVM(Toy_VM* vm, Toy_Module* module);
|
||||
TOY_API void Toy_bindVM(Toy_VM* vm, Toy_Module* module, bool preserveScope);
|
||||
TOY_API void Toy_runVM(Toy_VM* vm);
|
||||
|
||||
TOY_API void Toy_freeVM(Toy_VM* vm);
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
#include "toy_bytecode.h"
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include "toy_opcodes.h"
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//tests
|
||||
int test_bytecode_header(Toy_Bucket** bucketHandle) {
|
||||
//simple test to ensure the header looks right
|
||||
{
|
||||
//setup
|
||||
Toy_Ast* ast = NULL;
|
||||
Toy_private_emitAstPass(bucketHandle, &ast);
|
||||
|
||||
//run
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
|
||||
//check
|
||||
if (bc.ptr[0] != TOY_VERSION_MAJOR ||
|
||||
bc.ptr[1] != TOY_VERSION_MINOR ||
|
||||
bc.ptr[2] != TOY_VERSION_PATCH ||
|
||||
strcmp((char*)(bc.ptr + 3), TOY_VERSION_BUILD) != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to write the bytecode header correctly:\n" TOY_CC_RESET);
|
||||
fprintf(stderr, TOY_CC_ERROR "\t%d.%d.%d.%s\n" TOY_CC_RESET, (int)(bc.ptr[0]), (int)(bc.ptr[1]), (int)(bc.ptr[2]), (char*)(bc.ptr + 3));
|
||||
fprintf(stderr, TOY_CC_ERROR "\t%d.%d.%d.%s\n" TOY_CC_RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, TOY_VERSION_BUILD);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeBytecode(bc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bc.count % 4 != 0) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: bytecode size is not a multiple of 4, size is: %d\n" TOY_CC_RESET, (int)bc.count);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeBytecode(bc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
Toy_freeBytecode(bc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_bytecode_from_source(Toy_Bucket** bucketHandle) {
|
||||
{
|
||||
//setup
|
||||
const char* source = "(1 + 2) * (3 + 4);";
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
|
||||
Toy_bindLexer(&lexer, source);
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
|
||||
//check bytecode alignment
|
||||
if (bc.count % 4 != 0) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: bytecode alignment is not a multiple of 4 (size is %d), source: %s\n" TOY_CC_RESET, (int)bc.count, source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeBytecode(bc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check bytecode header
|
||||
if (bc.ptr[0] != TOY_VERSION_MAJOR ||
|
||||
bc.ptr[1] != TOY_VERSION_MINOR ||
|
||||
bc.ptr[2] != TOY_VERSION_PATCH ||
|
||||
strcmp((char*)(bc.ptr + 3), TOY_VERSION_BUILD) != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to write the bytecode header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeBytecode(bc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check contents of the routine (this is copy/pasted from test_routine.c, and tweaked with the offset)
|
||||
int offset = 3 + strlen(TOY_VERSION_BUILD) + 1;
|
||||
if (offset % 4 != 0) {
|
||||
offset += 4 - (offset % 4); //ceil
|
||||
}
|
||||
|
||||
int* ptr = (int*)(bc.ptr + offset);
|
||||
|
||||
if ((ptr++)[0] != 72 || //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 within bytecode, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeBytecode(bc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check code
|
||||
if (
|
||||
//left hand side
|
||||
*((unsigned char*)(offset + bc.ptr + 24)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(offset + bc.ptr + 25)) != TOY_VALUE_INTEGER ||
|
||||
*((unsigned char*)(offset + bc.ptr + 26)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 27)) != 0 ||
|
||||
*(int*)(offset + bc.ptr + 28) != 1 ||
|
||||
|
||||
*((unsigned char*)(offset + bc.ptr + 32)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(offset + bc.ptr + 33)) != TOY_VALUE_INTEGER ||
|
||||
*((unsigned char*)(offset + bc.ptr + 34)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 35)) != 0 ||
|
||||
*(int*)(offset + bc.ptr + 36) != 2 ||
|
||||
|
||||
*((unsigned char*)(offset + bc.ptr + 40)) != TOY_OPCODE_ADD ||
|
||||
*((unsigned char*)(offset + bc.ptr + 41)) != TOY_OPCODE_PASS ||
|
||||
*((unsigned char*)(offset + bc.ptr + 42)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 43)) != 0 ||
|
||||
|
||||
//right hand side
|
||||
*((unsigned char*)(offset + bc.ptr + 44)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(offset + bc.ptr + 45)) != TOY_VALUE_INTEGER ||
|
||||
*((unsigned char*)(offset + bc.ptr + 46)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 47)) != 0 ||
|
||||
*(int*)(offset + bc.ptr + 48) != 3 ||
|
||||
|
||||
*((unsigned char*)(offset + bc.ptr + 52)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(offset + bc.ptr + 53)) != TOY_VALUE_INTEGER ||
|
||||
*((unsigned char*)(offset + bc.ptr + 54)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 55)) != 0 ||
|
||||
*(int*)(offset + bc.ptr + 56) != 4 ||
|
||||
|
||||
*((unsigned char*)(offset + bc.ptr + 60)) != TOY_OPCODE_ADD ||
|
||||
*((unsigned char*)(offset + bc.ptr + 61)) != TOY_OPCODE_PASS ||
|
||||
*((unsigned char*)(offset + bc.ptr + 62)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 63)) != 0 ||
|
||||
|
||||
//multiply the two values
|
||||
*((unsigned char*)(offset + bc.ptr + 64)) != TOY_OPCODE_MULTIPLY ||
|
||||
*((unsigned char*)(offset + bc.ptr + 65)) != TOY_OPCODE_PASS ||
|
||||
*((unsigned char*)(offset + bc.ptr + 66)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 67)) != 0 ||
|
||||
|
||||
*((unsigned char*)(offset + bc.ptr + 68)) != TOY_OPCODE_RETURN ||
|
||||
*((unsigned char*)(offset + bc.ptr + 69)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 70)) != 0 ||
|
||||
*((unsigned char*)(offset + bc.ptr + 71)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code within bytecode, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeBytecode(bc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
Toy_freeBytecode(bc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
//run each test set, returning the total errors given
|
||||
int total = 0, res = 0;
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_bytecode_header(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
}
|
||||
total += res;
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_bytecode_from_source(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
}
|
||||
total += res;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "toy_routine.h"
|
||||
#include "toy_module_builder.h"
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include "toy_opcodes.h"
|
||||
@@ -9,8 +9,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//NOTE: This set of tests also covers 'Toy_Module'
|
||||
|
||||
//tests
|
||||
int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
int test_builder_expressions(Toy_Bucket** bucketHandle) {
|
||||
//simple test to ensure the header looks right with an empty ast
|
||||
{
|
||||
//setup
|
||||
@@ -18,18 +20,18 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
Toy_private_emitAstPass(bucketHandle, &ast);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 28 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //data count
|
||||
(ptr++)[0] != 0) //subs count
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, ast: PASS\n" TOY_CC_RESET);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, ast: PASS\n" TOY_CC_RESET);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -43,7 +45,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 27)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, ast: PASS\n" TOY_CC_RESET);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, ast: PASS\n" TOY_CC_RESET);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -66,18 +68,18 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 28 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -91,7 +93,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 27)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -114,18 +116,18 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 32 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -143,7 +145,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 31)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -166,18 +168,18 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 32 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -195,7 +197,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 31)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -218,18 +220,18 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//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 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -248,7 +250,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
*((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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -271,18 +273,18 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//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 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -301,7 +303,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
*((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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -324,26 +326,26 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* header = (int*)buffer;
|
||||
|
||||
if (header[0] != 64 || //total size
|
||||
header[1] != 0 || //param size
|
||||
header[2] != 4 || //jumps size
|
||||
header[1] != 4 || //jump size
|
||||
header[2] != 0 || //param size
|
||||
header[3] != 16 || //data size
|
||||
header[4] != 0 || //subs size
|
||||
|
||||
// header[??] != ?? || //params address
|
||||
header[5] != 32 || //code address
|
||||
header[6] != 44 || //jumps address
|
||||
header[6] != 44 || //jump address
|
||||
header[7] != 48 || //data address
|
||||
// header[??] != ?? || //subs address
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -367,7 +369,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -383,7 +385,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -399,7 +401,7 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine data, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder data, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -413,11 +415,11 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int test_routine_unary(Toy_Bucket** bucketHandle) {
|
||||
// int test_builder_unary(Toy_Bucket** bucketHandle) {
|
||||
// //Nothing produces a unary instruction yet
|
||||
// }
|
||||
|
||||
int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
int test_builder_binary(Toy_Bucket** bucketHandle) {
|
||||
//produce a simple algorithm
|
||||
{
|
||||
//setup
|
||||
@@ -430,18 +432,18 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 48 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -472,7 +474,7 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 47)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -495,18 +497,18 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 48 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -537,7 +539,7 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 47)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -560,18 +562,18 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 48 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -602,7 +604,7 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 47)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -625,18 +627,18 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 72 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -693,7 +695,7 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
*((unsigned char*)(buffer + 71)) != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -707,7 +709,7 @@ int test_routine_binary(Toy_Bucket** bucketHandle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
int test_builder_keywords(Toy_Bucket** bucketHandle) {
|
||||
//assert
|
||||
{
|
||||
//setup
|
||||
@@ -720,18 +722,18 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//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 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -755,7 +757,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
*((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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -778,18 +780,18 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//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 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -818,7 +820,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
*((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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -841,14 +843,14 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 76 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 4 || //jump count
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 12 || //data count
|
||||
(ptr++)[0] != 0 || //subs count
|
||||
|
||||
@@ -860,7 +862,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -908,7 +910,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -931,14 +933,14 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 116 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 8 || //jump count
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 28 || //data count
|
||||
(ptr++)[0] != 0 || //subs count
|
||||
|
||||
@@ -950,7 +952,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1022,7 +1024,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1045,18 +1047,18 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//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 || //param 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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1079,7 +1081,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
*((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);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1102,26 +1104,26 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* header = (int*)buffer;
|
||||
|
||||
if (header[0] != 64 || //total size
|
||||
header[1] != 0 || //param size
|
||||
header[2] != 4 || //jumps size
|
||||
header[1] != 4 || //jump size
|
||||
header[2] != 0 || //param size
|
||||
header[3] != 8 || //data size
|
||||
header[4] != 0 || //subs size
|
||||
|
||||
// header[??] != ?? || //params address
|
||||
header[5] != 32 || //code address
|
||||
header[6] != 52 || //jumps address
|
||||
header[6] != 52 || //jump address
|
||||
header[7] != 56 || //data address
|
||||
// header[??] != ?? || //subs address
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1154,7 +1156,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1170,7 +1172,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1186,7 +1188,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine data, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder data, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1209,26 +1211,26 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
unsigned char* buffer = Toy_compileRoutine(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
|
||||
//check header
|
||||
int* header = (int*)buffer;
|
||||
|
||||
if (header[0] != 64 || //total size
|
||||
header[1] != 0 || //param size
|
||||
header[2] != 4 || //jumps size
|
||||
header[1] != 4 || //jump size
|
||||
header[2] != 0 || //param size
|
||||
header[3] != 8 || //data size
|
||||
header[4] != 0 || //subs size
|
||||
|
||||
// header[??] != ?? || //params address
|
||||
header[5] != 32 || //code address
|
||||
header[6] != 52 || //jumps address
|
||||
header[6] != 52 || //jump address
|
||||
header[7] != 56 || //data address
|
||||
// header[??] != ?? || //subs address
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1261,7 +1263,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1277,7 +1279,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1293,7 +1295,7 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine data, source: %s\n" TOY_CC_RESET, source);
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected module builder data, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
@@ -1313,7 +1315,7 @@ int main(void) {
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_expressions(&bucket);
|
||||
res = test_builder_expressions(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
@@ -1323,7 +1325,7 @@ int main(void) {
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_binary(&bucket);
|
||||
res = test_builder_binary(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
@@ -1333,7 +1335,7 @@ int main(void) {
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_keywords(&bucket);
|
||||
res = test_builder_keywords(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
127
tests/cases/test_module_bundle.c
Normal file
127
tests/cases/test_module_bundle.c
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "toy_module_bundle.h"
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
#include "toy_opcodes.h"
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//tests
|
||||
int test_bundle_header(Toy_Bucket** bucketHandle) {
|
||||
//simple test to ensure the header looks right
|
||||
{
|
||||
//setup
|
||||
Toy_Ast* ast = NULL;
|
||||
Toy_private_emitAstPass(bucketHandle, &ast);
|
||||
|
||||
//run
|
||||
Toy_ModuleBundle bundle;
|
||||
Toy_initModuleBundle(&bundle);
|
||||
Toy_appendModuleBundle(&bundle, ast);
|
||||
|
||||
if (bundle.count % 4 != 0) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: module bundle size is not a multiple of 4, size is: %d\n" TOY_CC_RESET, (int)bundle.count);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeModuleBundle(&bundle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check
|
||||
if (bundle.ptr[0] != TOY_VERSION_MAJOR ||
|
||||
bundle.ptr[1] != TOY_VERSION_MINOR ||
|
||||
bundle.ptr[2] != TOY_VERSION_PATCH ||
|
||||
bundle.ptr[3] != 1 || //only one module
|
||||
strcmp((char*)(bundle.ptr + 4), TOY_VERSION_BUILD) != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to write the module bundle header correctly:\n" TOY_CC_RESET);
|
||||
fprintf(stderr, TOY_CC_ERROR "\t%d.%d.%d.%s, %d modules found\n" TOY_CC_RESET, (int)(bundle.ptr[0]), (int)(bundle.ptr[1]), (int)(bundle.ptr[2]), (char*)(bundle.ptr + 4), (int)(bundle.ptr[2]));
|
||||
fprintf(stderr, TOY_CC_ERROR "\t%d.%d.%d.%s, %d modules expected\n" TOY_CC_RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, TOY_VERSION_BUILD, 1);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeModuleBundle(&bundle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
Toy_freeModuleBundle(&bundle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_bundle_from_source(Toy_Bucket** bucketHandle) {
|
||||
{
|
||||
//setup
|
||||
const char* source = "(1 + 2) * (3 + 4);";
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
|
||||
Toy_bindLexer(&lexer, source);
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
Toy_ModuleBundle bundle;
|
||||
Toy_initModuleBundle(&bundle);
|
||||
Toy_appendModuleBundle(&bundle, ast);
|
||||
|
||||
//check bytecode alignment
|
||||
if (bundle.count % 4 != 0) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: module bundle size is not a multiple of 4 (size is %d), source: %s\n" TOY_CC_RESET, (int)bundle.count, source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeModuleBundle(&bundle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//check bytecode header
|
||||
//check
|
||||
if (bundle.ptr[0] != TOY_VERSION_MAJOR ||
|
||||
bundle.ptr[1] != TOY_VERSION_MINOR ||
|
||||
bundle.ptr[2] != TOY_VERSION_PATCH ||
|
||||
bundle.ptr[3] != 1 || //only one module
|
||||
strcmp((char*)(bundle.ptr + 4), TOY_VERSION_BUILD) != 0)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to write the module bundle header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeModuleBundle(&bundle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
Toy_freeModuleBundle(&bundle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
//run each test set, returning the total errors given
|
||||
int total = 0, res = 0;
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_bundle_header(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
}
|
||||
total += res;
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_bundle_from_source(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
||||
}
|
||||
total += res;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "toy_lexer.h"
|
||||
#include "toy_parser.h"
|
||||
#include "toy_bytecode.h"
|
||||
#include "toy_module_builder.h"
|
||||
#include "toy_print.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <string.h>
|
||||
|
||||
//utils
|
||||
Toy_Bytecode makeBytecodeFromSource(Toy_Bucket** bucketHandle, const char* source) { //did I forget this?
|
||||
unsigned char* makeCodeFromSource(Toy_Bucket** bucketHandle, const char* source) {
|
||||
Toy_Lexer lexer;
|
||||
Toy_bindLexer(&lexer, source);
|
||||
|
||||
@@ -19,16 +19,14 @@ Toy_Bytecode makeBytecodeFromSource(Toy_Bucket** bucketHandle, const char* sourc
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
|
||||
return bc;
|
||||
return Toy_compileModuleBuilder(ast);
|
||||
}
|
||||
|
||||
//tests
|
||||
int test_setup_and_teardown(Toy_Bucket** bucketHandle) {
|
||||
//basic init & quit
|
||||
{
|
||||
//generate bytecode for testing
|
||||
//generate module for testing
|
||||
const char* source = "(1 + 2) * (3 + 4);";
|
||||
|
||||
Toy_Lexer lexer;
|
||||
@@ -38,41 +36,34 @@ int test_setup_and_teardown(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
|
||||
//check the header size
|
||||
int headerSize = 3 + strlen(TOY_VERSION_BUILD) + 1;
|
||||
if (headerSize % 4 != 0) {
|
||||
headerSize += 4 - (headerSize % 4); //ceil
|
||||
}
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//check the module was loaded correctly
|
||||
if (
|
||||
vm.module - bc.ptr != headerSize ||
|
||||
vm.moduleSize != 72 ||
|
||||
vm.paramSize != 0 ||
|
||||
vm.jumpsSize != 0 ||
|
||||
vm.dataSize != 0 ||
|
||||
vm.subsSize != 0
|
||||
vm.codeAddr != 24 || // module header is: total, jumps, prams, data, subs, codeAddr
|
||||
vm.jumpsCount != 0 ||
|
||||
vm.paramCount != 0 ||
|
||||
vm.dataCount != 0 ||
|
||||
vm.subsCount != 0
|
||||
)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to setup and teadown Toy_VM, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//don't run it this time, simply teadown
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -91,13 +82,13 @@ int test_simple_execution(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -113,13 +104,13 @@ int test_simple_execution(Toy_Bucket** bucketHandle) {
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//teadown
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -138,13 +129,13 @@ int test_opcode_not_equal(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -160,13 +151,13 @@ int test_opcode_not_equal(Toy_Bucket** bucketHandle) {
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//teadown
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -195,11 +186,13 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -213,7 +206,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetAssertFailureCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -222,7 +215,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test assert false
|
||||
@@ -238,11 +231,13 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -257,7 +252,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetAssertFailureCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -266,7 +261,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test assert false with message
|
||||
@@ -282,11 +277,13 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -301,7 +298,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetAssertFailureCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -310,7 +307,7 @@ int test_keyword_assert(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -330,11 +327,13 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -349,7 +348,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -358,7 +357,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test print with a string
|
||||
@@ -374,11 +373,13 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -393,7 +394,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -402,7 +403,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test print with a string concat
|
||||
@@ -418,11 +419,13 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -437,7 +440,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -446,7 +449,7 @@ int test_keyword_print(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -466,11 +469,13 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -485,7 +490,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -494,7 +499,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test if-then (falsy)
|
||||
@@ -510,11 +515,13 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -528,7 +535,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -537,7 +544,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test if-then-else (truthy)
|
||||
@@ -553,11 +560,13 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -572,7 +581,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -581,7 +590,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test if-then-else (falsy)
|
||||
@@ -597,11 +606,13 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -616,7 +627,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
Toy_resetPrintCallback();
|
||||
free(callbackUtilReceived);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -625,7 +636,7 @@ int test_keyword_ifThenElse(Toy_Bucket** bucketHandle) {
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -644,13 +655,13 @@ int test_scope(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -672,13 +683,13 @@ int test_scope(Toy_Bucket** bucketHandle) {
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//teadown
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//test declaration with absent value
|
||||
@@ -693,13 +704,13 @@ int test_scope(Toy_Bucket** bucketHandle) {
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
Toy_Bytecode bc = Toy_compileBytecode(ast);
|
||||
unsigned char* buffer = Toy_compileModuleBuilder(ast);
|
||||
Toy_Module module = Toy_parseModule(buffer);
|
||||
|
||||
//run the setup
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
Toy_bindVM(&vm, &bc);
|
||||
Toy_bindVM(&vm, &module, false);
|
||||
|
||||
//run
|
||||
Toy_runVM(&vm);
|
||||
@@ -719,13 +730,13 @@ int test_scope(Toy_Bucket** bucketHandle) {
|
||||
|
||||
//cleanup and return
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//teadown
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBytecode(bc);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -740,10 +751,12 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) {
|
||||
Toy_initVM(&vm);
|
||||
|
||||
//run 1
|
||||
Toy_Bytecode bc1 = makeBytecodeFromSource(bucketHandle, "print \"Hello world!\";");
|
||||
Toy_bindVM(&vm, &bc1);
|
||||
unsigned char* buffer1 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";");
|
||||
Toy_Module module1 = Toy_parseModule(buffer1);
|
||||
Toy_bindVM(&vm, &module1, false);
|
||||
|
||||
Toy_runVM(&vm);
|
||||
Toy_resetVM(&vm);
|
||||
Toy_resetVM(&vm, true);
|
||||
|
||||
if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 1\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL");
|
||||
@@ -751,18 +764,20 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) {
|
||||
//cleanup and return
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeBytecode(bc1);
|
||||
free(buffer1);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_resetPrintCallback();
|
||||
return -1;
|
||||
}
|
||||
Toy_freeBytecode(bc1);
|
||||
free(buffer1);
|
||||
|
||||
//run 2
|
||||
Toy_Bytecode bc2 = makeBytecodeFromSource(bucketHandle, "print \"Hello world!\";");
|
||||
Toy_bindVM(&vm, &bc2);
|
||||
unsigned char* buffer2 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";");
|
||||
Toy_Module module2 = Toy_parseModule(buffer2);
|
||||
Toy_bindVM(&vm, &module2, true); //preserve during repeated calls
|
||||
|
||||
Toy_runVM(&vm);
|
||||
Toy_resetVM(&vm);
|
||||
Toy_resetVM(&vm, true);
|
||||
|
||||
if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 2\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL");
|
||||
@@ -770,18 +785,20 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) {
|
||||
//cleanup and return
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeBytecode(bc2);
|
||||
free(buffer2);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_resetPrintCallback();
|
||||
return -1;
|
||||
}
|
||||
Toy_freeBytecode(bc2);
|
||||
free(buffer2);
|
||||
|
||||
//run 3
|
||||
Toy_Bytecode bc3 = makeBytecodeFromSource(bucketHandle, "print \"Hello world!\";");
|
||||
Toy_bindVM(&vm, &bc3);
|
||||
unsigned char* buffer3 = makeCodeFromSource(bucketHandle, "print \"Hello world!\";");
|
||||
Toy_Module module3 = Toy_parseModule(buffer3);
|
||||
Toy_bindVM(&vm, &module3, true); //preserve during repeated calls
|
||||
|
||||
Toy_runVM(&vm);
|
||||
Toy_resetVM(&vm);
|
||||
Toy_resetVM(&vm, true);
|
||||
|
||||
if (callbackUtilReceived == NULL || strcmp(callbackUtilReceived, "Hello world!") != 0) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected value '%s' found in VM reuse run 3\n" TOY_CC_RESET, callbackUtilReceived != NULL ? callbackUtilReceived : "NULL");
|
||||
@@ -789,12 +806,12 @@ int test_vm_reuse(Toy_Bucket** bucketHandle) {
|
||||
//cleanup and return
|
||||
free(callbackUtilReceived);
|
||||
callbackUtilReceived = NULL;
|
||||
Toy_freeBytecode(bc3);
|
||||
free(buffer3);
|
||||
Toy_freeVM(&vm);
|
||||
Toy_resetPrintCallback();
|
||||
return -1;
|
||||
}
|
||||
Toy_freeBytecode(bc3);
|
||||
free(buffer3);
|
||||
|
||||
//cleanup
|
||||
Toy_freeVM(&vm);
|
||||
|
||||
Reference in New Issue
Block a user