Implemented assert keyword, read more

The assert keyword works, but I want to add a cmd option to suppress or
disable the errors.

The tests need some serious TLC. I know that, but I'm kicking it down
the road for now.
This commit is contained in:
2024-11-09 17:41:29 +11:00
parent 1925d41940
commit 1608a13b43
9 changed files with 189 additions and 71 deletions

View File

@@ -95,6 +95,16 @@ void Toy_private_emitAstCompound(Toy_Bucket** bucketHandle, Toy_Ast** astHandle,
(*astHandle) = tmp; (*astHandle) = tmp;
} }
void Toy_private_emitAstAssert(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* child, Toy_Ast* msg) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_ASSERT;
tmp->assert.child = child;
tmp->assert.message = msg;
(*astHandle) = tmp;
}
void Toy_private_emitAstPrint(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) { void Toy_private_emitAstPrint(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast)); Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));

View File

@@ -17,6 +17,7 @@ typedef enum Toy_AstType {
TOY_AST_GROUP, TOY_AST_GROUP,
TOY_AST_COMPOUND, TOY_AST_COMPOUND,
TOY_AST_ASSERT,
TOY_AST_PRINT, TOY_AST_PRINT,
TOY_AST_VAR_DECLARE, TOY_AST_VAR_DECLARE,
@@ -116,6 +117,12 @@ typedef struct Toy_AstCompound {
Toy_Ast* right; Toy_Ast* right;
} Toy_AstCompound; } Toy_AstCompound;
typedef struct Toy_AstAssert {
Toy_AstType type;
Toy_Ast* child;
Toy_Ast* message;
} Toy_AstAssert;
typedef struct Toy_AstPrint { typedef struct Toy_AstPrint {
Toy_AstType type; Toy_AstType type;
Toy_Ast* child; Toy_Ast* child;
@@ -160,6 +167,7 @@ union Toy_Ast { //32 | 64 BITNESS
Toy_AstCompare compare; //16 | 24 Toy_AstCompare compare; //16 | 24
Toy_AstGroup group; //8 | 16 Toy_AstGroup group; //8 | 16
Toy_AstCompound compound; //16 | 24 Toy_AstCompound compound; //16 | 24
Toy_AstAssert assert; //16 | 24
Toy_AstPrint print; //8 | 16 Toy_AstPrint print; //8 | 16
Toy_AstVarDeclare varDeclare; //16 | 24 Toy_AstVarDeclare varDeclare; //16 | 24
Toy_AstVarAssign varAssign; //16 | 24 Toy_AstVarAssign varAssign; //16 | 24
@@ -179,6 +187,7 @@ void Toy_private_emitAstCompare(Toy_Bucket** bucketHandle, Toy_Ast** astHandle,T
void Toy_private_emitAstGroup(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstGroup(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstCompound(Toy_Bucket** bucketHandle, Toy_Ast** astHandle,Toy_AstFlag flag, Toy_Ast* right); void Toy_private_emitAstCompound(Toy_Bucket** bucketHandle, Toy_Ast** astHandle,Toy_AstFlag flag, Toy_Ast* right);
void Toy_private_emitAstAssert(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_Ast* child, Toy_Ast* msg);
void Toy_private_emitAstPrint(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstPrint(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstVariableDeclaration(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_Ast* expr); void Toy_private_emitAstVariableDeclaration(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_Ast* expr);

View File

@@ -37,6 +37,7 @@ typedef enum Toy_OpcodeType {
TOY_OPCODE_SCOPE_POP, TOY_OPCODE_SCOPE_POP,
//various action instructions //various action instructions
TOY_OPCODE_ASSERT,
TOY_OPCODE_PRINT, TOY_OPCODE_PRINT,
TOY_OPCODE_CONCAT, TOY_OPCODE_CONCAT,
TOY_OPCODE_INDEX, TOY_OPCODE_INDEX,

View File

@@ -195,7 +195,7 @@ static ParsingTuple parsingRulesetTable[] = {
//structural operators //structural operators
{PREC_NONE,group,NULL},// TOY_TOKEN_OPERATOR_PAREN_LEFT, {PREC_NONE,group,NULL},// TOY_TOKEN_OPERATOR_PAREN_LEFT,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_PAREN_RIGHT, {PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_PAREN_RIGHT,
{PREC_CALL,NULL,compound},// TOY_TOKEN_OPERATOR_BRACKET_LEFT, {PREC_GROUP,NULL,compound},// TOY_TOKEN_OPERATOR_BRACKET_LEFT,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_BRACKET_RIGHT, {PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_BRACKET_RIGHT,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_BRACE_LEFT, {PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_BRACE_LEFT,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_BRACE_RIGHT, {PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_BRACE_RIGHT,
@@ -208,7 +208,7 @@ static ParsingTuple parsingRulesetTable[] = {
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_COLON, {PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_COLON,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_SEMICOLON, // ; {PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_SEMICOLON, // ;
{PREC_CALL,NULL,compound},// TOY_TOKEN_OPERATOR_COMMA, // , {PREC_GROUP,NULL,compound},// TOY_TOKEN_OPERATOR_COMMA, // ,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_DOT, // . {PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_DOT, // .
{PREC_CALL,NULL,binary},// TOY_TOKEN_OPERATOR_CONCAT, // .. {PREC_CALL,NULL,binary},// TOY_TOKEN_OPERATOR_CONCAT, // ..
@@ -563,11 +563,11 @@ static Toy_AstFlag compound(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_A
advance(parser); advance(parser);
if (parser->previous.type == TOY_TOKEN_OPERATOR_COMMA) { if (parser->previous.type == TOY_TOKEN_OPERATOR_COMMA) {
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1); parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP);
return TOY_AST_FLAG_COMPOUND_COLLECTION; return TOY_AST_FLAG_COMPOUND_COLLECTION;
} }
else if (parser->previous.type == TOY_TOKEN_OPERATOR_BRACKET_LEFT) { else if (parser->previous.type == TOY_TOKEN_OPERATOR_BRACKET_LEFT) {
parsePrecedence(bucketHandle, parser, rootHandle, PREC_ASSIGNMENT + 1); parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP);
consume(parser, TOY_TOKEN_OPERATOR_BRACKET_RIGHT, "Expected ']' at the end of index expression"); consume(parser, TOY_TOKEN_OPERATOR_BRACKET_RIGHT, "Expected ']' at the end of index expression");
return TOY_AST_FLAG_COMPOUND_INDEX; return TOY_AST_FLAG_COMPOUND_INDEX;
} }
@@ -655,6 +655,21 @@ static void makeExpr(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** ro
//forward declarations //forward declarations
static void makeBlockStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle); static void makeBlockStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle);
static void makeAssertStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
Toy_Ast* ast = NULL; //assert's emit function is a bit different
makeExpr(bucketHandle, parser, &ast);
//NOTE: if it's a compound, then it's got a second arg
if (ast->type == TOY_AST_COMPOUND) {
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast->compound.left, ast->compound.right);
}
else {
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast, NULL);
}
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of assert statement");
}
static void makePrintStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) { static void makePrintStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
makeExpr(bucketHandle, parser, rootHandle); makeExpr(bucketHandle, parser, rootHandle);
Toy_private_emitAstPrint(bucketHandle, rootHandle); Toy_private_emitAstPrint(bucketHandle, rootHandle);
@@ -715,7 +730,11 @@ static void makeStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** ro
return; return;
} }
//assert else if (match(parser, TOY_TOKEN_KEYWORD_ASSERT)) {
makeAssertStmt(bucketHandle, parser, rootHandle);
return;
}
//if-then-else //if-then-else
//while-then //while-then
//for-pre-clause-post-then //for-pre-clause-post-then

View File

@@ -280,6 +280,22 @@ static unsigned int writeInstructionCompound(Toy_Routine** rt, Toy_AstCompound a
} }
} }
static unsigned int writeInstructionAssert(Toy_Routine** rt, Toy_AstAssert ast) {
//the thing to print
writeRoutineCode(rt, ast.child);
writeRoutineCode(rt, ast.message);
//output the print opcode
EMIT_BYTE(rt, code, TOY_OPCODE_ASSERT);
//4-byte alignment
EMIT_BYTE(rt, code, ast.message != NULL ? 2 : 1); //arg count
EMIT_BYTE(rt, code,0);
EMIT_BYTE(rt, code,0);
return 0;
}
static unsigned int writeInstructionPrint(Toy_Routine** rt, Toy_AstPrint ast) { static unsigned int writeInstructionPrint(Toy_Routine** rt, Toy_AstPrint ast) {
//the thing to print //the thing to print
writeRoutineCode(rt, ast.child); writeRoutineCode(rt, ast.child);
@@ -504,6 +520,10 @@ static unsigned int writeRoutineCode(Toy_Routine** rt, Toy_Ast* ast) {
result += writeInstructionCompound(rt, ast->compound); result += writeInstructionCompound(rt, ast->compound);
break; break;
case TOY_AST_ASSERT:
result += writeInstructionAssert(rt, ast->assert);
break;
case TOY_AST_PRINT: case TOY_AST_PRINT:
result += writeInstructionPrint(rt, ast->print); result += writeInstructionPrint(rt, ast->print);
break; break;

View File

@@ -2,7 +2,9 @@
#include "toy_console_colors.h" #include "toy_console_colors.h"
#include "toy_string.h" #include "toy_string.h"
#include "toy_print.h"
#include <stdio.h>
#include <stdlib.h>
//utils //utils
static unsigned int hashUInt(unsigned int x) { static unsigned int hashUInt(unsigned int x) {
@@ -37,10 +39,10 @@ unsigned int Toy_hashValue(Toy_Value value) {
case TOY_VALUE_TYPE: case TOY_VALUE_TYPE:
case TOY_VALUE_ANY: case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN: case TOY_VALUE_UNKNOWN:
break; fprintf(stderr, TOY_CC_ERROR "ERROR: Can't hash an unknown value type, exiting\n" TOY_CC_RESET);
exit(-1);
} }
Toy_error(TOY_CC_ERROR "ERROR: Can't hash an unknown value type\n" TOY_CC_RESET);
return 0; return 0;
} }
@@ -64,11 +66,11 @@ Toy_Value Toy_copyValue(Toy_Value value) {
case TOY_VALUE_TYPE: case TOY_VALUE_TYPE:
case TOY_VALUE_ANY: case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN: case TOY_VALUE_UNKNOWN:
break; fprintf(stderr, TOY_CC_ERROR "ERROR: Can't copy an unknown value type, exiting\n" TOY_CC_RESET);
exit(-1);
} }
//dummy return //dummy return
Toy_error(TOY_CC_ERROR "ERROR: Can't copy an unknown value type\n" TOY_CC_RESET);
return TOY_VALUE_FROM_NULL(); return TOY_VALUE_FROM_NULL();
} }
@@ -93,14 +95,15 @@ void Toy_freeValue(Toy_Value value) {
case TOY_VALUE_TYPE: case TOY_VALUE_TYPE:
case TOY_VALUE_ANY: case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN: case TOY_VALUE_UNKNOWN:
Toy_error(TOY_CC_ERROR "ERROR: Can't free an unknown type\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "ERROR: Can't free an unknown value type, exiting\n" TOY_CC_RESET);
exit(-1);
} }
} }
bool Toy_checkValueIsTruthy(Toy_Value value) { bool Toy_checkValueIsTruthy(Toy_Value value) {
//null is an error //null is an error
if (TOY_VALUE_IS_NULL(value)) { if (TOY_VALUE_IS_NULL(value)) {
Toy_error(TOY_CC_ERROR "ERROR: 'null' is neither true nor false\n" TOY_CC_RESET); Toy_error("'null' is neither true nor false");
return false; return false;
} }
@@ -158,10 +161,10 @@ bool Toy_checkValuesAreEqual(Toy_Value left, Toy_Value right) {
case TOY_VALUE_TYPE: case TOY_VALUE_TYPE:
case TOY_VALUE_ANY: case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN: case TOY_VALUE_UNKNOWN:
break; fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown types in value equality, exiting\n" TOY_CC_RESET);
exit(-1);
} }
Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value equality\n" TOY_CC_RESET);
return false; return false;
} }
@@ -187,10 +190,10 @@ bool Toy_checkValuesAreComparable(Toy_Value left, Toy_Value right) {
case TOY_VALUE_TYPE: case TOY_VALUE_TYPE:
case TOY_VALUE_ANY: case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN: case TOY_VALUE_UNKNOWN:
break; fprintf(stderr, TOY_CC_ERROR "Unknown types in value comparison check, exiting\n" TOY_CC_RESET);
exit(-1);
} }
Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value comparison check\n" TOY_CC_RESET);
return false; return false;
} }
@@ -235,9 +238,64 @@ int Toy_compareValues(Toy_Value left, Toy_Value right) {
case TOY_VALUE_TYPE: case TOY_VALUE_TYPE:
case TOY_VALUE_ANY: case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN: case TOY_VALUE_UNKNOWN:
break; fprintf(stderr, TOY_CC_ERROR "Unknown types in value comparison, exiting\n" TOY_CC_RESET);
exit(-1);
} }
Toy_error(TOY_CC_ERROR "ERROR: Unknown types in value comparison\n" TOY_CC_RESET);
return -1; return -1;
} }
void Toy_stringifyValue(Toy_Value value, Toy_callbackType callback) {
//NOTE: don't append a newline
switch(value.type) {
case TOY_VALUE_NULL:
callback("null");
break;
case TOY_VALUE_BOOLEAN:
callback(TOY_VALUE_AS_BOOLEAN(value) ? "true" : "false");
break;
case TOY_VALUE_INTEGER: {
char buffer[16];
sprintf(buffer, "%d", TOY_VALUE_AS_INTEGER(value));
callback(buffer);
break;
}
case TOY_VALUE_FLOAT: {
char buffer[16];
sprintf(buffer, "%f", TOY_VALUE_AS_FLOAT(value));
callback(buffer);
break;
}
case TOY_VALUE_STRING: {
Toy_String* str = TOY_VALUE_AS_STRING(value);
//TODO: decide on how long strings, etc. live for in memory
if (str->type == TOY_STRING_NODE) {
char* buffer = Toy_getStringRawBuffer(str);
callback(buffer);
free(buffer);
}
else if (str->type == TOY_STRING_LEAF) {
callback(str->as.leaf.data);
}
else if (str->type == TOY_STRING_NAME) {
callback(str->as.name.data); //should this be a thing?
}
break;
}
case TOY_VALUE_ARRAY:
case TOY_VALUE_TABLE:
case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE:
case TOY_VALUE_TYPE:
case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN:
fprintf(stderr, TOY_CC_ERROR "Unknown types in value stringify, exiting\n" TOY_CC_RESET);
exit(-1);
}
}

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "toy_common.h" #include "toy_common.h"
#include "toy_print.h"
//forward declarations //forward declarations
struct Toy_String; struct Toy_String;
@@ -67,3 +68,6 @@ TOY_API bool Toy_checkValueIsTruthy(Toy_Value value);
TOY_API bool Toy_checkValuesAreEqual(Toy_Value left, Toy_Value right); TOY_API bool Toy_checkValuesAreEqual(Toy_Value left, Toy_Value right);
TOY_API bool Toy_checkValuesAreComparable(Toy_Value left, Toy_Value right); TOY_API bool Toy_checkValuesAreComparable(Toy_Value left, Toy_Value right);
TOY_API int Toy_compareValues(Toy_Value left, Toy_Value right); TOY_API int Toy_compareValues(Toy_Value left, Toy_Value right);
//convert the value to a string, then forward it to a callback
TOY_API void Toy_stringifyValue(Toy_Value value, Toy_callbackType callback);

