diff --git a/scripts/small.toy b/scripts/small.toy index 96acd6f..d18ddcb 100644 --- a/scripts/small.toy +++ b/scripts/small.toy @@ -1,9 +1,14 @@ import compound; +fn p(x) { + print x; +}; + fn f(acc, k, v) { - return acc + v; + acc(v); + return acc; } var a = [1, 2, 3, 4]; -print a.reduce(0, f); //prints "10" \ No newline at end of file +a.reduce(p, f); //prints "10" \ No newline at end of file diff --git a/source/toy_compiler.c b/source/toy_compiler.c index f28cef9..335c453 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -15,6 +15,7 @@ void Toy_initCompiler(Toy_Compiler* compiler) { compiler->bytecode = NULL; compiler->capacity = 0; compiler->count = 0; + compiler->panic = false; } //separated out, so it can be recursive @@ -133,6 +134,7 @@ static int writeNodeCompoundToCache(Toy_Compiler* compiler, Toy_ASTNode* node) { index = Toy_pushLiteralArray(&compiler->literalCache, literal); Toy_freeLiteral(literal); } + else if (node->compound.literalType == TOY_LITERAL_ARRAY) { //ensure each literal value is in the cache, individually for (int i = 0; i < node->compound.count; i++) { @@ -160,7 +162,7 @@ static int writeNodeCompoundToCache(Toy_Compiler* compiler, Toy_ASTNode* node) { break; default: - fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized node type in writeNodeCompoundToCache()" TOY_CC_RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized node type in writeNodeCompoundToCache()\n" TOY_CC_RESET); return -1; } } @@ -172,7 +174,8 @@ static int writeNodeCompoundToCache(Toy_Compiler* compiler, Toy_ASTNode* node) { Toy_freeLiteral(literal); } else { - fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized compound type in writeNodeCompoundToCache()" TOY_CC_RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized compound type in writeNodeCompoundToCache()\n" TOY_CC_RESET); + return -1; } return index; @@ -333,7 +336,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode break; case TOY_AST_NODE_TERNARY: { - // TODO + // TODO: a ?: b; //process the condition Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->ternary.condition, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode); @@ -402,6 +405,11 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode case TOY_AST_NODE_COMPOUND: { int index = writeNodeCompoundToCache(compiler, node); + if (index < 0) { + compiler->panic = true; + return TOY_OP_EOF; + } + //push the node opcode to the bytecode if (index >= 256) { //push a "long" index @@ -469,6 +477,11 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte } + //adopt the panic state if anything happened + if (fnCompiler->panic) { + compiler->panic = true; + } + //create the function in the literal cache (by storing the compiler object) Toy_Literal fnLiteral = TOY_TO_FUNCTION_LITERAL(fnCompiler, 0); fnLiteral.type = TOY_LITERAL_FUNCTION_INTERMEDIATE; //NOTE: changing type @@ -505,6 +518,11 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode case TOY_AST_NODE_FN_COLLECTION: { //embed these in the bytecode... unsigned short index = (unsigned short)writeNodeCollectionToCache(compiler, node); + + if (index == (unsigned short)-1) { + compiler->panic = true; + return TOY_OP_EOF; + } memcpy(compiler->bytecode + compiler->count, &index, sizeof(index)); compiler->count += sizeof(unsigned short); @@ -755,7 +773,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode case TOY_AST_NODE_BREAK: { if (!breakAddressesPtr) { - fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Can't place a break statement here\n" TOY_CC_RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Can't place a break statement here\n" TOY_CC_RESET); break; } @@ -773,7 +791,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode case TOY_AST_NODE_CONTINUE: { if (!continueAddressesPtr) { - fprintf(stderr, TOY_CC_ERROR "TOY_CC_ERROR: Can't place a continue statement here\n" TOY_CC_RESET); + fprintf(stderr, TOY_CC_ERROR "[internal] Can't place a continue statement here\n" TOY_CC_RESET); break; } @@ -1008,6 +1026,11 @@ static void emitFloat(unsigned char** collationPtr, int* capacityPtr, int* count //return the result static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size, bool embedHeader) { + if (compiler->panic) { + fprintf(stderr, TOY_CC_ERROR "[internal] Can't collate a panicked compiler\n" TOY_CC_RESET); + return NULL; + } + int capacity = TOY_GROW_CAPACITY(0); int count = 0; unsigned char* collation = TOY_ALLOCATE(unsigned char, capacity); diff --git a/source/toy_compiler.h b/source/toy_compiler.h index c206d5b..08b8d44 100644 --- a/source/toy_compiler.h +++ b/source/toy_compiler.h @@ -11,6 +11,7 @@ typedef struct Toy_Compiler { unsigned char* bytecode; int capacity; int count; + bool panic; } Toy_Compiler; TOY_API void Toy_initCompiler(Toy_Compiler* compiler);