Add <<= and >>= operators (#119)

* Add <<= and >>=
This commit is contained in:
Tiago Cavalcante Trindade 2021-06-23 11:24:20 -03:00 committed by GitHub
parent 64bf27674a
commit 6d434db0cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 10 deletions

View File

@ -105,9 +105,8 @@ typedef enum {
TK_SRIGHT, // >> TK_SRIGHT, // >>
TK_SLEFT, // << TK_SLEFT, // <<
//TODO: TK_SRIGHTEQ, // >>=
//TK_SRIGHTEQ // >>= TK_SLEFTEQ, // <<=
//TK_SLEFTEQ // <<=
// Keywords. // Keywords.
TK_MODULE, // module TK_MODULE, // module
@ -808,17 +807,27 @@ static void lexToken(Compiler* compiler) {
return; return;
case '>': case '>':
if (matchChar(compiler, '>')) if (matchChar(compiler, '>')) {
if (matchChar(compiler, '=')) {
setNextToken(compiler, TK_SRIGHTEQ);
} else {
setNextToken(compiler, TK_SRIGHT); setNextToken(compiler, TK_SRIGHT);
else }
} else {
setNextTwoCharToken(compiler, '=', TK_GT, TK_GTEQ); setNextTwoCharToken(compiler, '=', TK_GT, TK_GTEQ);
}
return; return;
case '<': case '<':
if (matchChar(compiler, '<')) if (matchChar(compiler, '<')) {
if (matchChar(compiler, '=')) {
setNextToken(compiler, TK_SLEFTEQ);
} else {
setNextToken(compiler, TK_SLEFT); setNextToken(compiler, TK_SLEFT);
else }
} else {
setNextTwoCharToken(compiler, '=', TK_LT, TK_LTEQ); setNextTwoCharToken(compiler, '=', TK_LT, TK_LTEQ);
}
return; return;
case '+': case '+':
@ -991,6 +1000,8 @@ static bool matchAssignment(Compiler* compiler) {
if (match(compiler, TK_ANDEQ)) return true; if (match(compiler, TK_ANDEQ)) return true;
if (match(compiler, TK_OREQ)) return true; if (match(compiler, TK_OREQ)) return true;
if (match(compiler, TK_XOREQ)) return true; if (match(compiler, TK_XOREQ)) return true;
if (match(compiler, TK_SRIGHTEQ)) return true;
if (match(compiler, TK_SLEFTEQ)) return true;
return false; return false;
} }
@ -1180,6 +1191,8 @@ GrammarRule rules[] = { // Prefix Infix Infix Precedence
/* TK_XOREQ */ NO_RULE, /* TK_XOREQ */ NO_RULE,
/* TK_SRIGHT */ { NULL, exprBinaryOp, PREC_BITWISE_SHIFT }, /* TK_SRIGHT */ { NULL, exprBinaryOp, PREC_BITWISE_SHIFT },
/* TK_SLEFT */ { NULL, exprBinaryOp, PREC_BITWISE_SHIFT }, /* TK_SLEFT */ { NULL, exprBinaryOp, PREC_BITWISE_SHIFT },
/* TK_SRIGHTEQ */ NO_RULE,
/* TK_SLEFTEQ */ NO_RULE,
/* TK_MODULE */ NO_RULE, /* TK_MODULE */ NO_RULE,
/* TK_CLASS */ NO_RULE, /* TK_CLASS */ NO_RULE,
/* TK_FROM */ NO_RULE, /* TK_FROM */ NO_RULE,
@ -1876,10 +1889,12 @@ static void emitAssignment(Compiler* compiler, TokenType assignment) {
case TK_MINUSEQ: emitOpcode(compiler, OP_SUBTRACT); break; case TK_MINUSEQ: emitOpcode(compiler, OP_SUBTRACT); break;
case TK_STAREQ: emitOpcode(compiler, OP_MULTIPLY); break; case TK_STAREQ: emitOpcode(compiler, OP_MULTIPLY); break;
case TK_DIVEQ: emitOpcode(compiler, OP_DIVIDE); break; case TK_DIVEQ: emitOpcode(compiler, OP_DIVIDE); break;
case TK_MODEQ: emitOpcode(compiler, OP_MOD); break;
case TK_ANDEQ: emitOpcode(compiler, OP_BIT_AND); break; case TK_ANDEQ: emitOpcode(compiler, OP_BIT_AND); break;
case TK_OREQ: emitOpcode(compiler, OP_BIT_OR); break; case TK_OREQ: emitOpcode(compiler, OP_BIT_OR); break;
case TK_XOREQ: emitOpcode(compiler, OP_BIT_XOR); break; case TK_XOREQ: emitOpcode(compiler, OP_BIT_XOR); break;
case TK_MODEQ: emitOpcode(compiler, OP_MOD); break; case TK_SRIGHTEQ: emitOpcode(compiler, OP_BIT_RSHIFT); break;
case TK_SLEFTEQ: emitOpcode(compiler, OP_BIT_LSHIFT); break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;

View File

@ -114,6 +114,14 @@ for i in 0..1000
x = i; assert((x^=-1) == -i-1) x = i; assert((x^=-1) == -i-1)
end end
x = 99
x >>= 2
assert(x == 99 >> 2)
x = 99
x <<= 2
assert(x == 99 << 2)
assert(.5 == 0.5) assert(.5 == 0.5)
assert(.333 == .333) assert(.333 == .333)
assert(.1 + 1 == 1.1) assert(.1 + 1 == 1.1)