mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Fixed negation issue, moved some scripts to test/
This commit is contained in:
@@ -1,30 +0,0 @@
|
|||||||
//boolean origin
|
|
||||||
var b: bool = true;
|
|
||||||
|
|
||||||
print (int)b;
|
|
||||||
print (float)b;
|
|
||||||
print (string)b;
|
|
||||||
|
|
||||||
|
|
||||||
//integer origin
|
|
||||||
var i: int = 42;
|
|
||||||
|
|
||||||
print (bool)i;
|
|
||||||
print (float)i;
|
|
||||||
print (string)i;
|
|
||||||
|
|
||||||
|
|
||||||
//float origin
|
|
||||||
var f: float = 3.14;
|
|
||||||
|
|
||||||
print (bool)f;
|
|
||||||
print (int)f;
|
|
||||||
print (string)f;
|
|
||||||
|
|
||||||
|
|
||||||
//string origin
|
|
||||||
var s: string = "78.9";
|
|
||||||
|
|
||||||
print (bool)s;
|
|
||||||
print (int)s;
|
|
||||||
print (float)s;
|
|
||||||
@@ -87,4 +87,3 @@ assert false, "This is a failed assert, and will end execution";
|
|||||||
|
|
||||||
print "This will not be printed because of the above assert";
|
print "This will not be printed because of the above assert";
|
||||||
|
|
||||||
//TODO: use a proper assert-based version of this file
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static void stdoutWrapper(const char* output) {
|
static void stdoutWrapper(const char* output) {
|
||||||
fprintf(stdout, output);
|
fprintf(stdout, "%s", output);
|
||||||
fprintf(stdout, "\n"); //default new line
|
fprintf(stdout, "\n"); //default new line
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stderrWrapper(const char* output) {
|
static void stderrWrapper(const char* output) {
|
||||||
fprintf(stderr, "Assertion failure: ");
|
fprintf(stderr, "Assertion failure: ");
|
||||||
fprintf(stderr, output);
|
fprintf(stderr, "%s", output);
|
||||||
fprintf(stderr, "\n"); //default new line
|
fprintf(stderr, "\n"); //default new line
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +177,32 @@ static bool execPushLiteral(Interpreter* interpreter, bool lng) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool execNegate(Interpreter* interpreter) {
|
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);
|
Literal lit = popLiteralArray(&interpreter->stack);
|
||||||
|
|
||||||
if (!parseIdentifierToValue(interpreter, &lit)) {
|
if (!parseIdentifierToValue(interpreter, &lit)) {
|
||||||
@@ -187,14 +212,8 @@ static bool execNegate(Interpreter* interpreter) {
|
|||||||
if (IS_BOOLEAN(lit)) {
|
if (IS_BOOLEAN(lit)) {
|
||||||
lit = TO_BOOLEAN_LITERAL(!AS_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 {
|
else {
|
||||||
printf("[internal] The interpreter can't negate that literal: ");
|
printf("[internal] The interpreter can't invert that literal: ");
|
||||||
printLiteral(lit);
|
printLiteral(lit);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
return false;
|
return false;
|
||||||
@@ -665,6 +684,12 @@ static void execInterpreter(Interpreter* interpreter) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_INVERT:
|
||||||
|
if (!execInvert(interpreter)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("Unknown opcode found %d, terminating\n", opcode);
|
printf("Unknown opcode found %d, terminating\n", opcode);
|
||||||
printLiteralArray(&interpreter->stack, "\n");
|
printLiteralArray(&interpreter->stack, "\n");
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
//utils
|
//utils
|
||||||
static void stdoutWrapper(const char* output) {
|
static void stdoutWrapper(const char* output) {
|
||||||
fprintf(stdout, output);
|
fprintf(stdout, "%s", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
//buffer the prints
|
//buffer the prints
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ typedef enum Opcode {
|
|||||||
OP_COMPARE_LESS_EQUAL,
|
OP_COMPARE_LESS_EQUAL,
|
||||||
OP_COMPARE_GREATER,
|
OP_COMPARE_GREATER,
|
||||||
OP_COMPARE_GREATER_EQUAL,
|
OP_COMPARE_GREATER_EQUAL,
|
||||||
|
OP_INVERT, //for booleans
|
||||||
|
|
||||||
//meta
|
//meta
|
||||||
OP_SECTION_END,
|
OP_SECTION_END,
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ static Opcode unary(Parser* parser, Node** nodeHandle) {
|
|||||||
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
||||||
|
|
||||||
//check for negative literals (optimisation)
|
//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
|
//negate directly, if int or float
|
||||||
Literal lit = tmpNode->atomic.literal;
|
Literal lit = tmpNode->atomic.literal;
|
||||||
|
|
||||||
@@ -378,26 +378,44 @@ static Opcode unary(Parser* parser, Node** nodeHandle) {
|
|||||||
|
|
||||||
return OP_EOF;
|
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) {
|
else if (parser->previous.type == TOKEN_NOT) {
|
||||||
//temp handle to potentially negate values
|
//temp handle to potentially negate values
|
||||||
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
||||||
|
|
||||||
//check for negative literals (optimisation)
|
//check for inverted booleans
|
||||||
if (tmpNode->type == NODE_LITERAL && !IS_IDENTIFIER(tmpNode->atomic.literal)) {
|
if (tmpNode->type == NODE_LITERAL && IS_BOOLEAN(tmpNode->atomic.literal)) {
|
||||||
//negate directly, if int or float
|
//negate directly, if int or float
|
||||||
Literal lit = tmpNode->atomic.literal;
|
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;
|
tmpNode->atomic.literal = lit;
|
||||||
*nodeHandle = tmpNode;
|
*nodeHandle = tmpNode;
|
||||||
|
|
||||||
return OP_EOF;
|
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 {
|
else {
|
||||||
@@ -405,11 +423,6 @@ static Opcode unary(Parser* parser, Node** nodeHandle) {
|
|||||||
return OP_EOF;
|
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;
|
return OP_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
test/arithmetic.toy
Normal file
15
test/arithmetic.toy
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//test operators (integers)
|
||||||
|
assert 1 + 1 == 2, "1 + 1 == 2";
|
||||||
|
assert 1 - 1 == 0, "1 - 1 == 0";
|
||||||
|
assert 2 * 2 == 4, "2 * 2 == 4";
|
||||||
|
assert 1 / 2 == 0, "1 / 2 == 0"; //integer division
|
||||||
|
assert 5 % 2 == 1, "5 % 2 == 1";
|
||||||
|
|
||||||
|
//test operators (floats)
|
||||||
|
assert 1.0 + 1.0 == 2.0, "1.0 + 1.0 == 2.0";
|
||||||
|
assert 1.0 - 1.0 == 0.0, "1.0 - 1.0 == 0.0";
|
||||||
|
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";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
33
test/casting.toy
Normal file
33
test/casting.toy
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//boolean origin
|
||||||
|
var b: bool = true;
|
||||||
|
|
||||||
|
assert (int)b == 1, "bool -> int";
|
||||||
|
assert (float)b == 1, "bool -> float";
|
||||||
|
assert (string)b == "true", "bool -> string";
|
||||||
|
|
||||||
|
|
||||||
|
//integer origin
|
||||||
|
var i: int = 42;
|
||||||
|
|
||||||
|
assert (bool)i == true, "int -> bool";
|
||||||
|
assert (float)i == 42, "int -> float";
|
||||||
|
assert (string)i == "42", "int -> string";
|
||||||
|
|
||||||
|
|
||||||
|
//float origin
|
||||||
|
var f: float = 3.14;
|
||||||
|
|
||||||
|
assert (bool)f == true, "float -> bool";
|
||||||
|
assert (int)f == 3, "float -> int";
|
||||||
|
assert (string)f == "3.14", "float -> string";
|
||||||
|
|
||||||
|
|
||||||
|
//string origin
|
||||||
|
var s: string = "78.9";
|
||||||
|
|
||||||
|
assert (bool)s == true, "string -> bool";
|
||||||
|
assert (int)s == 78, "string -> int";
|
||||||
|
assert (float)s == 78.9, "string -> float";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
//test numbers
|
//test numbers
|
||||||
assert 1 < 2, "1 < 2";
|
assert 1 < 2, "1 < 2";
|
||||||
assert 1 == 1, "1 == 1";
|
assert 1 == 1, "1 == 1";
|
||||||
Reference in New Issue
Block a user