From 190477add86e311bbcd661f5af5324467637277a Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Tue, 26 May 2026 18:01:49 +1000 Subject: [PATCH] Fixed negative variables handled incorrectly --- repl/bytecode_inspector.c | 4 ++++ source/toy_ast.h | 5 +++-- source/toy_compiler.c | 11 +++++++++++ source/toy_opcodes.h | 1 + source/toy_parser.c | 2 +- source/toy_vm.c | 20 ++++++++++++++++++++ 6 files changed, 40 insertions(+), 3 deletions(-) diff --git a/repl/bytecode_inspector.c b/repl/bytecode_inspector.c index 99121b6..deb3611 100644 --- a/repl/bytecode_inspector.c +++ b/repl/bytecode_inspector.c @@ -233,6 +233,10 @@ int inspect_instruction(unsigned char* bytecode, unsigned int pc, unsigned int j printf(MARKER "MODULO %s\n", MARKER_VALUE(pc, unsigned char), bytecode[pc + 1] == TOY_OPCODE_ASSIGN ? "and ASSIGN" : ""); return 4; + case TOY_OPCODE_INVERT: + printf(MARKER "INVERT\n", MARKER_VALUE(pc, unsigned char)); + return 4; + case TOY_OPCODE_COMPARE_EQUAL: printf(MARKER "COMPARE %s\n", MARKER_VALUE(pc, unsigned char), bytecode[pc + 1] != TOY_OPCODE_NEGATE ? "==" : "!="); return 4; diff --git a/source/toy_ast.h b/source/toy_ast.h index 1754dcd..0e79887 100644 --- a/source/toy_ast.h +++ b/source/toy_ast.h @@ -86,9 +86,10 @@ typedef enum Toy_AstFlag { TOY_AST_FLAG_PREFIX_DECREMENT = 42, TOY_AST_FLAG_POSTFIX_INCREMENT = 43, TOY_AST_FLAG_POSTFIX_DECREMENT = 44, + TOY_AST_FLAG_INVERT = 45, - TOY_AST_FLAG_INVOKATION = 45, - TOY_AST_FLAG_ATTRIBUTE = 46, + TOY_AST_FLAG_INVOKATION = 46, + TOY_AST_FLAG_ATTRIBUTE = 47, // TOY_AST_FLAG_TERNARY, } Toy_AstFlag; diff --git a/source/toy_compiler.c b/source/toy_compiler.c index ab939b2..a73669f 100644 --- a/source/toy_compiler.c +++ b/source/toy_compiler.c @@ -377,6 +377,17 @@ static unsigned int writeInstructionUnary(Toy_Bytecode** mb, Toy_AstUnary ast) { result = 1; } + else if (ast.flag == TOY_AST_FLAG_INVERT) { + result = writeBytecodeFromAst(mb, ast.child); + + EMIT_BYTE(mb, code, TOY_OPCODE_INVERT); + + //4-byte alignment + EMIT_BYTE(mb, code, 0); + EMIT_BYTE(mb, code, 0); + EMIT_BYTE(mb, code, 0); + } + else { fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST unary flag found\n" TOY_CC_RESET); exit(-1); diff --git a/source/toy_opcodes.h b/source/toy_opcodes.h index 0154365..cd7b111 100644 --- a/source/toy_opcodes.h +++ b/source/toy_opcodes.h @@ -22,6 +22,7 @@ typedef enum Toy_OpcodeType { TOY_OPCODE_MULTIPLY, TOY_OPCODE_DIVIDE, TOY_OPCODE_MODULO, + TOY_OPCODE_INVERT, //negative numbers //comparison instructions TOY_OPCODE_COMPARE_EQUAL, diff --git a/source/toy_parser.c b/source/toy_parser.c index 75894fa..20d7450 100644 --- a/source/toy_parser.c +++ b/source/toy_parser.c @@ -417,7 +417,7 @@ static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast* } else { //actually emit the negation node - Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE); + Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_INVERT); } } diff --git a/source/toy_vm.c b/source/toy_vm.c index 010c0a1..10d906b 100644 --- a/source/toy_vm.c +++ b/source/toy_vm.c @@ -554,6 +554,25 @@ static void processIterate(Toy_VM* vm) { } static void processArithmetic(Toy_VM* vm, Toy_OpcodeType opcode) { + //BUGFIX: handle negative variables + if (opcode == TOY_OPCODE_INVERT) { + Toy_Value value = Toy_popStack(&vm->stack); + if (TOY_VALUE_IS_INTEGER(value)) { + int intermediate = TOY_VALUE_AS_INTEGER(value); + Toy_pushStack(&vm->stack, TOY_VALUE_FROM_INTEGER(-intermediate)); + } + else if (TOY_VALUE_IS_FLOAT(value)) { + float intermediate = TOY_VALUE_AS_FLOAT(value); + Toy_pushStack(&vm->stack, TOY_VALUE_FROM_FLOAT(-intermediate)); + } + else { + Toy_error("Can't negate a non-number"); + Toy_freeValue(value); + Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL()); + } + return; + } + Toy_Value right = Toy_popStack(&vm->stack); Toy_Value left = Toy_popStack(&vm->stack); @@ -1096,6 +1115,7 @@ static unsigned int process(Toy_VM* vm) { case TOY_OPCODE_MULTIPLY: case TOY_OPCODE_DIVIDE: case TOY_OPCODE_MODULO: + case TOY_OPCODE_INVERT: processArithmetic(vm, opcode); break;