diff --git a/src/compiler.h b/src/compiler.h index d49a0202..4e98ddfd 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -87,6 +87,7 @@ public: rules[TK("@num")] = { METHOD(exprLiteral), NO_INFIX }; rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX }; rules[TK("@fstr")] = { METHOD(exprFString), NO_INFIX }; + rules[TK("?")] = { nullptr, METHOD(exprTernary), PREC_TERNARY }; rules[TK("=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT }; rules[TK("+=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT }; rules[TK("-=")] = { nullptr, METHOD(exprAssign), PREC_ASSIGNMENT }; @@ -102,7 +103,7 @@ public: #undef METHOD #undef NO_INFIX -#define EXPR() parsePrecedence(PREC_LOGICAL_OR) // no '=' and ',' just a simple expression +#define EXPR() parsePrecedence(PREC_TERNARY) // no '=' and ',' just a simple expression #define EXPR_TUPLE() parsePrecedence(PREC_COMMA) // no '=', but ',' is allowed #define EXPR_ANY() parsePrecedence(PREC_ASSIGNMENT) } @@ -195,6 +196,7 @@ public: case '&': parser->setNextToken(TK("&")); return; case '|': parser->setNextToken(TK("|")); return; case '^': parser->setNextToken(TK("^")); return; + case '?': parser->setNextToken(TK("?")); return; case '.': { if(parser->matchChar('.')) { if(parser->matchChar('.')) { @@ -411,6 +413,16 @@ public: patchJump(patch); } + void exprTernary() { + int patch = emitCode(OP_POP_JUMP_IF_FALSE); + EXPR(); // if true + int patch2 = emitCode(OP_JUMP_ABSOLUTE); + consume(TK(":")); + patchJump(patch); + EXPR(); // if false + patchJump(patch2); + } + void exprBinaryOp() { _TokenType op = parser->previous.type; parsePrecedence((Precedence)(rules[op].precedence + 1)); diff --git a/src/obj.h b/src/obj.h index e5b24de3..ec71f375 100644 --- a/src/obj.h +++ b/src/obj.h @@ -10,7 +10,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL; const _Float _FLOAT_INF_POS = INFINITY; const _Float _FLOAT_INF_NEG = -INFINITY; -#define PK_VERSION "0.3.0" +#define PK_VERSION "0.3.1" class CodeObject; class BasePointer; diff --git a/src/parser.h b/src/parser.h index 79ff025a..7b9fb814 100644 --- a/src/parser.h +++ b/src/parser.h @@ -8,7 +8,7 @@ constexpr const char* __TOKENS[] = { "@error", "@eof", "@eol", "@sof", ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%", "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->", - "<<", ">>", "&", "|", "^", + "<<", ">>", "&", "|", "^", "?", "==", "!=", ">=", "<=", "+=", "-=", "*=", "/=", "//=", /** KW_BEGIN **/ @@ -73,6 +73,7 @@ enum Precedence { PREC_NONE, PREC_ASSIGNMENT, // = PREC_COMMA, // , + PREC_TERNARY, // ?: PREC_LOGICAL_OR, // or PREC_LOGICAL_AND, // and PREC_EQUALITY, // == != diff --git a/tests/basic.py b/tests/basic.py index e288af9b..362d07f6 100644 --- a/tests/basic.py +++ b/tests/basic.py @@ -89,4 +89,9 @@ assert [1, 2, 3] != [1, 2, 4] # test + *= assert [1, 2, 3] + [4, 5, 6] == [1, 2, 3, 4, 5, 6] -assert [1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3] \ No newline at end of file +assert [1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3] + +# test ?: +a = 5 +assert ((a > 3) ? 1 : 0) == 1 +assert ((a < 3) ? 1 : 0) == 0