add neg, add numeric parsing

This commit is contained in:
zongor 2026-02-03 15:57:52 -08:00
parent 8e9ab93151
commit 11cfe34c95
3 changed files with 75 additions and 9 deletions

View File

@ -240,10 +240,7 @@ static void unary() {
switch (operatorType) {
case TOKEN_MINUS: {
code[cp++] = OP_PUSH_8;
code[cp++] = 0;
code[cp++] = OP_EXCH;
code[cp++] = OP_SUB_INT; // kinda cheating, should work
code[cp++] = OP_NEG;
break;
}
case TOKEN_BANG: {
@ -259,22 +256,85 @@ static void binary() {
TokenType operatorType = parser.previous.type;
ParseRule *rule = getRule(operatorType);
parsePrecedence((Precedence)(rule->precedence + 1));
switch (operatorType) {
case TOKEN_PLUS: {
code[cp++] = OP_ADD_INT;
switch (parser.previous.type) {
case TOKEN_LITERAL_INT:
code[cp++] = OP_ADD_INT;
break;
case TOKEN_LITERAL_NAT:
code[cp++] = OP_ADD_NAT;
break;
case TOKEN_LITERAL_REAL:
code[cp++] = OP_ADD_REAL;
break;
case TOKEN_IDENTIFIER:
printf("FIXME: find the identifier's type for add\n");
break;
default:
printf("Unknown Add Arg=%d\n", parser.previous.type);
return; // Unreachable.
}
break;
}
case TOKEN_MINUS: {
code[cp++] = OP_SUB_INT;
switch (parser.previous.type) {
case TOKEN_LITERAL_INT:
code[cp++] = OP_SUB_INT;
break;
case TOKEN_LITERAL_NAT:
code[cp++] = OP_SUB_NAT;
break;
case TOKEN_LITERAL_REAL:
code[cp++] = OP_SUB_REAL;
break;
case TOKEN_IDENTIFIER:
printf("FIXME: find the identifier's type for sub\n");
break;
default:
printf("Unknown Sub Arg=%d\n", parser.previous.type);
return; // Unreachable.
}
break;
}
case TOKEN_STAR: {
code[cp++] = OP_MUL_INT;
switch (parser.previous.type) {
case TOKEN_LITERAL_INT:
code[cp++] = OP_MUL_INT;
break;
case TOKEN_LITERAL_NAT:
code[cp++] = OP_MUL_NAT;
break;
case TOKEN_LITERAL_REAL:
code[cp++] = OP_MUL_REAL;
break;
case TOKEN_IDENTIFIER:
printf("FIXME: find the identifier's type for mul\n");
break;
default:
printf("Unknown Mul Arg=%d\n", parser.previous.type);
return; // Unreachable.
}
break;
}
case TOKEN_SLASH: {
code[cp++] = OP_DIV_INT;
switch (parser.previous.type) {
case TOKEN_LITERAL_INT:
code[cp++] = OP_DIV_INT;
break;
case TOKEN_LITERAL_NAT:
code[cp++] = OP_DIV_NAT;
break;
case TOKEN_LITERAL_REAL:
code[cp++] = OP_DIV_REAL;
break;
case TOKEN_IDENTIFIER:
printf("FIXME: find the identifier's type for div\n");
break;
default:
printf("Unknown Div Arg=%d\n", parser.previous.type);
return; // Unreachable.
}
break;
}
case TOKEN_EQ_EQ: {

View File

@ -389,6 +389,11 @@ bool step_vm() {
stack[sp++] = result;
return true;
}
case OP_NEG: {
i32 a = (i32)stack[--sp];
stack[sp++] = -a;
return true;
}
case OP_NOT: {
u32 a = !stack[--sp];
stack[sp++] = a;

View File

@ -60,6 +60,7 @@ typedef enum {
OP_BIT_AND, /* obj2 obj1 `bit_and` obj | obj1 & obj2 */
OP_BIT_OR, /* obj2 obj1 `bit_or` obj | obj1 | obj2 */
OP_BIT_XOR, /* obj2 obj1 `bit_xor` obj | obj1 ^ obj2 */
OP_NEG, /* obj1 `neg` -obj | -obj1 */
OP_NOT, /* obj1 `bit_xor` !obj | not obj1 */
OP_JMP, /* pc `jump` | jump unconditionally */
OP_JMP_FLAG, /* pc `jump_if_flag` | jump to pc if flag > 0 */