add ?: opt

This commit is contained in:
blueloveTH 2022-11-24 00:25:30 +08:00
parent 3ddeac241a
commit d9cf73a6d3
4 changed files with 22 additions and 4 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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, // == !=

View File

@ -90,3 +90,8 @@ 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]
# test ?:
a = 5
assert ((a > 3) ? 1 : 0) == 1
assert ((a < 3) ? 1 : 0) == 0