diff --git a/repl/main.c b/repl/main.c index 9f88889..e6c6ec5 100644 --- a/repl/main.c +++ b/repl/main.c @@ -2,7 +2,7 @@ #include "toy_lexer.h" #include "toy_parser.h" -#include "toy_module_compiler.h" +#include "toy_compiler.h" #include "toy_vm.h" #include @@ -332,16 +332,15 @@ int repl(const char* filepath) { continue; } - unsigned char* buffer = Toy_compileModule(ast); - Toy_Module module = Toy_parseModule(buffer); - Toy_bindVM(&vm, &module, runCount++ > 0); + unsigned char* bytecode = Toy_compileToBytecode(ast); + Toy_bindVM(&vm, bytecode, runCount++ > 0); //run Toy_runVM(&vm); //free the memory, and leave the VM ready for the next loop Toy_resetVM(&vm, true); - free(buffer); + free(bytecode); printf("%s> ", prompt); //shows the terminal prompt } @@ -368,7 +367,7 @@ static void debugStackPrint(Toy_Stack* stack) { //print value Toy_String* string = Toy_stringifyValue(&stringBucket, Toy_unwrapValue(v)); - char* buffer = Toy_getStringRawBuffer(string); + char* buffer = Toy_getStringRaw(string); printf("%s", buffer); free(buffer); Toy_freeString(string); @@ -382,23 +381,23 @@ static void debugStackPrint(Toy_Stack* stack) { static void debugScopePrint(Toy_Scope* scope, int depth) { //DEBUG: if there's anything in the scope, print it - if (scope->table->count > 0) { + if (scope->count > 0) { Toy_Bucket* stringBucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); printf("Scope %d Dump\n-------------------------\ntype\tname\tvalue\n", depth); - for (unsigned int i = 0; i < scope->table->capacity; i++) { - if ( (TOY_VALUE_IS_STRING(scope->table->data[i].key) && TOY_VALUE_AS_STRING(scope->table->data[i].key)->info.type == TOY_STRING_NAME) != true) { + for (unsigned int i = 0; i < scope->capacity; i++) { + if (scope->data[i].key.info.length == 0) { continue; } - Toy_Value k = scope->table->data[i].key; - Toy_Value v = scope->table->data[i].value; + Toy_String k = scope->data[i].key; + Toy_Value v = scope->data[i].value; - printf("%s\t%s\t", Toy_private_getValueTypeAsCString(v.type), TOY_VALUE_AS_STRING(k)->name.data); + printf("%s\t%s\t", Toy_private_getValueTypeAsCString(v.type), k.leaf.data); //print value Toy_String* string = Toy_stringifyValue(&stringBucket, Toy_unwrapValue(v)); - char* buffer = Toy_getStringRawBuffer(string); + char* buffer = Toy_getStringRaw(string); printf("%s", buffer); free(buffer); Toy_freeString(string); @@ -481,16 +480,14 @@ int main(int argc, const char* argv[]) { Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); Toy_Ast* ast = Toy_scanParser(&bucket, &parser); - unsigned char* buffer = Toy_compileModule(ast); + unsigned char* bytecode = Toy_compileToBytecode(ast); Toy_freeBucket(&bucket); free(source); //run the compiled code Toy_VM vm; Toy_initVM(&vm); - - Toy_Module module = Toy_parseModule(buffer); - Toy_bindVM(&vm, &module, false); + Toy_bindVM(&vm, bytecode, false); Toy_runVM(&vm); @@ -502,7 +499,7 @@ int main(int argc, const char* argv[]) { //cleanup Toy_freeVM(&vm); - free(buffer); + free(bytecode); } else { repl(argv[0]); diff --git a/scripts/hello_world.toy b/scripts/hello_world.toy new file mode 100644 index 0000000..c71d05d --- /dev/null +++ b/scripts/hello_world.toy @@ -0,0 +1 @@ +print "Hello world"; \ No newline at end of file diff --git a/source/toy_module_compiler.c b/source/toy_compiler.c similarity index 86% rename from source/toy_module_compiler.c rename to source/toy_compiler.c index 7c55379..b943ffb 100644 --- a/source/toy_module_compiler.c +++ b/source/toy_compiler.c @@ -1,4 +1,4 @@ -#include "toy_module_compiler.h" +#include "toy_compiler.h" #include "toy_console_colors.h" #include "toy_opcodes.h" @@ -43,7 +43,7 @@ Toy_private_EscapeArray* Toy_private_resizeEscapeArray(Toy_private_EscapeArray* ptr = (Toy_private_EscapeArray*)realloc(ptr, capacity * sizeof(Toy_private_EscapeEntry_t) + sizeof(Toy_private_EscapeArray)); if (ptr == NULL) { - fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to resize an escape array within 'Toy_ModuleCompiler' from %d to %d capacity\n" TOY_CC_RESET, (int)originalCapacity, (int)capacity); + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to resize an escape array within 'Toy_Bytecode' from %d to %d capacity\n" TOY_CC_RESET, (int)originalCapacity, (int)capacity); exit(-1); } @@ -62,7 +62,7 @@ static void expand(unsigned char** handle, unsigned int* capacity, unsigned int* (*handle) = realloc((*handle), (*capacity)); if ((*handle) == NULL) { - fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate %d space for a part of 'Toy_ModuleCompiler'\n" TOY_CC_RESET, (int)(*capacity)); + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate %d space for a part of 'Toy_Bytecode'\n" TOY_CC_RESET, (int)(*capacity)); exit(1); } } @@ -142,7 +142,7 @@ static unsigned int emitCStringToData(unsigned char** dataHandle, unsigned int* return addr; //return the address of the string in the data section } -static unsigned int emitString(Toy_ModuleCompiler** mb, Toy_String* str) { +static unsigned int emitString(Toy_Bytecode** mb, Toy_String* str) { //the address within the data section unsigned int dataAddr = 0; @@ -173,7 +173,7 @@ static unsigned int emitString(Toy_ModuleCompiler** mb, Toy_String* str) { return 1; } -static unsigned int emitParameters(Toy_ModuleCompiler* mb, Toy_Ast* ast) { +static unsigned int emitParameters(Toy_Bytecode* mb, Toy_Ast* ast) { //recursive checks if (ast == NULL) { return 0; @@ -211,12 +211,12 @@ static unsigned int emitParameters(Toy_ModuleCompiler* mb, Toy_Ast* ast) { return 1; } -static unsigned int writeModuleCompilerCode(Toy_ModuleCompiler** mb, Toy_Ast* ast); //forward declare for recursion -static void writeModuleCompilerBody(Toy_ModuleCompiler* mb, Toy_Ast* ast); -static unsigned char* writeModuleCompilerResult(Toy_ModuleCompiler* mb); -static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAssign ast, bool chainedAssignment); //forward declare for chaining of var declarations +static unsigned int writeBytecodeFromAst(Toy_Bytecode** mb, Toy_Ast* ast); //forward declare for recursion +static void writeBytecodeBody(Toy_Bytecode* mb, Toy_Ast* ast); +static unsigned char* collateBytecodeBody(Toy_Bytecode* mb); +static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign ast, bool chainedAssignment); //forward declare for chaining of var declarations -static unsigned int writeInstructionValue(Toy_ModuleCompiler** mb, Toy_AstValue ast) { +static unsigned int writeInstructionValue(Toy_Bytecode** mb, Toy_AstValue ast) { EMIT_BYTE(mb, code, TOY_OPCODE_READ); EMIT_BYTE(mb, code, ast.value.type); @@ -263,11 +263,11 @@ static unsigned int writeInstructionValue(Toy_ModuleCompiler** mb, Toy_AstValue return 1; } -static unsigned int writeInstructionUnary(Toy_ModuleCompiler** mb, Toy_AstUnary ast) { +static unsigned int writeInstructionUnary(Toy_Bytecode** mb, Toy_AstUnary ast) { unsigned int result = 0; if (ast.flag == TOY_AST_FLAG_NEGATE) { - result = writeModuleCompilerCode(mb, ast.child); + result = writeBytecodeFromAst(mb, ast.child); EMIT_BYTE(mb, code, TOY_OPCODE_NEGATE); @@ -371,10 +371,10 @@ static unsigned int writeInstructionUnary(Toy_ModuleCompiler** mb, Toy_AstUnary return result; } -static unsigned int writeInstructionBinary(Toy_ModuleCompiler** mb, Toy_AstBinary ast) { +static unsigned int writeInstructionBinary(Toy_Bytecode** mb, Toy_AstBinary ast) { //left, then right, then the binary's operation - writeModuleCompilerCode(mb, ast.left); - writeModuleCompilerCode(mb, ast.right); + writeBytecodeFromAst(mb, ast.left); + writeBytecodeFromAst(mb, ast.right); if (ast.flag == TOY_AST_FLAG_ADD) { EMIT_BYTE(mb, code,TOY_OPCODE_ADD); @@ -408,9 +408,9 @@ static unsigned int writeInstructionBinary(Toy_ModuleCompiler** mb, Toy_AstBinar return 1; //leaves only 1 value on the stack } -static unsigned int writeInstructionBinaryShortCircuit(Toy_ModuleCompiler** mb, Toy_AstBinaryShortCircuit ast) { +static unsigned int writeInstructionBinaryShortCircuit(Toy_Bytecode** mb, Toy_AstBinaryShortCircuit ast) { //lhs - writeModuleCompilerCode(mb, ast.left); + writeBytecodeFromAst(mb, ast.left); //duplicate the top (so the lhs can be 'returned' by this expression, if needed) EMIT_BYTE(mb, code,TOY_OPCODE_DUPLICATE); @@ -449,7 +449,7 @@ static unsigned int writeInstructionBinaryShortCircuit(Toy_ModuleCompiler** mb, EMIT_BYTE(mb, code, 0); //rhs - writeModuleCompilerCode(mb, ast.right); + writeBytecodeFromAst(mb, ast.right); //set the parameter OVERWRITE_INT(mb, code, paramAddr, CURRENT_ADDRESS(mb, code) - (paramAddr + 4)); @@ -457,10 +457,10 @@ static unsigned int writeInstructionBinaryShortCircuit(Toy_ModuleCompiler** mb, return 1; //leaves only 1 value on the stack } -static unsigned int writeInstructionCompare(Toy_ModuleCompiler** mb, Toy_AstCompare ast) { +static unsigned int writeInstructionCompare(Toy_Bytecode** mb, Toy_AstCompare ast) { //left, then right, then the compare's operation - writeModuleCompilerCode(mb, ast.left); - writeModuleCompilerCode(mb, ast.right); + writeBytecodeFromAst(mb, ast.left); + writeBytecodeFromAst(mb, ast.right); if (ast.flag == TOY_AST_FLAG_COMPARE_EQUAL) { EMIT_BYTE(mb, code,TOY_OPCODE_COMPARE_EQUAL); @@ -499,13 +499,13 @@ static unsigned int writeInstructionCompare(Toy_ModuleCompiler** mb, Toy_AstComp return 1; //leaves only 1 value on the stack } -static unsigned int writeInstructionGroup(Toy_ModuleCompiler** mb, Toy_AstGroup ast) { +static unsigned int writeInstructionGroup(Toy_Bytecode** mb, Toy_AstGroup ast) { //not certain what this leaves - return writeModuleCompilerCode(mb, ast.child); + return writeBytecodeFromAst(mb, ast.child); } -static unsigned int writeInstructionCompound(Toy_ModuleCompiler** mb, Toy_AstCompound ast) { - unsigned int result = writeModuleCompilerCode(mb, ast.child); +static unsigned int writeInstructionCompound(Toy_Bytecode** mb, Toy_AstCompound ast) { + unsigned int result = writeBytecodeFromAst(mb, ast.child); if (ast.flag == TOY_AST_FLAG_COMPOUND_ARRAY) { //signal how many values to read in as array elements @@ -542,12 +542,12 @@ static unsigned int writeInstructionCompound(Toy_ModuleCompiler** mb, Toy_AstCom } } -static unsigned int writeInstructionAggregate(Toy_ModuleCompiler** mb, Toy_AstAggregate ast) { +static unsigned int writeInstructionAggregate(Toy_Bytecode** mb, Toy_AstAggregate ast) { unsigned int result = 0; //left, then right - result += writeModuleCompilerCode(mb, ast.left); - result += writeModuleCompilerCode(mb, ast.right); + result += writeBytecodeFromAst(mb, ast.left); + result += writeBytecodeFromAst(mb, ast.right); if (ast.flag == TOY_AST_FLAG_COLLECTION) { //collections are handled above @@ -575,10 +575,10 @@ static unsigned int writeInstructionAggregate(Toy_ModuleCompiler** mb, Toy_AstAg } } -static unsigned int writeInstructionAssert(Toy_ModuleCompiler** mb, Toy_AstAssert ast) { +static unsigned int writeInstructionAssert(Toy_Bytecode** mb, Toy_AstAssert ast) { //the thing to print - writeModuleCompilerCode(mb, ast.child); - writeModuleCompilerCode(mb, ast.message); + writeBytecodeFromAst(mb, ast.child); + writeBytecodeFromAst(mb, ast.message); //output the print opcode EMIT_BYTE(mb, code, TOY_OPCODE_ASSERT); @@ -591,9 +591,9 @@ static unsigned int writeInstructionAssert(Toy_ModuleCompiler** mb, Toy_AstAsser return 0; } -static unsigned int writeInstructionIfThenElse(Toy_ModuleCompiler** mb, Toy_AstIfThenElse ast) { +static unsigned int writeInstructionIfThenElse(Toy_Bytecode** mb, Toy_AstIfThenElse ast) { //cond-branch - writeModuleCompilerCode(mb, ast.condBranch); + writeBytecodeFromAst(mb, ast.condBranch); //emit the jump word (opcode, type, condition, padding) EMIT_BYTE(mb, code, TOY_OPCODE_JUMP); @@ -604,7 +604,7 @@ static unsigned int writeInstructionIfThenElse(Toy_ModuleCompiler** mb, Toy_AstI unsigned int thenParamAddr = SKIP_INT(mb, code); //parameter to be written later //emit then-branch - writeModuleCompilerCode(mb, ast.thenBranch); + writeBytecodeFromAst(mb, ast.thenBranch); if (ast.elseBranch != NULL) { //emit the jump-to-end (opcode, type, condition, padding) @@ -619,7 +619,7 @@ static unsigned int writeInstructionIfThenElse(Toy_ModuleCompiler** mb, Toy_AstI OVERWRITE_INT(mb, code, thenParamAddr, CURRENT_ADDRESS(mb, code) - (thenParamAddr + 4)); //emit the else branch - writeModuleCompilerCode(mb, ast.elseBranch); + writeBytecodeFromAst(mb, ast.elseBranch); //specify the ending position for the else branch OVERWRITE_INT(mb, code, elseParamAddr, CURRENT_ADDRESS(mb, code) - (elseParamAddr + 4)); @@ -633,12 +633,12 @@ static unsigned int writeInstructionIfThenElse(Toy_ModuleCompiler** mb, Toy_AstI return 0; } -static unsigned int writeInstructionWhileThen(Toy_ModuleCompiler** mb, Toy_AstWhileThen ast) { +static unsigned int writeInstructionWhileThen(Toy_Bytecode** mb, Toy_AstWhileThen ast) { //begin unsigned int beginAddr = CURRENT_ADDRESS(mb, code); //cond-branch - writeModuleCompilerCode(mb, ast.condBranch); + writeBytecodeFromAst(mb, ast.condBranch); //emit the jump word (opcode, type, condition, padding) EMIT_BYTE(mb, code, TOY_OPCODE_JUMP); @@ -649,7 +649,7 @@ static unsigned int writeInstructionWhileThen(Toy_ModuleCompiler** mb, Toy_AstWh unsigned int paramAddr = SKIP_INT(mb, code); //parameter to be written later //emit then-branch - writeModuleCompilerCode(mb, ast.thenBranch); + writeBytecodeFromAst(mb, ast.thenBranch); //jump to begin to repeat the conditional test EMIT_BYTE(mb, code, TOY_OPCODE_JUMP); @@ -694,7 +694,7 @@ static unsigned int writeInstructionWhileThen(Toy_ModuleCompiler** mb, Toy_AstWh return 0; } -static unsigned int writeInstructionBreak(Toy_ModuleCompiler** mb, Toy_AstBreak ast) { +static unsigned int writeInstructionBreak(Toy_Bytecode** mb, Toy_AstBreak ast) { //unused (void)ast; @@ -718,7 +718,7 @@ static unsigned int writeInstructionBreak(Toy_ModuleCompiler** mb, Toy_AstBreak return 0; } -static unsigned int writeInstructionContinue(Toy_ModuleCompiler** mb, Toy_AstContinue ast) { +static unsigned int writeInstructionContinue(Toy_Bytecode** mb, Toy_AstContinue ast) { //unused (void)ast; @@ -742,9 +742,9 @@ static unsigned int writeInstructionContinue(Toy_ModuleCompiler** mb, Toy_AstCon return 0; } -static unsigned int writeInstructionReturn(Toy_ModuleCompiler** mb, Toy_AstReturn ast) { +static unsigned int writeInstructionReturn(Toy_Bytecode** mb, Toy_AstReturn ast) { //the things to return - unsigned int retCount = writeModuleCompilerCode(mb, ast.child); + unsigned int retCount = writeBytecodeFromAst(mb, ast.child); //output the print opcode EMIT_BYTE(mb, code,TOY_OPCODE_RETURN); @@ -757,9 +757,9 @@ static unsigned int writeInstructionReturn(Toy_ModuleCompiler** mb, Toy_AstRetur return 0; } -static unsigned int writeInstructionPrint(Toy_ModuleCompiler** mb, Toy_AstPrint ast) { +static unsigned int writeInstructionPrint(Toy_Bytecode** mb, Toy_AstPrint ast) { //the thing to print - writeModuleCompilerCode(mb, ast.child); + writeBytecodeFromAst(mb, ast.child); //output the print opcode EMIT_BYTE(mb, code,TOY_OPCODE_PRINT); @@ -772,13 +772,13 @@ static unsigned int writeInstructionPrint(Toy_ModuleCompiler** mb, Toy_AstPrint return 0; } -static unsigned int writeInstructionVarDeclare(Toy_ModuleCompiler** mb, Toy_AstVarDeclare ast) { +static unsigned int writeInstructionVarDeclare(Toy_Bytecode** mb, Toy_AstVarDeclare ast) { //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true if (checkForChaining(ast.expr)) { writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - writeModuleCompilerCode(mb, ast.expr); //default value + writeBytecodeFromAst(mb, ast.expr); //default value } //delcare with the given name string @@ -792,7 +792,7 @@ static unsigned int writeInstructionVarDeclare(Toy_ModuleCompiler** mb, Toy_AstV return 0; } -static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAssign ast, bool chainedAssignment) { +static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign ast, bool chainedAssignment) { unsigned int result = 0; //target is a name string @@ -811,15 +811,15 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs //target is an indexing of some compound value else if (ast.target->type == TOY_AST_AGGREGATE && ast.target->aggregate.flag == TOY_AST_FLAG_INDEX) { - writeModuleCompilerCode(mb, ast.target->aggregate.left); //any deeper indexing will just work, using reference values - writeModuleCompilerCode(mb, ast.target->aggregate.right); //key + writeBytecodeFromAst(mb, ast.target->aggregate.left); //any deeper indexing will just work, using reference values + writeBytecodeFromAst(mb, ast.target->aggregate.right); //key //if we're dealing with chained assignments, hijack the next assignment with 'chainedAssignment' set to true if (checkForChaining(ast.expr)) { result += writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - result += writeModuleCompilerCode(mb, ast.expr); //default value + result += writeBytecodeFromAst(mb, ast.expr); //default value } EMIT_BYTE(mb, code, TOY_OPCODE_ASSIGN_COMPOUND); //uses the top three values on the stack @@ -844,7 +844,7 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs result += writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - result += writeModuleCompilerCode(mb, ast.expr); //default value + result += writeBytecodeFromAst(mb, ast.expr); //default value } EMIT_BYTE(mb, code, TOY_OPCODE_ASSIGN); @@ -863,7 +863,7 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs result += writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - result += writeModuleCompilerCode(mb, ast.expr); //default value + result += writeBytecodeFromAst(mb, ast.expr); //default value } EMIT_BYTE(mb, code,TOY_OPCODE_ADD); @@ -882,7 +882,7 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs result += writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - result += writeModuleCompilerCode(mb, ast.expr); //default value + result += writeBytecodeFromAst(mb, ast.expr); //default value } EMIT_BYTE(mb, code,TOY_OPCODE_SUBTRACT); @@ -901,7 +901,7 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs result += writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - result += writeModuleCompilerCode(mb, ast.expr); //default value + result += writeBytecodeFromAst(mb, ast.expr); //default value } EMIT_BYTE(mb, code,TOY_OPCODE_MULTIPLY); @@ -920,7 +920,7 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs result += writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - result += writeModuleCompilerCode(mb, ast.expr); //default value + result += writeBytecodeFromAst(mb, ast.expr); //default value } EMIT_BYTE(mb, code,TOY_OPCODE_DIVIDE); @@ -939,7 +939,7 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs result += writeInstructionAssign(mb, ast.expr->varAssign, true); } else { - result += writeModuleCompilerCode(mb, ast.expr); //default value + result += writeBytecodeFromAst(mb, ast.expr); //default value } EMIT_BYTE(mb, code,TOY_OPCODE_MODULO); @@ -956,7 +956,7 @@ static unsigned int writeInstructionAssign(Toy_ModuleCompiler** mb, Toy_AstVarAs return result + (chainedAssignment ? 1 : 0); } -static unsigned int writeInstructionAccess(Toy_ModuleCompiler** mb, Toy_AstVarAccess ast) { +static unsigned int writeInstructionAccess(Toy_Bytecode** mb, Toy_AstVarAccess ast) { if (!(ast.child->type == TOY_AST_VALUE && TOY_VALUE_IS_STRING(ast.child->value.value))) { fprintf(stderr, TOY_CC_ERROR "COMPILER ERROR: Found a non-name-string in a value node when trying to write access\n" TOY_CC_RESET); (*mb)->panic = true; @@ -982,7 +982,7 @@ static unsigned int writeInstructionAccess(Toy_ModuleCompiler** mb, Toy_AstVarAc return 1; } -static unsigned int writeInstructionFnDeclare(Toy_ModuleCompiler** mb, Toy_AstFnDeclare ast) { +static unsigned int writeInstructionFnDeclare(Toy_Bytecode** mb, Toy_AstFnDeclare ast) { /* FnDeclare: name, params, body @@ -1001,16 +1001,16 @@ static unsigned int writeInstructionFnDeclare(Toy_ModuleCompiler** mb, Toy_AstFn .right->value.value.as.string.name (param4: any) */ - //generate the submodule - Toy_ModuleCompiler compiler = { 0 }; + //generate the subroutine + Toy_Bytecode compiler = { 0 }; compiler.breakEscapes = Toy_private_resizeEscapeArray(NULL, TOY_ESCAPE_INITIAL_CAPACITY); compiler.continueEscapes = Toy_private_resizeEscapeArray(NULL, TOY_ESCAPE_INITIAL_CAPACITY); //compile the ast to memory unsigned int paramCount = emitParameters(&compiler, ast.params); - writeModuleCompilerBody(&compiler, ast.body); - unsigned char* submodule = writeModuleCompilerResult(&compiler); + writeBytecodeBody(&compiler, ast.body); + unsigned char* subroutine = collateBytecodeBody(&compiler); //cleanup the compiler Toy_private_resizeEscapeArray(compiler.breakEscapes, 0); @@ -1022,10 +1022,10 @@ static unsigned int writeInstructionFnDeclare(Toy_ModuleCompiler** mb, Toy_AstFn free(compiler.data); free(compiler.subs); - //write the submodule to the subs section + //write the subroutine to the subs section unsigned int subsAddr = (*mb)->subsCount; - emitBuffer(&((*mb)->subs), &((*mb)->subsCapacity), &((*mb)->subsCount), submodule, *((unsigned int*)submodule)); - free(submodule); + emitBuffer(&((*mb)->subs), &((*mb)->subsCapacity), &((*mb)->subsCount), subroutine, *((unsigned int*)subroutine)); + free(subroutine); //read the function as a value, with the address as a parameter EMIT_BYTE(mb, code, TOY_OPCODE_READ); @@ -1047,8 +1047,8 @@ static unsigned int writeInstructionFnDeclare(Toy_ModuleCompiler** mb, Toy_AstFn return 0; } -static unsigned int writeInstructionFnInvoke(Toy_ModuleCompiler** mb, Toy_AstFnInvoke ast) { - unsigned int argCount = writeModuleCompilerCode(mb, ast.args); +static unsigned int writeInstructionFnInvoke(Toy_Bytecode** mb, Toy_AstFnInvoke ast) { + unsigned int argCount = writeBytecodeFromAst(mb, ast.args); if (argCount > 255) { fprintf(stderr, TOY_CC_ERROR "COMPILER ERROR: Invalid function invokation with %d functions arguments (maximum 255)\n" TOY_CC_RESET, (int)argCount); @@ -1056,7 +1056,7 @@ static unsigned int writeInstructionFnInvoke(Toy_ModuleCompiler** mb, Toy_AstFnI return 0; } - unsigned int fnCount = writeModuleCompilerCode(mb, ast.function); + unsigned int fnCount = writeBytecodeFromAst(mb, ast.function); if (fnCount != 1) { fprintf(stderr, TOY_CC_ERROR "COMPILER ERROR: Invalid function invokation with %d function AST nodes (expected 1)\n" TOY_CC_RESET, (int)fnCount); @@ -1073,7 +1073,7 @@ static unsigned int writeInstructionFnInvoke(Toy_ModuleCompiler** mb, Toy_AstFnI return 0; } -static unsigned int writeModuleCompilerCode(Toy_ModuleCompiler** mb, Toy_Ast* ast) { +static unsigned int writeBytecodeFromAst(Toy_Bytecode** mb, Toy_Ast* ast) { if (ast == NULL) { return 0; } @@ -1098,8 +1098,8 @@ static unsigned int writeModuleCompilerCode(Toy_ModuleCompiler** mb, Toy_Ast* as (*mb)->currentScopeDepth++; } - result += writeModuleCompilerCode(mb, ast->block.child); - result += writeModuleCompilerCode(mb, ast->block.next); + result += writeBytecodeFromAst(mb, ast->block.child); + result += writeBytecodeFromAst(mb, ast->block.next); if (ast->block.innerScope) { EMIT_BYTE(mb, code, TOY_OPCODE_SCOPE_POP); @@ -1210,10 +1210,10 @@ static unsigned int writeModuleCompilerCode(Toy_ModuleCompiler** mb, Toy_Ast* as return result; } -static void writeModuleCompilerBody(Toy_ModuleCompiler* mb, Toy_Ast* ast) { - //this is separated from 'writeModuleCompilerResult', to separate the concerns for modules & functions +static void writeBytecodeBody(Toy_Bytecode* mb, Toy_Ast* ast) { + //this is separated from 'collateBytecodeBody', to separate the concerns for bytecode & functions - writeModuleCompilerCode(&mb, ast); + writeBytecodeFromAst(&mb, ast); EMIT_BYTE(&mb, code, TOY_OPCODE_RETURN); //end terminator EMIT_BYTE(&mb, code, 0); //4-byte alignment @@ -1221,7 +1221,7 @@ static void writeModuleCompilerBody(Toy_ModuleCompiler* mb, Toy_Ast* ast) { EMIT_BYTE(&mb, code, 0); } -static unsigned char* writeModuleCompilerResult(Toy_ModuleCompiler* mb) { +static unsigned char* collateBytecodeBody(Toy_Bytecode* mb) { //if an error occurred, just exit if (mb->panic) { return NULL; @@ -1312,16 +1312,16 @@ static unsigned char* writeModuleCompilerResult(Toy_ModuleCompiler* mb) { } //exposed functions -unsigned char* Toy_compileModule(Toy_Ast* ast) { +unsigned char* Toy_compileToBytecode(Toy_Ast* ast) { //setup - Toy_ModuleCompiler compiler = { 0 }; + Toy_Bytecode compiler = { 0 }; compiler.breakEscapes = Toy_private_resizeEscapeArray(NULL, TOY_ESCAPE_INITIAL_CAPACITY); compiler.continueEscapes = Toy_private_resizeEscapeArray(NULL, TOY_ESCAPE_INITIAL_CAPACITY); //compile the ast to memory - writeModuleCompilerBody(&compiler, ast); - unsigned char* buffer = writeModuleCompilerResult(&compiler); + writeBytecodeBody(&compiler, ast); + unsigned char* buffer = collateBytecodeBody(&compiler); //cleanup Toy_private_resizeEscapeArray(compiler.breakEscapes, 0); diff --git a/source/toy_module_compiler.h b/source/toy_compiler.h similarity index 87% rename from source/toy_module_compiler.h rename to source/toy_compiler.h index 7b85289..514b85b 100644 --- a/source/toy_module_compiler.h +++ b/source/toy_compiler.h @@ -26,8 +26,8 @@ typedef struct Toy_private_EscapeArray { TOY_API Toy_private_EscapeArray* Toy_private_resizeEscapeArray(Toy_private_EscapeArray* ptr, unsigned int capacity); -//structure for holding the module as it is built -typedef struct Toy_ModuleCompiler { +//structure for holding the bytecode during compilation +typedef struct Toy_Bytecode { unsigned char* code; //the instruction set unsigned int codeCapacity; unsigned int codeCount; @@ -44,7 +44,7 @@ typedef struct Toy_ModuleCompiler { unsigned int dataCapacity; unsigned int dataCount; - unsigned char* subs; //submodules, built recursively + unsigned char* subs; //subroutines etc, built recursively unsigned int subsCapacity; unsigned int subsCount; @@ -57,6 +57,6 @@ typedef struct Toy_ModuleCompiler { //compilation errors bool panic; -} Toy_ModuleCompiler; +} Toy_Bytecode; -TOY_API unsigned char* Toy_compileModule(Toy_Ast* ast); +TOY_API unsigned char* Toy_compileToBytecode(Toy_Ast* ast); diff --git a/source/toy_function.c b/source/toy_function.c index 9004757..a0af800 100644 --- a/source/toy_function.c +++ b/source/toy_function.c @@ -1,10 +1,10 @@ #include "toy_function.h" -Toy_Function* Toy_createModuleFunction(Toy_Bucket** bucketHandle, Toy_Module module) { +Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned char* bytecode) { Toy_Function* fn = (Toy_Function*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Function)); - fn->type = TOY_FUNCTION_MODULE; - fn->module.module = module; + fn->type = TOY_FUNCTION_CUSTOM; + fn->bytecode.code = bytecode; return fn; } \ No newline at end of file diff --git a/source/toy_function.h b/source/toy_function.h index bd1a0d4..741f33f 100644 --- a/source/toy_function.h +++ b/source/toy_function.h @@ -1,18 +1,17 @@ #pragma once #include "toy_common.h" - -#include "toy_module.h" +#include "toy_bucket.h" typedef enum Toy_FunctionType { - TOY_FUNCTION_MODULE, + TOY_FUNCTION_CUSTOM, TOY_FUNCTION_NATIVE, } Toy_FunctionType; -typedef struct Toy_FunctionModule { +typedef struct Toy_FunctionBytecode { Toy_FunctionType type; - Toy_Module module; -} Toy_FunctionModule; + unsigned char* code; +} Toy_FunctionBytecode; typedef struct Toy_FunctionNative { Toy_FunctionType type; @@ -21,8 +20,8 @@ typedef struct Toy_FunctionNative { typedef union Toy_Function_t { Toy_FunctionType type; - Toy_FunctionModule module; + Toy_FunctionBytecode bytecode; Toy_FunctionNative native; } Toy_Function; -TOY_API Toy_Function* Toy_createModuleFunction(Toy_Bucket** bucketHandle, Toy_Module module); +TOY_API Toy_Function* Toy_createFunctionFromBytecode(Toy_Bucket** bucketHandle, unsigned char* bytecode); diff --git a/source/toy_module.c b/source/toy_module.c deleted file mode 100644 index 7189933..0000000 --- a/source/toy_module.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "toy_module.h" -#include "toy_console_colors.h" - -static inline unsigned int readUnsignedInt(unsigned char** handle) { - unsigned int i = *((unsigned int*)(*handle)); - (*handle) += 4; - return i; -} - -Toy_Module Toy_parseModule(unsigned char* ptr) { - if (ptr == NULL) { - return (Toy_Module){ 0 }; - } - - Toy_Module module; - - module.parentScope = NULL; - - module.code = ptr; - - //header - readUnsignedInt(&ptr); - - module.jumpsCount = readUnsignedInt(&ptr); - module.paramCount = readUnsignedInt(&ptr); - module.dataCount = readUnsignedInt(&ptr); - module.subsCount = readUnsignedInt(&ptr); - - module.codeAddr = readUnsignedInt(&ptr); - if (module.jumpsCount) { - module.jumpsAddr = readUnsignedInt(&ptr); - } - if (module.paramCount) { - module.paramAddr = readUnsignedInt(&ptr); - } - if (module.dataCount) { - module.dataAddr = readUnsignedInt(&ptr); - } - if (module.subsCount) { - module.subsAddr = readUnsignedInt(&ptr); - } - - return module; -} \ No newline at end of file diff --git a/source/toy_module.h b/source/toy_module.h deleted file mode 100644 index 82033a0..0000000 --- a/source/toy_module.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "toy_common.h" -#include "toy_scope.h" - -//runtime module info -typedef struct Toy_Module { - //closure support - points to parent scope - Toy_Scope* parentScope; - - unsigned char* code; - - //extracted metadata - // unsigned int codeCount; //NOTE: not used - unsigned int jumpsCount; - unsigned int paramCount; - unsigned int dataCount; - unsigned int subsCount; - - unsigned int codeAddr; - unsigned int jumpsAddr; - unsigned int paramAddr; - unsigned int dataAddr; - unsigned int subsAddr; -} Toy_Module; - -TOY_API Toy_Module Toy_parseModule(unsigned char* ptr); diff --git a/source/toy_value.c b/source/toy_value.c index 6d155a1..c6404a3 100644 --- a/source/toy_value.c +++ b/source/toy_value.c @@ -430,19 +430,17 @@ int Toy_compareValues(Toy_Value left, Toy_Value right) { Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) { MAYBE_UNWRAP(value); - //TODO: could have "constant" strings that can be referenced, instead of null, true, false, etc. - new string type of 'permanent' - switch(value.type) { case TOY_VALUE_NULL: - return Toy_createString(bucketHandle, ""); //TODO: remake "createString" to to handle params like this + return Toy_toString(bucketHandle, ""); case TOY_VALUE_BOOLEAN: - return Toy_createString(bucketHandle, value.as.boolean ? "" : ""); + return Toy_toString(bucketHandle, value.as.boolean ? "" : ""); case TOY_VALUE_INTEGER: { char buffer[16]; sprintf(buffer, "%d", value.as.integer); - return Toy_createString(bucketHandle, buffer); + return Toy_toString(bucketHandle, buffer); } case TOY_VALUE_FLOAT: { @@ -463,7 +461,7 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) { //wipe the trailing zeros while(decimal != length && buffer[length-1] == '0') buffer[--length] = '\0'; - return Toy_createStringLength(bucketHandle, buffer, length); + return Toy_toStringLength(bucketHandle, buffer, length); } case TOY_VALUE_STRING: @@ -475,14 +473,14 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) { //if array is empty, skip below if (ptr->count == 0) { - Toy_String* empty = Toy_createString(bucketHandle, "[]"); + Toy_String* empty = Toy_toString(bucketHandle, "[]"); return empty; } - Toy_String* open = Toy_createStringLength(bucketHandle, "[", 1); - Toy_String* close = Toy_createStringLength(bucketHandle, "]", 1); - Toy_String* comma = Toy_createStringLength(bucketHandle, ",", 1); //reusable - Toy_String* quote = Toy_createStringLength(bucketHandle, "\"", 1); //reusable + Toy_String* open = Toy_toStringLength(bucketHandle, "[", 1); + Toy_String* close = Toy_toStringLength(bucketHandle, "]", 1); + Toy_String* comma = Toy_toStringLength(bucketHandle, ",", 1); //reusable + Toy_String* quote = Toy_toStringLength(bucketHandle, "\"", 1); //reusable bool needsComma = false; Toy_String* string = open; @@ -538,15 +536,15 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) { //if table is empty, skip below if (ptr->count == 0) { - Toy_String* empty = Toy_createString(bucketHandle, "[:]"); + Toy_String* empty = Toy_toString(bucketHandle, "[:]"); return empty; } - Toy_String* open = Toy_createStringLength(bucketHandle, "[", 1); - Toy_String* close = Toy_createStringLength(bucketHandle, "]", 1); - Toy_String* colon = Toy_createStringLength(bucketHandle, ":", 1); //reusable - Toy_String* comma = Toy_createStringLength(bucketHandle, ",", 1); //reusable - Toy_String* quote = Toy_createStringLength(bucketHandle, "\"", 1); //reusable + Toy_String* open = Toy_toStringLength(bucketHandle, "[", 1); + Toy_String* close = Toy_toStringLength(bucketHandle, "]", 1); + Toy_String* colon = Toy_toStringLength(bucketHandle, ":", 1); //reusable + Toy_String* comma = Toy_toStringLength(bucketHandle, ",", 1); //reusable + Toy_String* quote = Toy_toStringLength(bucketHandle, "\"", 1); //reusable bool needsComma = false; Toy_String* string = open; @@ -626,7 +624,7 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) { case TOY_VALUE_FUNCTION: //dummy - return Toy_createString(bucketHandle, ""); + return Toy_toString(bucketHandle, ""); case TOY_VALUE_OPAQUE: case TOY_VALUE_ANY: diff --git a/source/toy_vm.c b/source/toy_vm.c index 6004081..bf408ea 100644 --- a/source/toy_vm.c +++ b/source/toy_vm.c @@ -73,12 +73,7 @@ static void processRead(Toy_VM* vm) { //build a string from the data section if (stringType == TOY_STRING_LEAF) { - value = TOY_VALUE_FROM_STRING(Toy_createString(&vm->memoryBucket, cstring)); - } - else if (stringType == TOY_STRING_NAME) { - Toy_ValueType valueType = TOY_VALUE_UNKNOWN; - - value = TOY_VALUE_FROM_STRING(Toy_createNameStringLength(&vm->memoryBucket, cstring, len, valueType, false)); + value = TOY_VALUE_FROM_STRING(Toy_toStringLength(&vm->memoryBucket, cstring, len)); } else { Toy_error("Invalid string type found in opcode read"); @@ -161,11 +156,8 @@ static void processRead(Toy_VM* vm) { unsigned int addr = (unsigned int)READ_INT(vm); - Toy_Module module = Toy_parseModule(vm->code + vm->subsAddr + addr); - module.parentScope = Toy_private_pushDummyScope(&vm->memoryBucket, vm->scope); - //create and push the function value - Toy_Function* function = Toy_createModuleFunction(&vm->memoryBucket, module); + Toy_Function* function = Toy_createFunctionFromBytecode(&vm->memoryBucket, vm->code + vm->subsAddr + addr); value = TOY_VALUE_FROM_FUNCTION(function); break; @@ -210,7 +202,7 @@ static void processDeclare(Toy_VM* vm) { char* cstring = (char*)(vm->code + vm->dataAddr + jump); //build the name string - Toy_String* name = Toy_createNameStringLength(&vm->memoryBucket, cstring, len, type, constant); + Toy_String* name = Toy_toStringLength(&vm->memoryBucket, cstring, len); //get the value Toy_Value value = Toy_popStack(&vm->stack); @@ -221,7 +213,7 @@ static void processDeclare(Toy_VM* vm) { } //declare it - Toy_declareScope(vm->scope, name, value); + Toy_declareScope(vm->scope, name, type, value, constant); //cleanup Toy_freeString(name); @@ -232,18 +224,20 @@ static void processAssign(Toy_VM* vm) { Toy_Value value = Toy_popStack(&vm->stack); Toy_Value name = Toy_popStack(&vm->stack); - //check name string type - if (!TOY_VALUE_IS_STRING(name) || TOY_VALUE_AS_STRING(name)->info.type != TOY_STRING_NAME) { - Toy_error("Invalid assignment target"); - Toy_freeValue(name); - Toy_freeValue(value); - return; - } + //TODO: remove 'TOY_STRING_NAME' entirely + // //check name string type + // if (!TOY_VALUE_IS_STRING(name) || TOY_VALUE_AS_STRING(name)->info.type != TOY_STRING_NAME) { + // Toy_error("Invalid assignment target"); + // Toy_freeValue(name); + // Toy_freeValue(value); + // return; + // } - //BUGFIX: only allowable type coersion - if (TOY_VALUE_AS_STRING(name)->name.varType == TOY_VALUE_FLOAT && value.type == TOY_VALUE_INTEGER) { - value = TOY_VALUE_FROM_FLOAT( (float)TOY_VALUE_AS_INTEGER(value) ); - } + // //FIXME + // //BUGFIX: only allowable type coersion + // if (TOY_VALUE_AS_STRING(name)->name.varType == TOY_VALUE_FLOAT && value.type == TOY_VALUE_INTEGER) { + // value = TOY_VALUE_FROM_FLOAT( (float)TOY_VALUE_AS_INTEGER(value) ); + // } //assign it Toy_assignScope(vm->scope, TOY_VALUE_AS_STRING(name), value); //scope now owns the value, doesn't need to be freed @@ -265,7 +259,7 @@ static void processAssignCompound(Toy_VM* vm) { Toy_Value target = Toy_popStack(&vm->stack); //shake out variable names - if (TOY_VALUE_IS_STRING(target) && TOY_VALUE_AS_STRING(target)->info.type == TOY_STRING_NAME) { + if (TOY_VALUE_IS_STRING(target)) { Toy_Value* valuePtr = Toy_accessScopeAsPointer(vm->scope, TOY_VALUE_AS_STRING(target)); Toy_freeValue(target); if (valuePtr == NULL) { @@ -344,12 +338,12 @@ static void processAssignCompound(Toy_VM* vm) { static void processAccess(Toy_VM* vm) { Toy_Value name = Toy_popStack(&vm->stack); - //check name string type - if (!TOY_VALUE_IS_STRING(name) || TOY_VALUE_AS_STRING(name)->info.type != TOY_STRING_NAME) { - Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL()); - Toy_error("Invalid access target"); - return; - } + // //check name string type + // if (!TOY_VALUE_IS_STRING(name) || TOY_VALUE_AS_STRING(name)->info.type != TOY_STRING_NAME) { + // Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL()); + // Toy_error("Invalid access target"); + // return; + // } //find the value Toy_Value* valuePtr = Toy_accessScopeAsPointer(vm->scope, TOY_VALUE_AS_STRING(name)); @@ -397,13 +391,14 @@ static void processInvoke(Toy_VM* vm) { Toy_Function* fn = TOY_VALUE_AS_FUNCTION(value); switch(fn->type) { - case TOY_FUNCTION_MODULE: { - Toy_Module module = fn->module.module; - - //NOTE: counts within the modules actually specify size in memory, so the argCount is multiplied by 8 for the 8 bytes used in the params table + case TOY_FUNCTION_CUSTOM: { + //spin up a new sub-vm + Toy_VM subVM; + Toy_inheritVM(&subVM, vm); + Toy_bindVM(&subVM, fn->bytecode.code, false); //check args count - if (argCount * 8 != module.paramCount) { + if (argCount * 8 != subVM.paramCount) { Toy_error("Incorrect number of parameters specified for function call"); break; } @@ -413,26 +408,21 @@ static void processInvoke(Toy_VM* vm) { break; } - //spin up a new sub-vm - Toy_VM subVM; - Toy_inheritVM(&subVM, vm); - Toy_bindVM(&subVM, &module, false); - //inject params, backwards from the stack for (unsigned int i = argCount; i > 0; i--) { Toy_Value argValue = Toy_popStack(&vm->stack); //paramAddr is relative to the data section, and is followed by the param type - unsigned int paramAddr = ((unsigned int*)(module.code + module.paramAddr))[(i-1)*2]; - Toy_ValueType paramType = (Toy_ValueType)(((unsigned int*)(module.code + module.paramAddr))[(i-1)*2 + 1]); + unsigned int paramAddr = ((unsigned int*)(subVM.code + subVM.paramAddr))[(i-1)*2]; + Toy_ValueType paramType = (Toy_ValueType)(((unsigned int*)(subVM.code + subVM.paramAddr))[(i-1)*2 + 1]); //c-string of the param's name - const char* cstr = ((char*)(module.code + module.dataAddr)) + paramAddr; + const char* cstr = ((char*)(subVM.code + subVM.dataAddr)) + paramAddr; //as a name string - Toy_String* name = Toy_createNameStringLength(&subVM.memoryBucket, cstr, strlen(cstr), paramType, true); + Toy_String* name = Toy_toStringLength(&subVM.memoryBucket, cstr, strlen(cstr)); - Toy_declareScope(subVM.scope, name, argValue); + Toy_declareScope(subVM.scope, name, paramType, argValue, true); } //run @@ -723,7 +713,7 @@ static void processAssert(Toy_VM* vm) { //determine the args if (count == 1) { - message = TOY_VALUE_FROM_STRING(Toy_createString(&vm->memoryBucket, "assertion failed")); //TODO: needs a better default message + message = TOY_VALUE_FROM_STRING(Toy_toString(&vm->memoryBucket, "assertion failed")); //TODO: needs a better default message value = Toy_popStack(&vm->stack); } else if (count == 2) { @@ -739,7 +729,7 @@ static void processAssert(Toy_VM* vm) { if (TOY_VALUE_IS_NULL(value) || Toy_checkValueIsTruthy(value) != true) { //on a failure, print the message Toy_String* string = Toy_stringifyValue(&vm->memoryBucket, message); - char* buffer = Toy_getStringRawBuffer(string); + char* buffer = Toy_getStringRaw(string); Toy_assertFailure(buffer); @@ -757,7 +747,7 @@ static void processPrint(Toy_VM* vm) { //print the value on top of the stack, popping it Toy_Value value = Toy_popStack(&vm->stack); Toy_String* string = Toy_stringifyValue(&vm->memoryBucket, value); - char* buffer = Toy_getStringRawBuffer(string); //TODO: check string type to skip this call + char* buffer = Toy_getStringRaw(string); //TODO: check string type to skip this call Toy_print(buffer); @@ -847,11 +837,11 @@ static void processIndex(Toy_VM* vm) { //extract cstring, based on type if (str->info.type == TOY_STRING_LEAF) { const char* cstr = str->leaf.data; - result = Toy_createStringLength(&vm->memoryBucket, cstr + i, l); + result = Toy_toStringLength(&vm->memoryBucket, cstr + i, l); } else if (str->info.type == TOY_STRING_NODE) { - char* cstr = Toy_getStringRawBuffer(str); - result = Toy_createStringLength(&vm->memoryBucket, cstr + i, l); + char* cstr = Toy_getStringRaw(str); + result = Toy_toStringLength(&vm->memoryBucket, cstr + i, l); free(cstr); } else { @@ -1113,28 +1103,41 @@ void Toy_inheritVM(Toy_VM* vm, Toy_VM* parent) { Toy_resetVM(vm, true); } -void Toy_bindVM(Toy_VM* vm, Toy_Module* module, bool preserveScope) { - vm->code = module->code; +void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, bool preserveScope) { + vm->code = bytecode; //set code, so it can be read - vm->jumpsCount = module->jumpsCount; - vm->paramCount = module->paramCount; - vm->dataCount = module->dataCount; - vm->subsCount = module->subsCount; + (void)READ_UNSIGNED_INT(vm); //global header - vm->codeAddr = module->codeAddr; - vm->jumpsAddr = module->jumpsAddr; - vm->paramAddr = module->paramAddr; - vm->dataAddr = module->dataAddr; - vm->subsAddr = module->subsAddr; + //section headers + vm->jumpsCount = READ_UNSIGNED_INT(vm); + vm->paramCount = READ_UNSIGNED_INT(vm); + vm->dataCount = READ_UNSIGNED_INT(vm); + vm->subsCount = READ_UNSIGNED_INT(vm); + //section locations + vm->codeAddr = READ_UNSIGNED_INT(vm); + if (vm->jumpsCount) { + vm->jumpsAddr = READ_UNSIGNED_INT(vm); + } + if (vm->paramCount) { + vm->paramAddr = READ_UNSIGNED_INT(vm); + } + if (vm->dataCount) { + vm->dataAddr = READ_UNSIGNED_INT(vm); + } + if (vm->subsCount) { + vm->subsAddr = READ_UNSIGNED_INT(vm); + } + + //scopes if (preserveScope == false) { - vm->scope = Toy_pushScope(&vm->memoryBucket, module->parentScope); + vm->scope = Toy_pushScope(&vm->memoryBucket, NULL); } } unsigned int Toy_runVM(Toy_VM* vm) { if (vm->codeAddr == 0) { - //ignore uninitialized VMs or empty modules + //ignore uninitialized VMs or empty bytecode return 0; } diff --git a/source/toy_vm.h b/source/toy_vm.h index ee8e92e..a6ce92e 100644 --- a/source/toy_vm.h +++ b/source/toy_vm.h @@ -4,7 +4,6 @@ #include "toy_bucket.h" #include "toy_scope.h" -#include "toy_module.h" #include "toy_value.h" #include "toy_string.h" @@ -48,7 +47,7 @@ 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 scope bucket -TOY_API void Toy_bindVM(Toy_VM* vm, Toy_Module* module, bool preserveScope); +void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, bool preserveScope); TOY_API unsigned int Toy_runVM(Toy_VM* vm); TOY_API void Toy_freeVM(Toy_VM* vm);