mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Added arithmetic assign operators
This commit is contained in:
@@ -269,18 +269,22 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) {
|
|||||||
if(IS_INTEGER(lhs) && IS_INTEGER(rhs)) {
|
if(IS_INTEGER(lhs) && IS_INTEGER(rhs)) {
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case OP_ADDITION:
|
case OP_ADDITION:
|
||||||
|
case OP_VAR_ADDITION_ASSIGN:
|
||||||
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) + AS_INTEGER(rhs) ));
|
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) + AS_INTEGER(rhs) ));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OP_SUBTRACTION:
|
case OP_SUBTRACTION:
|
||||||
|
case OP_VAR_SUBTRACTION_ASSIGN:
|
||||||
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) - AS_INTEGER(rhs) ));
|
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) - AS_INTEGER(rhs) ));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OP_MULTIPLICATION:
|
case OP_MULTIPLICATION:
|
||||||
|
case OP_VAR_MULTIPLICATION_ASSIGN:
|
||||||
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) * AS_INTEGER(rhs) ));
|
pushLiteralArray(&interpreter->stack, TO_INTEGER_LITERAL( AS_INTEGER(lhs) * AS_INTEGER(rhs) ));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OP_DIVISION:
|
case OP_DIVISION:
|
||||||
|
case OP_VAR_DIVISION_ASSIGN:
|
||||||
if (AS_INTEGER(rhs) == 0) {
|
if (AS_INTEGER(rhs) == 0) {
|
||||||
printf(ERROR "ERROR: Can't divide by zero (error found in interpreter)" RESET);
|
printf(ERROR "ERROR: Can't divide by zero (error found in interpreter)" RESET);
|
||||||
return false;
|
return false;
|
||||||
@@ -289,6 +293,7 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OP_MODULO:
|
case OP_MODULO:
|
||||||
|
case OP_VAR_MODULO_ASSIGN:
|
||||||
if (AS_INTEGER(rhs) == 0) {
|
if (AS_INTEGER(rhs) == 0) {
|
||||||
printf(ERROR "ERROR: Can't modulo by zero (error found in interpreter)" RESET);
|
printf(ERROR "ERROR: Can't modulo by zero (error found in interpreter)" RESET);
|
||||||
return false;
|
return false;
|
||||||
@@ -303,7 +308,7 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//catch bad modulo
|
//catch bad modulo
|
||||||
if (opcode == OP_MODULO) {
|
if (opcode == OP_MODULO || opcode == OP_VAR_MODULO_ASSIGN) {
|
||||||
printf(ERROR "ERROR: Bad arithmetic argument (modulo on floats not allowed)\n" RESET);
|
printf(ERROR "ERROR: Bad arithmetic argument (modulo on floats not allowed)\n" RESET);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -311,18 +316,22 @@ static bool execArithmetic(Interpreter* interpreter, Opcode opcode) {
|
|||||||
if(IS_FLOAT(lhs) && IS_FLOAT(rhs)) {
|
if(IS_FLOAT(lhs) && IS_FLOAT(rhs)) {
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case OP_ADDITION:
|
case OP_ADDITION:
|
||||||
|
case OP_VAR_ADDITION_ASSIGN:
|
||||||
pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) + AS_FLOAT(rhs) ));
|
pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) + AS_FLOAT(rhs) ));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OP_SUBTRACTION:
|
case OP_SUBTRACTION:
|
||||||
|
case OP_VAR_SUBTRACTION_ASSIGN:
|
||||||
pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) - AS_FLOAT(rhs) ));
|
pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) - AS_FLOAT(rhs) ));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OP_MULTIPLICATION:
|
case OP_MULTIPLICATION:
|
||||||
|
case OP_VAR_MULTIPLICATION_ASSIGN:
|
||||||
pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) * AS_FLOAT(rhs) ));
|
pushLiteralArray(&interpreter->stack, TO_FLOAT_LITERAL( AS_FLOAT(lhs) * AS_FLOAT(rhs) ));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OP_DIVISION:
|
case OP_DIVISION:
|
||||||
|
case OP_VAR_DIVISION_ASSIGN:
|
||||||
if (AS_FLOAT(rhs) == 0) {
|
if (AS_FLOAT(rhs) == 0) {
|
||||||
printf(ERROR "ERROR: Can't divide by zero (error found in interpreter)" RESET);
|
printf(ERROR "ERROR: Can't divide by zero (error found in interpreter)" RESET);
|
||||||
return false;
|
return false;
|
||||||
@@ -414,6 +423,18 @@ static bool execVarAssign(Interpreter* interpreter) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool execVarArithmeticAssign(Interpreter* interpreter) {
|
||||||
|
Literal rhs = popLiteralArray(&interpreter->stack);
|
||||||
|
Literal lhs = popLiteralArray(&interpreter->stack);
|
||||||
|
|
||||||
|
//duplicate the name
|
||||||
|
pushLiteralArray(&interpreter->stack, lhs);
|
||||||
|
pushLiteralArray(&interpreter->stack, lhs);
|
||||||
|
pushLiteralArray(&interpreter->stack, rhs);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool execValCast(Interpreter* interpreter) {
|
static bool execValCast(Interpreter* interpreter) {
|
||||||
Literal value = popLiteralArray(&interpreter->stack);
|
Literal value = popLiteralArray(&interpreter->stack);
|
||||||
Literal type = popLiteralArray(&interpreter->stack);
|
Literal type = popLiteralArray(&interpreter->stack);
|
||||||
@@ -691,6 +712,21 @@ static void execInterpreter(Interpreter* interpreter) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_VAR_ADDITION_ASSIGN:
|
||||||
|
case OP_VAR_SUBTRACTION_ASSIGN:
|
||||||
|
case OP_VAR_MULTIPLICATION_ASSIGN:
|
||||||
|
case OP_VAR_DIVISION_ASSIGN:
|
||||||
|
case OP_VAR_MODULO_ASSIGN:
|
||||||
|
execVarArithmeticAssign(interpreter);
|
||||||
|
if (!execArithmetic(interpreter, opcode)) {
|
||||||
|
popLiteralArray(&interpreter->stack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!execVarAssign(interpreter)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case OP_GROUPING_BEGIN:
|
case OP_GROUPING_BEGIN:
|
||||||
execInterpreter(interpreter);
|
execInterpreter(interpreter);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ typedef enum Opcode {
|
|||||||
OP_VAR_DECL_LONG, //declare a variable to be used (as a long literal)
|
OP_VAR_DECL_LONG, //declare a variable to be used (as a long literal)
|
||||||
|
|
||||||
OP_VAR_ASSIGN, //assign to a literal
|
OP_VAR_ASSIGN, //assign to a literal
|
||||||
|
OP_VAR_ADDITION_ASSIGN,
|
||||||
|
OP_VAR_SUBTRACTION_ASSIGN,
|
||||||
|
OP_VAR_MULTIPLICATION_ASSIGN,
|
||||||
|
OP_VAR_DIVISION_ASSIGN,
|
||||||
|
OP_VAR_MODULO_ASSIGN,
|
||||||
|
|
||||||
OP_TYPE_CAST, //temporarily change a type of an atomic value
|
OP_TYPE_CAST, //temporarily change a type of an atomic value
|
||||||
|
|
||||||
|
|||||||
@@ -326,6 +326,31 @@ static Opcode binary(Parser* parser, Node** nodeHandle) {
|
|||||||
return OP_VAR_ASSIGN;
|
return OP_VAR_ASSIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TOKEN_PLUS_ASSIGN: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT);
|
||||||
|
return OP_VAR_ADDITION_ASSIGN;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_MINUS_ASSIGN: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT);
|
||||||
|
return OP_VAR_SUBTRACTION_ASSIGN;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_MULTIPLY_ASSIGN: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT);
|
||||||
|
return OP_VAR_MULTIPLICATION_ASSIGN;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_DIVIDE_ASSIGN: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT);
|
||||||
|
return OP_VAR_DIVISION_ASSIGN;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_MODULO_ASSIGN: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT);
|
||||||
|
return OP_VAR_MODULO_ASSIGN;
|
||||||
|
}
|
||||||
|
|
||||||
//comparison
|
//comparison
|
||||||
case TOKEN_EQUAL: {
|
case TOKEN_EQUAL: {
|
||||||
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
||||||
@@ -641,11 +666,11 @@ ParseRule parseRules[] = { //must match the token types
|
|||||||
{NULL, binary, PREC_FACTOR},// TOKEN_MULTIPLY,
|
{NULL, binary, PREC_FACTOR},// TOKEN_MULTIPLY,
|
||||||
{NULL, binary, PREC_FACTOR},// TOKEN_DIVIDE,
|
{NULL, binary, PREC_FACTOR},// TOKEN_DIVIDE,
|
||||||
{NULL, binary, PREC_FACTOR},// TOKEN_MODULO,
|
{NULL, binary, PREC_FACTOR},// TOKEN_MODULO,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_PLUS_ASSIGN,
|
{NULL, binary, PREC_ASSIGNMENT},// TOKEN_PLUS_ASSIGN,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_MINUS_ASSIGN,
|
{NULL, binary, PREC_ASSIGNMENT},// TOKEN_MINUS_ASSIGN,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_MULTIPLY_ASSIGN,
|
{NULL, binary, PREC_ASSIGNMENT},// TOKEN_MULTIPLY_ASSIGN,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_DIVIDE_ASSIGN,
|
{NULL, binary, PREC_ASSIGNMENT},// TOKEN_DIVIDE_ASSIGN,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_MODULO_ASSIGN,
|
{NULL, binary, PREC_ASSIGNMENT},// TOKEN_MODULO_ASSIGN,
|
||||||
{incrementPrefix, incrementInfix, PREC_CALL},// TOKEN_PLUS_PLUS,
|
{incrementPrefix, incrementInfix, PREC_CALL},// TOKEN_PLUS_PLUS,
|
||||||
{decrementPrefix, decrementInfix, PREC_CALL},// TOKEN_MINUS_MINUS,
|
{decrementPrefix, decrementInfix, PREC_CALL},// TOKEN_MINUS_MINUS,
|
||||||
{NULL, binary, PREC_ASSIGNMENT},// TOKEN_ASSIGN,
|
{NULL, binary, PREC_ASSIGNMENT},// TOKEN_ASSIGN,
|
||||||
|
|||||||
@@ -12,4 +12,20 @@ assert 2.0 * 2.0 == 4.0, "2.0 * 2.0 == 4.0";
|
|||||||
assert 1.0 / 2.0 == 0.5, "1.0 / 2.0 == 0.5";
|
assert 1.0 / 2.0 == 0.5, "1.0 / 2.0 == 0.5";
|
||||||
|
|
||||||
|
|
||||||
|
var a = 10;
|
||||||
|
|
||||||
|
a += 20;
|
||||||
|
a -= 25;
|
||||||
|
|
||||||
|
assert a == 5, "+= or -= failed";
|
||||||
|
|
||||||
|
a *= 5;
|
||||||
|
a /= 2;
|
||||||
|
|
||||||
|
assert a == 12, "*= or /= failed";
|
||||||
|
|
||||||
|
a %= 8;
|
||||||
|
|
||||||
|
assert a == 4, "%= failed";
|
||||||
|
|
||||||
print "All good";
|
print "All good";
|
||||||
Reference in New Issue
Block a user