mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-17 16:38:22 +00:00
Add %% operator (divisor modulo)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
10
src/ir.c
10
src/ir.c
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user