mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Added negate opcode to equality opcode, in the second byte
This commit is contained in:
@@ -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
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user