mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +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;
|
||||
}
|
||||
|
||||
//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_TARGETNAME=Toy
|
||||
|
||||
#TODO: fix windows & macos
|
||||
#SRC_LIBLINE is a fancy way of making the linker work correctly
|
||||
ifeq ($(shell uname),Linux)
|
||||
SRC_TARGETEXT=.so
|
||||
|
||||
@@ -42,7 +42,6 @@ void Toy_private_emitAstValue(Toy_Bucket** bucket, Toy_Ast** handle, Toy_Value v
|
||||
(*handle) = tmp;
|
||||
}
|
||||
|
||||
//TODO: flag range checks
|
||||
void Toy_private_emitAstUnary(Toy_Bucket** bucket, Toy_Ast** handle, Toy_AstFlag flag) {
|
||||
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) {
|
||||
EMIT_BYTE(rt, TOY_OPCODE_COMPARE_EQUAL);
|
||||
EMIT_BYTE(rt, 0);
|
||||
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, TOY_OPCODE_NEGATE); //squeezed into one word
|
||||
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
|
||||
|
||||
//TODO
|
||||
//
|
||||
ret->type = TOY_STRING_LEAF;
|
||||
ret->length = str->length;
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -254,7 +263,7 @@ static void process(Toy_VM* vm) {
|
||||
case TOY_OPCODE_AND:
|
||||
case TOY_OPCODE_OR:
|
||||
case TOY_OPCODE_TRUTHY:
|
||||
case TOY_OPCODE_NEGATE: //TODO: squeeze into !=
|
||||
case TOY_OPCODE_NEGATE:
|
||||
processLogical(vm, opcode);
|
||||
break;
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ int test_routine_header_and_values(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) {
|
||||
@@ -476,7 +476,7 @@ int test_routine_binary(Toy_Bucket** bucket) {
|
||||
//check header
|
||||
int* ptr = (int*)buffer;
|
||||
|
||||
if ((ptr++)[0] != 52 || //total size
|
||||
if ((ptr++)[0] != 48 || //total size
|
||||
(ptr++)[0] != 0 || //param count
|
||||
(ptr++)[0] != 0 || //jump count
|
||||
(ptr++)[0] != 0 || //data count
|
||||
@@ -503,19 +503,14 @@ int test_routine_binary(Toy_Bucket** bucket) {
|
||||
*(int*)(buffer + 36) != 5 ||
|
||||
|
||||
*((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 + 43)) != 0 ||
|
||||
|
||||
*((unsigned char*)(buffer + 44)) != TOY_OPCODE_NEGATE ||
|
||||
*((unsigned char*)(buffer + 44)) != TOY_OPCODE_RETURN ||
|
||||
*((unsigned char*)(buffer + 45)) != 0 ||
|
||||
*((unsigned char*)(buffer + 46)) != 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
|
||||
*((unsigned char*)(buffer + 47)) != 0
|
||||
)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//tests
|
||||
int test_simple_execution(Toy_Bucket** bucket) {
|
||||
//basic init & quit
|
||||
//test execution
|
||||
{
|
||||
//generate bytecode for testing
|
||||
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
|
||||
)
|
||||
{
|
||||
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
|
||||
Toy_freeVM(&vm);
|
||||
@@ -142,5 +185,15 @@ int main() {
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user