View File

@@ -177,6 +177,7 @@ static void processAssign(Toy_VM* vm) {
//cleanup //cleanup
Toy_freeValue(name); Toy_freeValue(name);
} }
static void processAccess(Toy_VM* vm) { static void processAccess(Toy_VM* vm) {
Toy_Value name = Toy_popStack(&vm->stack); Toy_Value name = Toy_popStack(&vm->stack);
@@ -348,62 +349,42 @@ static void processLogical(Toy_VM* vm, Toy_OpcodeType opcode) {
} }
} }
static void processAssert(Toy_VM* vm) {
unsigned int count = READ_BYTE(vm);
Toy_Value value = TOY_VALUE_FROM_NULL();
Toy_Value message = TOY_VALUE_FROM_NULL();
//determine the args
if (count == 1) {
message = TOY_VALUE_FROM_STRING(Toy_createString(&vm->stringBucket, "assertion failed"));
value = Toy_popStack(&vm->stack);
}
else if (count == 2) {
message = Toy_popStack(&vm->stack);
value = Toy_popStack(&vm->stack);
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid assert argument count %d found, exiting\n" TOY_CC_RESET, (int)count);
exit(-1);
}
//do the check
if (TOY_VALUE_IS_NULL(value) || Toy_checkValueIsTruthy(value) == false) {
//on a failure, print the message
Toy_stringifyValue(message, Toy_error);
}
//cleanup
Toy_freeValue(value);
Toy_freeValue(message);
}
static void processPrint(Toy_VM* vm) { static void processPrint(Toy_VM* vm) {
//print the value on top of the stack, popping it //print the value on top of the stack, popping it
Toy_Value value = Toy_popStack(&vm->stack); Toy_Value value = Toy_popStack(&vm->stack);
Toy_stringifyValue(value, Toy_print);
//NOTE: don't append a newline - leave that choice to the host Toy_freeValue(value);
switch(value.type) {
case TOY_VALUE_NULL:
Toy_print("null");
break;
case TOY_VALUE_BOOLEAN:
Toy_print(TOY_VALUE_AS_BOOLEAN(value) ? "true" : "false");
break;
case TOY_VALUE_INTEGER: {
char buffer[16];
sprintf(buffer, "%d", TOY_VALUE_AS_INTEGER(value));
Toy_print(buffer);
break;
}
case TOY_VALUE_FLOAT: {
char buffer[16];
sprintf(buffer, "%f", TOY_VALUE_AS_FLOAT(value));
Toy_print(buffer);
break;
}
case TOY_VALUE_STRING: {
Toy_String* str = TOY_VALUE_AS_STRING(value);
//TODO: decide on how long strings, etc. live for in memory
if (str->type == TOY_STRING_NODE) {
char* buffer = Toy_getStringRawBuffer(str);
Toy_print(buffer);
free(buffer);
}
else if (str->type == TOY_STRING_LEAF) {
Toy_print(str->as.leaf.data);
}
else if (str->type == TOY_STRING_NAME) {
Toy_print(str->as.name.data); //should this be a thing?
}
break;
}
case TOY_VALUE_ARRAY:
case TOY_VALUE_TABLE:
case TOY_VALUE_FUNCTION:
case TOY_VALUE_OPAQUE:
case TOY_VALUE_TYPE:
case TOY_VALUE_ANY:
case TOY_VALUE_UNKNOWN:
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown value type %d passed to processPrint, exiting\n" TOY_CC_RESET, value.type);
exit(-1);
}
} }
static void processConcat(Toy_VM* vm) { static void processConcat(Toy_VM* vm) {
@@ -447,11 +428,17 @@ static void processIndex(Toy_VM* vm) {
//type checks //type checks
if (!TOY_VALUE_IS_INTEGER(index)) { if (!TOY_VALUE_IS_INTEGER(index)) {
Toy_error("Failed to index a string"); Toy_error("Failed to index a string");
Toy_freeValue(value);
Toy_freeValue(index);
Toy_freeValue(length);
return; return;
} }
if (!(TOY_VALUE_IS_NULL(length) || TOY_VALUE_IS_INTEGER(length))) { if (!(TOY_VALUE_IS_NULL(length) || TOY_VALUE_IS_INTEGER(length))) {
Toy_error("Failed to index-length a string"); Toy_error("Failed to index-length a string");
Toy_freeValue(value);
Toy_freeValue(index);
Toy_freeValue(length);
return; return;
} }
@@ -486,6 +473,10 @@ static void processIndex(Toy_VM* vm) {
fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown value type %d found in processIndex, exiting\n" TOY_CC_RESET, value.type); fprintf(stderr, TOY_CC_ERROR "ERROR: Unknown value type %d found in processIndex, exiting\n" TOY_CC_RESET, value.type);
exit(-1); exit(-1);
} }
Toy_freeValue(value);
Toy_freeValue(index);
Toy_freeValue(length);
} }
static void process(Toy_VM* vm) { static void process(Toy_VM* vm) {
@@ -554,6 +545,10 @@ static void process(Toy_VM* vm) {
break; break;
//various action instructions //various action instructions
case TOY_OPCODE_ASSERT:
processAssert(vm);
break;
case TOY_OPCODE_PRINT: case TOY_OPCODE_PRINT:
processPrint(vm); processPrint(vm);
break; break;

View File

@@ -23,6 +23,7 @@ int test_sizeof_ast_64bit() {
TEST_SIZEOF(Toy_AstCompare, 24); TEST_SIZEOF(Toy_AstCompare, 24);
TEST_SIZEOF(Toy_AstGroup, 16); TEST_SIZEOF(Toy_AstGroup, 16);
TEST_SIZEOF(Toy_AstCompound, 24); TEST_SIZEOF(Toy_AstCompound, 24);
TEST_SIZEOF(Toy_AstAssert, 24);
TEST_SIZEOF(Toy_AstPrint, 16); TEST_SIZEOF(Toy_AstPrint, 16);
TEST_SIZEOF(Toy_AstVarDeclare, 24); TEST_SIZEOF(Toy_AstVarDeclare, 24);
TEST_SIZEOF(Toy_AstVarAssign, 24); TEST_SIZEOF(Toy_AstVarAssign, 24);
@@ -56,6 +57,7 @@ int test_sizeof_ast_32bit() {
TEST_SIZEOF(Toy_AstCompare, 16); TEST_SIZEOF(Toy_AstCompare, 16);
TEST_SIZEOF(Toy_AstGroup, 8); TEST_SIZEOF(Toy_AstGroup, 8);
TEST_SIZEOF(Toy_AstCompound, 16); TEST_SIZEOF(Toy_AstCompound, 16);
TEST_SIZEOF(Toy_AstAssert, 12);
TEST_SIZEOF(Toy_AstPrint, 8); TEST_SIZEOF(Toy_AstPrint, 8);
TEST_SIZEOF(Toy_AstVarDeclare, 12); TEST_SIZEOF(Toy_AstVarDeclare, 12);
TEST_SIZEOF(Toy_AstVarAssign, 16); TEST_SIZEOF(Toy_AstVarAssign, 16);