mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Fixed negation issue, moved some scripts to test/
This commit is contained in:
@@ -8,13 +8,13 @@
|
||||
#include <string.h>
|
||||
|
||||
static void stdoutWrapper(const char* output) {
|
||||
fprintf(stdout, output);
|
||||
fprintf(stdout, "%s", output);
|
||||
fprintf(stdout, "\n"); //default new line
|
||||
}
|
||||
|
||||
static void stderrWrapper(const char* output) {
|
||||
fprintf(stderr, "Assertion failure: ");
|
||||
fprintf(stderr, output);
|
||||
fprintf(stderr, "%s", output);
|
||||
fprintf(stderr, "\n"); //default new line
|
||||
}
|
||||
|
||||
@@ -177,7 +177,32 @@ static bool execPushLiteral(Interpreter* interpreter, bool lng) {
|
||||
}
|
||||
|
||||
static bool execNegate(Interpreter* interpreter) {
|
||||
//negate the top literal on the stack
|
||||
//negate the top literal on the stack (numbers only)
|
||||
Literal lit = popLiteralArray(&interpreter->stack);
|
||||
|
||||
if (!parseIdentifierToValue(interpreter, &lit)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (IS_INTEGER(lit)) {
|
||||
lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit));
|
||||
}
|
||||
else if (IS_FLOAT(lit)) {
|
||||
lit = TO_FLOAT_LITERAL(-AS_FLOAT(lit));
|
||||
}
|
||||
else {
|
||||
printf("[internal] The interpreter can't negate that literal: ");
|
||||
printLiteral(lit);
|
||||
printf("\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pushLiteralArray(&interpreter->stack, lit);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool execInvert(Interpreter* interpreter) {
|
||||
//negate the top literal on the stack (booleans only)
|
||||
Literal lit = popLiteralArray(&interpreter->stack);
|
||||
|
||||
if (!parseIdentifierToValue(interpreter, &lit)) {
|
||||
@@ -187,14 +212,8 @@ static bool execNegate(Interpreter* interpreter) {
|
||||
if (IS_BOOLEAN(lit)) {
|
||||
lit = TO_BOOLEAN_LITERAL(!AS_BOOLEAN(lit));
|
||||
}
|
||||
else if (IS_INTEGER(lit)) {
|
||||
lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit));
|
||||
}
|
||||
else if (IS_FLOAT(lit)) {
|
||||
lit = TO_FLOAT_LITERAL(-AS_FLOAT(lit));
|
||||
}
|
||||
else {
|
||||
printf("[internal] The interpreter can't negate that literal: ");
|
||||
printf("[internal] The interpreter can't invert that literal: ");
|
||||
printLiteral(lit);
|
||||
printf("\n");
|
||||
return false;
|
||||
@@ -665,6 +684,12 @@ static void execInterpreter(Interpreter* interpreter) {
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_INVERT:
|
||||
if (!execInvert(interpreter)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown opcode found %d, terminating\n", opcode);
|
||||
printLiteralArray(&interpreter->stack, "\n");
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
//utils
|
||||
static void stdoutWrapper(const char* output) {
|
||||
fprintf(stdout, output);
|
||||
fprintf(stdout, "%s", output);
|
||||
}
|
||||
|
||||
//buffer the prints
|
||||
|
||||
@@ -42,6 +42,7 @@ typedef enum Opcode {
|
||||
OP_COMPARE_LESS_EQUAL,
|
||||
OP_COMPARE_GREATER,
|
||||
OP_COMPARE_GREATER_EQUAL,
|
||||
OP_INVERT, //for booleans
|
||||
|
||||
//meta
|
||||
OP_SECTION_END,
|
||||
|
||||
@@ -361,7 +361,7 @@ static Opcode unary(Parser* parser, Node** nodeHandle) {
|
||||
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
||||
|
||||
//check for negative literals (optimisation)
|
||||
if (tmpNode->type == NODE_LITERAL) {
|
||||
if (tmpNode->type == NODE_LITERAL && (IS_INTEGER(tmpNode->atomic.literal) || IS_FLOAT(tmpNode->atomic.literal))) {
|
||||
//negate directly, if int or float
|
||||
Literal lit = tmpNode->atomic.literal;
|
||||
|
||||
@@ -378,26 +378,44 @@ static Opcode unary(Parser* parser, Node** nodeHandle) {
|
||||
|
||||
return OP_EOF;
|
||||
}
|
||||
|
||||
//check for negated boolean errors
|
||||
if (tmpNode->type == NODE_LITERAL && IS_BOOLEAN(tmpNode->atomic.literal)) {
|
||||
error(parser, parser->previous, "Negative booleans are not allowed");
|
||||
return OP_EOF;
|
||||
}
|
||||
|
||||
//actually emit the negation
|
||||
emitNodeUnary(nodeHandle, OP_NEGATE);
|
||||
(*nodeHandle)->unary.child = tmpNode; //set negate's child to the literal
|
||||
}
|
||||
|
||||
else if (parser->previous.type == TOKEN_NOT) {
|
||||
//temp handle to potentially negate values
|
||||
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
||||
|
||||
//check for negative literals (optimisation)
|
||||
if (tmpNode->type == NODE_LITERAL && !IS_IDENTIFIER(tmpNode->atomic.literal)) {
|
||||
//check for inverted booleans
|
||||
if (tmpNode->type == NODE_LITERAL && IS_BOOLEAN(tmpNode->atomic.literal)) {
|
||||
//negate directly, if int or float
|
||||
Literal lit = tmpNode->atomic.literal;
|
||||
|
||||
if (IS_BOOLEAN(lit)) {
|
||||
lit = TO_BOOLEAN_LITERAL(!AS_BOOLEAN(lit));
|
||||
}
|
||||
lit = TO_BOOLEAN_LITERAL(!AS_BOOLEAN(lit));
|
||||
|
||||
tmpNode->atomic.literal = lit;
|
||||
*nodeHandle = tmpNode;
|
||||
|
||||
return OP_EOF;
|
||||
}
|
||||
|
||||
//check for inverted number errors
|
||||
if (tmpNode->type == NODE_LITERAL && (IS_INTEGER(tmpNode->atomic.literal) || IS_FLOAT(tmpNode->atomic.literal))) {
|
||||
error(parser, parser->previous, "Inverted numbers are not allowed");
|
||||
return OP_EOF;
|
||||
}
|
||||
|
||||
//actually emit the negation
|
||||
emitNodeUnary(nodeHandle, OP_INVERT);
|
||||
(*nodeHandle)->unary.child = tmpNode; //set negate's child to the literal
|
||||
}
|
||||
|
||||
else {
|
||||
@@ -405,11 +423,6 @@ static Opcode unary(Parser* parser, Node** nodeHandle) {
|
||||
return OP_EOF;
|
||||
}
|
||||
|
||||
|
||||
//actually emit the negation
|
||||
emitNodeUnary(nodeHandle, OP_NEGATE);
|
||||
(*nodeHandle)->unary.child = tmpNode; //set negate's child to the literal
|
||||
|
||||
return OP_EOF;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user