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("@num")] = { METHOD(exprLiteral), NO_INFIX };
rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX }; rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX };
rules[TK("@fstr")] = { METHOD(exprFString), 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 }; 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 METHOD
#undef NO_INFIX #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_TUPLE() parsePrecedence(PREC_COMMA) // no '=', but ',' is allowed
#define EXPR_ANY() parsePrecedence(PREC_ASSIGNMENT) #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 '^': parser->setNextToken(TK("^")); return; case '^': parser->setNextToken(TK("^")); return;
case '?': parser->setNextToken(TK("?")); return;
case '.': { case '.': {
if(parser->matchChar('.')) { if(parser->matchChar('.')) {
if(parser->matchChar('.')) { if(parser->matchChar('.')) {
@ -411,6 +413,16 @@ public:
patchJump(patch); 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() { void exprBinaryOp() {
_TokenType op = parser->previous.type; _TokenType op = parser->previous.type;
parsePrecedence((Precedence)(rules[op].precedence + 1)); 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_POS = INFINITY;
const _Float _FLOAT_INF_NEG = -INFINITY; const _Float _FLOAT_INF_NEG = -INFINITY;
#define PK_VERSION "0.3.0" #define PK_VERSION "0.3.1"
class CodeObject; class CodeObject;
class BasePointer; class BasePointer;

View File

@ -8,7 +8,7 @@ constexpr const char* __TOKENS[] = {
"@error", "@eof", "@eol", "@sof", "@error", "@eof", "@eol", "@sof",
".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%", ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "%",
"+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->", "+", "-", "*", "/", "//", "**", "=", ">", "<", "...", "->",
"<<", ">>", "&", "|", "^", "<<", ">>", "&", "|", "^", "?",
"==", "!=", ">=", "<=", "==", "!=", ">=", "<=",
"+=", "-=", "*=", "/=", "//=", "+=", "-=", "*=", "/=", "//=",
/** KW_BEGIN **/ /** KW_BEGIN **/
@ -73,6 +73,7 @@ enum Precedence {
PREC_NONE, PREC_NONE,
PREC_ASSIGNMENT, // = PREC_ASSIGNMENT, // =
PREC_COMMA, // , PREC_COMMA, // ,
PREC_TERNARY, // ?:
PREC_LOGICAL_OR, // or PREC_LOGICAL_OR, // or
PREC_LOGICAL_AND, // and PREC_LOGICAL_AND, // and
PREC_EQUALITY, // == != PREC_EQUALITY, // == !=

View File

@ -90,3 +90,8 @@ assert [1, 2, 3] != [1, 2, 4]
# test + *= # test + *=
assert [1, 2, 3] + [4, 5, 6] == [1, 2, 3, 4, 5, 6] 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] 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