Add %% operator (divisor modulo)

This commit is contained in:
Ginger Bill
2017-05-09 16:21:31 +01:00
parent 8677c81da7
commit c6d531df95
5 changed files with 21 additions and 1 deletions

View File

@@ -1864,8 +1864,10 @@ bool check_binary_op(Checker *c, Operand *o, Token op) {
break;
case Token_Mod:
case Token_ModMod:
case Token_AndNot:
case Token_ModEq:
case Token_ModModEq:
case Token_AndNotEq:
if (!is_type_integer(type)) {
error(op, "Operator `%.*s` is only allowed with integers", LIT(op.string));
@@ -2669,8 +2671,10 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
switch (op.kind) {
case Token_Quo:
case Token_Mod:
case Token_ModMod:
case Token_QuoEq:
case Token_ModEq:
case Token_ModModEq:
if ((x->mode == Addressing_Constant || is_type_integer(x->type)) &&
y->mode == Addressing_Constant) {
bool fail = false;

View File

@@ -595,6 +595,7 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
case Token_Quo: return exact_value_float(fmod(cast(f64)a, cast(f64)b));
case Token_QuoEq: c = a / b; break; // NOTE(bill): Integer division
case Token_Mod: c = a % b; break;
case Token_ModMod: c = ((a % b) + b)%b; break;
case Token_And: c = a & b; break;
case Token_Or: c = a | b; break;
case Token_Xor: c = a ^ b; break;

View File

@@ -2073,6 +2073,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
case Token_Mul:
case Token_Quo:
case Token_Mod:
case Token_ModMod:
case Token_And:
case Token_Or:
case Token_Xor:
@@ -2081,6 +2082,14 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
break;
}
if (op == Token_ModMod) {
irValue *n = left;
irValue *m = right;
irValue *a = ir_emit(proc, ir_instr_binary_op(proc, Token_Mod, n, m, type));
irValue *b = ir_emit(proc, ir_instr_binary_op(proc, Token_Add, a, m, type));
return ir_emit(proc, ir_instr_binary_op(proc, Token_Mod, b, m, type));
}
return ir_emit(proc, ir_instr_binary_op(proc, op, left, right, type));
}
@@ -3744,6 +3753,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
case Token_Mul:
case Token_Quo:
case Token_Mod:
case Token_ModMod:
case Token_And:
case Token_Or:
case Token_Xor:

View File

@@ -2136,6 +2136,7 @@ i32 token_precedence(AstFile *f, TokenKind t) {
case Token_Mul:
case Token_Quo:
case Token_Mod:
case Token_ModMod:
case Token_And:
case Token_AndNot:
case Token_Shl:
@@ -2305,6 +2306,7 @@ AstNode *parse_simple_stmt(AstFile *f, bool in_stmt_ok) {
case Token_MulEq:
case Token_QuoEq:
case Token_ModEq:
case Token_ModModEq:
case Token_AndEq:
case Token_OrEq:
case Token_XorEq:

View File

@@ -25,6 +25,7 @@ TOKEN_KIND(Token__OperatorBegin, "_OperatorBegin"), \
TOKEN_KIND(Token_Mul, "*"), \
TOKEN_KIND(Token_Quo, "/"), \
TOKEN_KIND(Token_Mod, "%"), \
TOKEN_KIND(Token_ModMod, "%%"), \
TOKEN_KIND(Token_And, "&"), \
TOKEN_KIND(Token_Or, "|"), \
TOKEN_KIND(Token_Xor, "~"), \
@@ -41,6 +42,7 @@ TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \
TOKEN_KIND(Token_MulEq, "*="), \
TOKEN_KIND(Token_QuoEq, "/="), \
TOKEN_KIND(Token_ModEq, "%="), \
TOKEN_KIND(Token_ModModEq, "%%="), \
TOKEN_KIND(Token_AndEq, "&="), \
TOKEN_KIND(Token_OrEq, "|="), \
TOKEN_KIND(Token_XorEq, "~="), \
@@ -892,8 +894,9 @@ Token tokenizer_get_token(Tokenizer *t) {
case '}': token.kind = Token_CloseBrace; break;
case '\\': token.kind = Token_BackSlash; break;
case '%': token.kind = token_kind_dub_eq(t, '%', Token_Mod, Token_ModEq, Token_ModMod, Token_ModModEq); break;
case '*': token.kind = token_kind_variant2(t, Token_Mul, Token_MulEq); break;
case '%': token.kind = token_kind_variant2(t, Token_Mod, Token_ModEq); break;
case '=': token.kind = token_kind_variant2(t, Token_Eq, Token_CmpEq); break;
case '~': token.kind = token_kind_variant2(t, Token_Xor, Token_XorEq); break;
case '!': token.kind = token_kind_variant2(t, Token_Not, Token_NotEq); break;