mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Comparions and the ! operator work
This commit is contained in:
28
scripts/comparisons.toy
Normal file
28
scripts/comparisons.toy
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
//test numbers
|
||||||
|
assert 1 < 2, "1 < 2";
|
||||||
|
assert 1 == 1, "1 == 1";
|
||||||
|
assert 2 > 1, "2 > 1";
|
||||||
|
assert 1 <= 2, "1 <= 2";
|
||||||
|
assert 2 >= 1, "2 >= 1";
|
||||||
|
|
||||||
|
|
||||||
|
//test variables
|
||||||
|
var a = 1;
|
||||||
|
var b = 2;
|
||||||
|
|
||||||
|
assert a < b, "a < b";
|
||||||
|
assert a == a, "a == a";
|
||||||
|
assert b > a, "b > a";
|
||||||
|
assert a <= b, "a <= b";
|
||||||
|
assert b >= a, "b >= a";
|
||||||
|
|
||||||
|
|
||||||
|
//test negation
|
||||||
|
assert !false, "!false";
|
||||||
|
|
||||||
|
var c = false;
|
||||||
|
assert !c, "!c";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -180,11 +180,14 @@ static bool execNegate(Interpreter* interpreter) {
|
|||||||
//negate the top literal on the stack
|
//negate the top literal on the stack
|
||||||
Literal lit = popLiteralArray(&interpreter->stack);
|
Literal lit = popLiteralArray(&interpreter->stack);
|
||||||
|
|
||||||
if (parseIdentifierToValue(interpreter, &lit)) {
|
if (!parseIdentifierToValue(interpreter, &lit)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_INTEGER(lit)) {
|
if (IS_BOOLEAN(lit)) {
|
||||||
|
lit = TO_BOOLEAN_LITERAL(!AS_BOOLEAN(lit));
|
||||||
|
}
|
||||||
|
else if (IS_INTEGER(lit)) {
|
||||||
lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit));
|
lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit));
|
||||||
}
|
}
|
||||||
else if (IS_FLOAT(lit)) {
|
else if (IS_FLOAT(lit)) {
|
||||||
@@ -440,6 +443,114 @@ static bool execValCast(Interpreter* interpreter) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool execCompareEqual(Interpreter* interpreter, bool invert) {
|
||||||
|
Literal rhs = popLiteralArray(&interpreter->stack);
|
||||||
|
Literal lhs = popLiteralArray(&interpreter->stack);
|
||||||
|
|
||||||
|
parseIdentifierToValue(interpreter, &rhs);
|
||||||
|
parseIdentifierToValue(interpreter, &lhs);
|
||||||
|
|
||||||
|
bool result = literalsAreEqual(lhs, rhs);
|
||||||
|
|
||||||
|
if (invert) {
|
||||||
|
result = !result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(result));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool execCompareLess(Interpreter* interpreter, bool invert) {
|
||||||
|
Literal rhs = popLiteralArray(&interpreter->stack);
|
||||||
|
Literal lhs = popLiteralArray(&interpreter->stack);
|
||||||
|
|
||||||
|
parseIdentifierToValue(interpreter, &rhs);
|
||||||
|
parseIdentifierToValue(interpreter, &lhs);
|
||||||
|
|
||||||
|
//not a number, return falure
|
||||||
|
if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) {
|
||||||
|
printf("Incorrect type in comparison, value \"");
|
||||||
|
printLiteral(lhs);
|
||||||
|
printf("\"\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(IS_INTEGER(rhs) || IS_FLOAT(rhs))) {
|
||||||
|
printf("Incorrect type in comparison, value \"");
|
||||||
|
printLiteral(rhs);
|
||||||
|
printf("\"\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//convert to floats - easier
|
||||||
|
if (IS_INTEGER(lhs)) {
|
||||||
|
lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_INTEGER(rhs)) {
|
||||||
|
rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (!invert) {
|
||||||
|
result = (AS_FLOAT(lhs) < AS_FLOAT(rhs));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = (AS_FLOAT(lhs) > AS_FLOAT(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(result));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool execCompareLessEqual(Interpreter* interpreter, bool invert) {
|
||||||
|
Literal rhs = popLiteralArray(&interpreter->stack);
|
||||||
|
Literal lhs = popLiteralArray(&interpreter->stack);
|
||||||
|
|
||||||
|
parseIdentifierToValue(interpreter, &rhs);
|
||||||
|
parseIdentifierToValue(interpreter, &lhs);
|
||||||
|
|
||||||
|
//not a number, return falure
|
||||||
|
if (!(IS_INTEGER(lhs) || IS_FLOAT(lhs))) {
|
||||||
|
printf("Incorrect type in comparison, value \"");
|
||||||
|
printLiteral(lhs);
|
||||||
|
printf("\"\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(IS_INTEGER(rhs) || IS_FLOAT(rhs))) {
|
||||||
|
printf("Incorrect type in comparison, value \"");
|
||||||
|
printLiteral(rhs);
|
||||||
|
printf("\"\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//convert to floats - easier
|
||||||
|
if (IS_INTEGER(lhs)) {
|
||||||
|
lhs = TO_FLOAT_LITERAL(AS_INTEGER(lhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_INTEGER(rhs)) {
|
||||||
|
rhs = TO_FLOAT_LITERAL(AS_INTEGER(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (!invert) {
|
||||||
|
result = (AS_FLOAT(lhs) < AS_FLOAT(rhs)) || literalsAreEqual(lhs, rhs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = (AS_FLOAT(lhs) > AS_FLOAT(rhs)) || literalsAreEqual(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
pushLiteralArray(&interpreter->stack, TO_BOOLEAN_LITERAL(result));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//the heart of toy
|
//the heart of toy
|
||||||
static void execInterpreter(Interpreter* interpreter) {
|
static void execInterpreter(Interpreter* interpreter) {
|
||||||
unsigned char opcode = readByte(interpreter->bytecode, &interpreter->count);
|
unsigned char opcode = readByte(interpreter->bytecode, &interpreter->count);
|
||||||
@@ -518,6 +629,42 @@ static void execInterpreter(Interpreter* interpreter) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_EQUAL:
|
||||||
|
if (!execCompareEqual(interpreter, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_NOT_EQUAL:
|
||||||
|
if (!execCompareEqual(interpreter, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_LESS:
|
||||||
|
if (!execCompareLess(interpreter, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_LESS_EQUAL:
|
||||||
|
if (!execCompareLessEqual(interpreter, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_GREATER:
|
||||||
|
if (!execCompareLess(interpreter, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_GREATER_EQUAL:
|
||||||
|
if (!execCompareLessEqual(interpreter, true)) {
|
||||||
|
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");
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ static Token makeToken(Lexer* lexer, TokenType type) {
|
|||||||
Token token;
|
Token token;
|
||||||
|
|
||||||
token.type = type;
|
token.type = type;
|
||||||
token.lexeme = &lexer->source[lexer->current - 1];
|
token.length = lexer->current - lexer->start;
|
||||||
token.length = 1;
|
token.lexeme = &lexer->source[lexer->current - token.length];
|
||||||
token.line = lexer->line;
|
token.line = lexer->line;
|
||||||
|
|
||||||
//BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed
|
//BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed
|
||||||
|
|||||||
@@ -101,4 +101,3 @@ void emitNodeVarTypes(Node** nodeHandle, Literal literal);
|
|||||||
void emitNodeVarDecl(Node** nodeHandle, Literal identifier, Literal type, Node* expression);
|
void emitNodeVarDecl(Node** nodeHandle, Literal identifier, Literal type, Node* expression);
|
||||||
|
|
||||||
void printNode(Node* node);
|
void printNode(Node* node);
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ typedef enum Opcode {
|
|||||||
|
|
||||||
OP_TYPE_CAST, //temporarily change a type of an atomic value
|
OP_TYPE_CAST, //temporarily change a type of an atomic value
|
||||||
|
|
||||||
|
//comparion of values
|
||||||
|
OP_COMPARE_EQUAL,
|
||||||
|
OP_COMPARE_NOT_EQUAL,
|
||||||
|
OP_COMPARE_LESS,
|
||||||
|
OP_COMPARE_LESS_EQUAL,
|
||||||
|
OP_COMPARE_GREATER,
|
||||||
|
OP_COMPARE_GREATER_EQUAL,
|
||||||
|
|
||||||
//meta
|
//meta
|
||||||
OP_SECTION_END,
|
OP_SECTION_END,
|
||||||
//TODO: add more
|
//TODO: add more
|
||||||
|
|||||||
195
source/parser.c
195
source/parser.c
@@ -97,7 +97,7 @@ typedef enum {
|
|||||||
PREC_TERNARY,
|
PREC_TERNARY,
|
||||||
PREC_OR,
|
PREC_OR,
|
||||||
PREC_AND,
|
PREC_AND,
|
||||||
PREC_EQUALITY,
|
// PREC_EQUALITY,
|
||||||
PREC_COMPARISON,
|
PREC_COMPARISON,
|
||||||
PREC_TERM,
|
PREC_TERM,
|
||||||
PREC_FACTOR,
|
PREC_FACTOR,
|
||||||
@@ -284,6 +284,7 @@ static Opcode binary(Parser* parser, Node** nodeHandle) {
|
|||||||
|
|
||||||
//binary() is an infix rule - so only get the RHS of the operator
|
//binary() is an infix rule - so only get the RHS of the operator
|
||||||
switch(parser->previous.type) {
|
switch(parser->previous.type) {
|
||||||
|
//arithmetic
|
||||||
case TOKEN_PLUS: {
|
case TOKEN_PLUS: {
|
||||||
parsePrecedence(parser, nodeHandle, PREC_TERM);
|
parsePrecedence(parser, nodeHandle, PREC_TERM);
|
||||||
return OP_ADDITION;
|
return OP_ADDITION;
|
||||||
@@ -309,11 +310,43 @@ static Opcode binary(Parser* parser, Node** nodeHandle) {
|
|||||||
return OP_MODULO;
|
return OP_MODULO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//assignment
|
||||||
case TOKEN_ASSIGN: {
|
case TOKEN_ASSIGN: {
|
||||||
parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT);
|
parsePrecedence(parser, nodeHandle, PREC_ASSIGNMENT);
|
||||||
return OP_VAR_ASSIGN;
|
return OP_VAR_ASSIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//comparison
|
||||||
|
case TOKEN_EQUAL: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
||||||
|
return OP_COMPARE_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_NOT_EQUAL: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
||||||
|
return OP_COMPARE_NOT_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_LESS: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
||||||
|
return OP_COMPARE_LESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_LESS_EQUAL: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
||||||
|
return OP_COMPARE_LESS_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_GREATER: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
||||||
|
return OP_COMPARE_GREATER;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOKEN_GREATER_EQUAL: {
|
||||||
|
parsePrecedence(parser, nodeHandle, PREC_COMPARISON);
|
||||||
|
return OP_COMPARE_GREATER_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error(parser, parser->previous, "Unexpected token passed to binary precedence rule");
|
error(parser, parser->previous, "Unexpected token passed to binary precedence rule");
|
||||||
return OP_EOF;
|
return OP_EOF;
|
||||||
@@ -321,47 +354,63 @@ static Opcode binary(Parser* parser, Node** nodeHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Opcode unary(Parser* parser, Node** nodeHandle) {
|
static Opcode unary(Parser* parser, Node** nodeHandle) {
|
||||||
switch(parser->previous.type) {
|
Node* tmpNode = NULL;
|
||||||
case TOKEN_MINUS: {
|
|
||||||
//temp handle to potentially negate values
|
|
||||||
Node* tmpNode = NULL;
|
|
||||||
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
|
||||||
|
|
||||||
//check for negative literals (optimisation)
|
if (parser->previous.type == TOKEN_MINUS) {
|
||||||
if (tmpNode->type == NODE_LITERAL) {
|
//temp handle to potentially negate values
|
||||||
//negate directly, if int or float
|
parsePrecedence(parser, &tmpNode, PREC_TERNARY); //can be a literal
|
||||||
Literal lit = tmpNode->atomic.literal;
|
|
||||||
|
|
||||||
if (IS_INTEGER(lit)) {
|
//check for negative literals (optimisation)
|
||||||
lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit));
|
if (tmpNode->type == NODE_LITERAL) {
|
||||||
}
|
//negate directly, if int or float
|
||||||
|
Literal lit = tmpNode->atomic.literal;
|
||||||
|
|
||||||
if (IS_FLOAT(lit)) {
|
if (IS_INTEGER(lit)) {
|
||||||
lit = TO_FLOAT_LITERAL(-AS_FLOAT(lit));
|
lit = TO_INTEGER_LITERAL(-AS_INTEGER(lit));
|
||||||
}
|
|
||||||
|
|
||||||
tmpNode->atomic.literal = lit;
|
|
||||||
*nodeHandle = tmpNode;
|
|
||||||
|
|
||||||
return OP_EOF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//process the literal without optimizations
|
if (IS_FLOAT(lit)) {
|
||||||
if (tmpNode->type == NODE_LITERAL) {
|
lit = TO_FLOAT_LITERAL(-AS_FLOAT(lit));
|
||||||
emitNodeUnary(nodeHandle, OP_NEGATE);
|
|
||||||
nodeHandle = &((*nodeHandle)->unary.child); //re-align after append
|
|
||||||
(*nodeHandle) = tmpNode; //set negate's child to the literal
|
|
||||||
return OP_EOF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error(parser, parser->previous, "Unexpected token passed to unary minus precedence rule");
|
tmpNode->atomic.literal = lit;
|
||||||
|
*nodeHandle = tmpNode;
|
||||||
|
|
||||||
return OP_EOF;
|
return OP_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
error(parser, parser->previous, "Unexpected token passed to unary precedence rule");
|
|
||||||
return OP_EOF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
//negate directly, if int or float
|
||||||
|
Literal lit = tmpNode->atomic.literal;
|
||||||
|
|
||||||
|
if (IS_BOOLEAN(lit)) {
|
||||||
|
lit = TO_BOOLEAN_LITERAL(!AS_BOOLEAN(lit));
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpNode->atomic.literal = lit;
|
||||||
|
*nodeHandle = tmpNode;
|
||||||
|
|
||||||
|
return OP_EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
error(parser, parser->previous, "Unexpected token passed to unary precedence rule");
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Opcode atomic(Parser* parser, Node** nodeHandle) {
|
static Opcode atomic(Parser* parser, Node** nodeHandle) {
|
||||||
@@ -522,9 +571,9 @@ ParseRule parseRules[] = { //must match the token types
|
|||||||
//math operators
|
//math operators
|
||||||
{NULL, binary, PREC_TERM},// TOKEN_PLUS,
|
{NULL, binary, PREC_TERM},// TOKEN_PLUS,
|
||||||
{unary, binary, PREC_TERM},// TOKEN_MINUS,
|
{unary, binary, PREC_TERM},// TOKEN_MINUS,
|
||||||
{NULL, binary, PREC_TERM},// TOKEN_MULTIPLY,
|
{NULL, binary, PREC_FACTOR},// TOKEN_MULTIPLY,
|
||||||
{NULL, binary, PREC_TERM},// TOKEN_DIVIDE,
|
{NULL, binary, PREC_FACTOR},// TOKEN_DIVIDE,
|
||||||
{NULL, binary, PREC_TERM},// TOKEN_MODULO,
|
{NULL, binary, PREC_FACTOR},// TOKEN_MODULO,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_PLUS_ASSIGN,
|
{NULL, NULL, PREC_NONE},// TOKEN_PLUS_ASSIGN,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_MINUS_ASSIGN,
|
{NULL, NULL, PREC_NONE},// TOKEN_MINUS_ASSIGN,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_MULTIPLY_ASSIGN,
|
{NULL, NULL, PREC_NONE},// TOKEN_MULTIPLY_ASSIGN,
|
||||||
@@ -541,20 +590,20 @@ ParseRule parseRules[] = { //must match the token types
|
|||||||
{NULL, NULL, PREC_NONE},// TOKEN_BRACKET_RIGHT,
|
{NULL, NULL, PREC_NONE},// TOKEN_BRACKET_RIGHT,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_BRACE_LEFT,
|
{NULL, NULL, PREC_NONE},// TOKEN_BRACE_LEFT,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_BRACE_RIGHT,
|
{NULL, NULL, PREC_NONE},// TOKEN_BRACE_RIGHT,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_NOT,
|
{unary, NULL, PREC_CALL},// TOKEN_NOT,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_NOT_EQUAL,
|
{NULL, binary, PREC_COMPARISON},// TOKEN_NOT_EQUAL,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_EQUAL,
|
{NULL, binary, PREC_COMPARISON},// TOKEN_EQUAL,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_LESS,
|
{NULL, binary, PREC_COMPARISON},// TOKEN_LESS,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_GREATER,
|
{NULL, binary, PREC_COMPARISON},// TOKEN_GREATER,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_LESS_EQUAL,
|
{NULL, binary, PREC_COMPARISON},// TOKEN_LESS_EQUAL,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_GREATER_EQUAL,
|
{NULL, binary, PREC_COMPARISON},// TOKEN_GREATER_EQUAL,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_AND,
|
{NULL, NULL, PREC_NONE},// TOKEN_AND,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_OR,
|
{NULL, NULL, PREC_NONE},// TOKEN_OR,
|
||||||
|
|
||||||
//other operators
|
//other operators
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_COLON,
|
{NULL, NULL, PREC_NONE},// TOKEN_COLON,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_SEMICOLON,
|
{NULL, NULL, PREC_NONE},// TOKEN_SEMICOLON,
|
||||||
{NULL, NULL, PREC_CALL},// TOKEN_COMMA,
|
{NULL, NULL, PREC_NONE},// TOKEN_COMMA,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_DOT,
|
{NULL, NULL, PREC_NONE},// TOKEN_DOT,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_PIPE,
|
{NULL, NULL, PREC_NONE},// TOKEN_PIPE,
|
||||||
{NULL, NULL, PREC_NONE},// TOKEN_REST,
|
{NULL, NULL, PREC_NONE},// TOKEN_REST,
|
||||||
@@ -577,6 +626,12 @@ static bool calcStaticBinaryArithmetic(Parser* parser, Node** nodeHandle) {
|
|||||||
case OP_MULTIPLICATION:
|
case OP_MULTIPLICATION:
|
||||||
case OP_DIVISION:
|
case OP_DIVISION:
|
||||||
case OP_MODULO:
|
case OP_MODULO:
|
||||||
|
case OP_COMPARE_EQUAL:
|
||||||
|
case OP_COMPARE_NOT_EQUAL:
|
||||||
|
case OP_COMPARE_LESS:
|
||||||
|
case OP_COMPARE_LESS_EQUAL:
|
||||||
|
case OP_COMPARE_GREATER:
|
||||||
|
case OP_COMPARE_GREATER_EQUAL:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -642,6 +697,30 @@ static bool calcStaticBinaryArithmetic(Parser* parser, Node** nodeHandle) {
|
|||||||
result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) );
|
result = TO_INTEGER_LITERAL( AS_INTEGER(lhs) % AS_INTEGER(rhs) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) == AS_INTEGER(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_NOT_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) != AS_INTEGER(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_LESS:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) < AS_INTEGER(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_LESS_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) <= AS_INTEGER(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_GREATER:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) > AS_INTEGER(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_GREATER_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_INTEGER(lhs) >= AS_INTEGER(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("[internal] bad opcode argument passed to calcStaticBinaryArithmetic()");
|
printf("[internal] bad opcode argument passed to calcStaticBinaryArithmetic()");
|
||||||
return false;
|
return false;
|
||||||
@@ -676,6 +755,30 @@ static bool calcStaticBinaryArithmetic(Parser* parser, Node** nodeHandle) {
|
|||||||
result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) );
|
result = TO_FLOAT_LITERAL( AS_FLOAT(lhs) / AS_FLOAT(rhs) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) == AS_FLOAT(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_NOT_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) != AS_FLOAT(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_LESS:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) < AS_FLOAT(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_LESS_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) <= AS_FLOAT(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_GREATER:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) > AS_FLOAT(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_COMPARE_GREATER_EQUAL:
|
||||||
|
result = TO_BOOLEAN_LITERAL( AS_FLOAT(lhs) >= AS_FLOAT(rhs) );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("[internal] bad opcode argument passed to calcStaticBinaryArithmetic()");
|
printf("[internal] bad opcode argument passed to calcStaticBinaryArithmetic()");
|
||||||
return false;
|
return false;
|
||||||
@@ -794,11 +897,11 @@ static void printStmt(Parser* parser, Node** nodeHandle) {
|
|||||||
static void assertStmt(Parser* parser, Node** nodeHandle) {
|
static void assertStmt(Parser* parser, Node** nodeHandle) {
|
||||||
//set the node info
|
//set the node info
|
||||||
(*nodeHandle)->type = NODE_BINARY;
|
(*nodeHandle)->type = NODE_BINARY;
|
||||||
(*nodeHandle)->unary.opcode = OP_ASSERT;
|
(*nodeHandle)->binary.opcode = OP_ASSERT;
|
||||||
|
|
||||||
parsePrecedence(parser, &((*nodeHandle)->binary.left), PREC_PRIMARY);
|
parsePrecedence(parser, &((*nodeHandle)->binary.left), PREC_TERNARY);
|
||||||
consume(parser, TOKEN_COMMA, "Expected ',' in assert statement");
|
consume(parser, TOKEN_COMMA, "Expected ',' in assert statement");
|
||||||
parsePrecedence(parser, &((*nodeHandle)->binary.right), PREC_PRIMARY);
|
parsePrecedence(parser, &((*nodeHandle)->binary.right), PREC_TERNARY);
|
||||||
|
|
||||||
consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of assert statement");
|
consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of assert statement");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user