Implement unary negation for numbers and logical not for booleans, introduce PREC_ASSIGNMENT and PREC_UNARY precedence levels, refactor parse functions to accept allowAssignment parameter, add assignment tests for global/local/chained/error cases, and update if-syntax to support statement branches and assignment in conditions.
Implement initial support for `if` expressions in the compiler, including new `TOKEN_IF` and `TOKEN_ELSE` tokens, `CODE_JUMP` and `CODE_JUMP_IF` bytecodes for conditional branching, and a `makeNull()` function in the VM to represent the value returned when an if-condition is false without an else clause. The `emit()` function now returns the index of the emitted bytecode to enable patching jump offsets. Also add a `nullClass` to the VM and a `OBJ_NULL` object type, along with a `dumpCode()` debugging helper and new test files for block syntax and if-expression behavior.