Added negate opcode to equality opcode, in the second byte

This commit is contained in:
2024-10-03 10:15:58 +10:00
parent 5db3e407b1
commit ab1c9b941f
8 changed files with 74 additions and 26 deletions

View File

@@ -262,5 +262,3 @@ int main(int argc, const char* argv[]) {
return 0; return 0;
} }
//TODO: simple and consistent way to print an AST and Toy_Value

View File

@@ -16,7 +16,6 @@ SRC_SOURCEFILES=$(wildcard $(SRC_SOURCEDIR)/*.c)
SRC_OBJFILES=$(addprefix $(SRC_OBJDIR)/,$(notdir $(SRC_SOURCEFILES:.c=.o))) SRC_OBJFILES=$(addprefix $(SRC_OBJDIR)/,$(notdir $(SRC_SOURCEFILES:.c=.o)))
SRC_TARGETNAME=Toy SRC_TARGETNAME=Toy
#TODO: fix windows & macos
#SRC_LIBLINE is a fancy way of making the linker work correctly #SRC_LIBLINE is a fancy way of making the linker work correctly
ifeq ($(shell uname),Linux) ifeq ($(shell uname),Linux)
SRC_TARGETEXT=.so SRC_TARGETEXT=.so

View File

@@ -42,7 +42,6 @@ void Toy_private_emitAstValue(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Value v
(*handle) = tmp; (*handle) = tmp;
} }
//TODO: flag range checks
void Toy_private_emitAstUnary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag) { void Toy_private_emitAstUnary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast)); Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucket, sizeof(Toy_Ast));

View File

@@ -167,12 +167,7 @@ static void writeInstructionBinary(Toy_Routine** rt, Toy_AstBinary ast) {
} }
else if (ast.flag == TOY_AST_FLAG_COMPARE_NOT) { else if (ast.flag == TOY_AST_FLAG_COMPARE_NOT) {
EMIT_BYTE(rt, TOY_OPCODE_COMPARE_EQUAL); EMIT_BYTE(rt, TOY_OPCODE_COMPARE_EQUAL);
EMIT_BYTE(rt, 0); EMIT_BYTE(rt, TOY_OPCODE_NEGATE); //squeezed into one word
EMIT_BYTE(rt, 0);
EMIT_BYTE(rt, 0);
EMIT_BYTE(rt, TOY_OPCODE_NEGATE); //TODO: squeeze these into one word
EMIT_BYTE(rt, 0);
EMIT_BYTE(rt, 0); EMIT_BYTE(rt, 0);
EMIT_BYTE(rt, 0); EMIT_BYTE(rt, 0);

View File

@@ -69,7 +69,7 @@ Toy_String* Toy_deepCopyString(Toy_Bucket** bucket, Toy_String* str) {
} }
Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucket, sizeof(Toy_String) + str->length + 1); //TODO: compensate for partitioning more space than bucket capacity Toy_String* ret = (Toy_String*)Toy_partitionBucket(bucket, sizeof(Toy_String) + str->length + 1); //TODO: compensate for partitioning more space than bucket capacity
//TODO //
ret->type = TOY_STRING_LEAF; ret->type = TOY_STRING_LEAF;
ret->length = str->length; ret->length = str->length;
ret->refCount = 1; ret->refCount = 1;

View File

@@ -165,7 +165,16 @@ static void processComparison(Toy_VM* vm, Toy_OpcodeType opcode) {
//most things can be equal, so handle it separately //most things can be equal, so handle it separately
if (opcode == TOY_OPCODE_COMPARE_EQUAL) { if (opcode == TOY_OPCODE_COMPARE_EQUAL) {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(TOY_VALUE_IS_EQUAL(left, right)) ); bool equal = TOY_VALUE_IS_EQUAL(left, right);
//equality has an optional "negate" opcode within it's word
if (READ_BYTE(vm) != TOY_OPCODE_NEGATE) {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(equal) );
}
else {
Toy_pushStack(&vm->stack, TOY_VALUE_TO_BOOLEAN(!equal) );
}
return; return;
} }
@@ -254,7 +263,7 @@ static void process(Toy_VM* vm) {
case TOY_OPCODE_AND: case TOY_OPCODE_AND:
case TOY_OPCODE_OR: case TOY_OPCODE_OR:
case TOY_OPCODE_TRUTHY: case TOY_OPCODE_TRUTHY:
case TOY_OPCODE_NEGATE: //TODO: squeeze into != case TOY_OPCODE_NEGATE:
processLogical(vm, opcode); processLogical(vm, opcode);
break; break;

View File

@@ -322,7 +322,7 @@ int test_routine_header_and_values(Toy_Bucket** bucket) {
} }
// int test_routine_unary(Toy_Bucket** bucket) { // int test_routine_unary(Toy_Bucket** bucket) {
// //TODO: Nothing produces a unary instruction yet // //Nothing produces a unary instruction yet
// } // }
int test_routine_binary(Toy_Bucket** bucket) { int test_routine_binary(Toy_Bucket** bucket) {
@@ -476,7 +476,7 @@ int test_routine_binary(Toy_Bucket** bucket) {
//check header //check header
int* ptr = (int*)buffer; int* ptr = (int*)buffer;
if ((ptr++)[0] != 52 || //total size if ((ptr++)[0] != 48 || //total size
(ptr++)[0] != 0 || //param count (ptr++)[0] != 0 || //param count
(ptr++)[0] != 0 || //jump count (ptr++)[0] != 0 || //jump count
(ptr++)[0] != 0 || //data count (ptr++)[0] != 0 || //data count
@@ -503,19 +503,14 @@ int test_routine_binary(Toy_Bucket** bucket) {
*(int*)(buffer + 36) != 5 || *(int*)(buffer + 36) != 5 ||
*((unsigned char*)(buffer + 40)) != TOY_OPCODE_COMPARE_EQUAL || *((unsigned char*)(buffer + 40)) != TOY_OPCODE_COMPARE_EQUAL ||
*((unsigned char*)(buffer + 41)) != 0 || *((unsigned char*)(buffer + 41)) != TOY_OPCODE_NEGATE ||
*((unsigned char*)(buffer + 42)) != 0 || *((unsigned char*)(buffer + 42)) != 0 ||
*((unsigned char*)(buffer + 43)) != 0 || *((unsigned char*)(buffer + 43)) != 0 ||
*((unsigned char*)(buffer + 44)) != TOY_OPCODE_NEGATE || *((unsigned char*)(buffer + 44)) != TOY_OPCODE_RETURN ||
*((unsigned char*)(buffer + 45)) != 0 || *((unsigned char*)(buffer + 45)) != 0 ||
*((unsigned char*)(buffer + 46)) != 0 || *((unsigned char*)(buffer + 46)) != 0 ||
*((unsigned char*)(buffer + 47)) != 0 || *((unsigned char*)(buffer + 47)) != 0
*((unsigned char*)(buffer + 48)) != TOY_OPCODE_RETURN ||
*((unsigned char*)(buffer + 49)) != 0 ||
*((unsigned char*)(buffer + 50)) != 0 ||
*((unsigned char*)(buffer + 51)) != 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 routine code, source: %s\n" TOY_CC_RESET, source);

View File

@@ -73,9 +73,8 @@ int test_setup_and_teardown(Toy_Bucket** bucket) {
return 0; return 0;
} }
//tests
int test_simple_execution(Toy_Bucket** bucket) { int test_simple_execution(Toy_Bucket** bucket) {
//basic init & quit //test execution
{ {
//generate bytecode for testing //generate bytecode for testing
const char* source = "(1 + 2) * (3 + 4);"; const char* source = "(1 + 2) * (3 + 4);";
@@ -104,7 +103,51 @@ int test_simple_execution(Toy_Bucket** bucket) {
TOY_VALUE_AS_INTEGER( Toy_peekStack(&vm.stack) ) != 21 TOY_VALUE_AS_INTEGER( Toy_peekStack(&vm.stack) ) != 21
) )
{ {
fprintf(stderr, TOY_CC_ERROR "ERROR: failed run the Toy_VM, source: %s\n" TOY_CC_RESET, source); fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected result in 'Toy_VM', source: %s\n" TOY_CC_RESET, source);
//cleanup and return
Toy_freeVM(&vm);
return -1;
}
//teadown
Toy_freeVM(&vm);
}
return 0;
}
int test_opcode_not_equal(Toy_Bucket** bucket) {
//testing a specific opcode; '!=' is compressed into a single word, so lets check it works
{
//generate bytecode for testing
const char* source = "3 != 5;";
Toy_Lexer lexer;
Toy_bindLexer(&lexer, source);
Toy_Parser parser;
Toy_bindParser(&parser, &lexer);
Toy_Ast* ast = Toy_scanParser(bucket, &parser);
Toy_Bytecode bc = Toy_compileBytecode(ast);
//run the setup
Toy_VM vm;
Toy_bindVM(&vm, bc.ptr, bc.capacity);
//run
Toy_runVM(&vm);
//check the final state of the stack
if (vm.stack == NULL ||
vm.stack->count != 1 ||
TOY_VALUE_IS_BOOLEAN( Toy_peekStack(&vm.stack) ) != true ||
TOY_VALUE_AS_BOOLEAN( Toy_peekStack(&vm.stack) ) != true
)
{
fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected result in 'Toy_VM', source: %s\n" TOY_CC_RESET, source);
//cleanup and return //cleanup and return
Toy_freeVM(&vm); Toy_freeVM(&vm);
@@ -142,5 +185,15 @@ int main() {
total += res; total += res;
} }
{
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
res = test_opcode_not_equal(&bucket);
Toy_freeBucket(&bucket);
if (res == 0) {
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
}
total += res;
}
return total; return total;
} }