From: NeilBrown Date: Wed, 1 May 2019 08:13:21 +0000 (+1000) Subject: oceani: add "remainder" operator. X-Git-Tag: JamisonCreek-3~30 X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=commitdiff_plain;h=9b6476d3862c262532453a916c54467a350714f9 oceani: add "remainder" operator. a % b treats a and b as integers, does a division, and reports the remainder. Signed-off-by: NeilBrown --- diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index 9e1ce02..68e5b60 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -47,7 +47,7 @@ Elements which are present to make a usable language are: - "blocks" of multiple statements. - `pass`: a statement which does nothing. - - expressions: `+`, `-`, `*`, `/` can apply to numbers and `++` can + - expressions: `+`, `-`, `*`, `/`, `%` can apply to numbers and `++` can catenate strings. `and`, `or`, `not` manipulate Booleans, and normal comparison operators can work on all three types. - `print`: will print the values in a list of expressions. @@ -2069,7 +2069,7 @@ precedence is handled better I might be able to discard this. ###### Binode types Plus, Minus, - Times, Divide, + Times, Divide, Rem, Concat, Absolute, Negate, Bracket, @@ -2119,6 +2119,7 @@ precedence is handled better I might be able to discard this. Top -> * ${ $0.op = Times; }$ | / ${ $0.op = Divide; }$ + | % ${ $0.op = Rem; }$ | ++ ${ $0.op = Concat; }$ ###### print binode cases @@ -2127,13 +2128,15 @@ precedence is handled better I might be able to discard this. case Times: case Divide: case Concat: + case Rem: print_exec(b->left, indent, 0); switch(b->op) { - case Plus: printf(" + "); break; - case Minus: printf(" - "); break; - case Times: printf(" * "); break; - case Divide: printf(" / "); break; - case Concat: printf(" ++ "); break; + case Plus: fputs(" + ", stdout); break; + case Minus: fputs(" - ", stdout); break; + case Times: fputs(" * ", stdout); break; + case Divide: fputs(" / ", stdout); break; + case Rem: fputs(" % ", stdout); break; + case Concat: fputs(" ++ ", stdout); break; default: abort(); } print_exec(b->right, indent, 0); @@ -2156,6 +2159,7 @@ precedence is handled better I might be able to discard this. case Plus: case Minus: case Times: + case Rem: case Divide: /* both must be numbers, result is Tnum */ case Absolute: @@ -2207,6 +2211,20 @@ precedence is handled better I might be able to discard this. right = interp_exec(b->right); mpq_div(rv.num, rv.num, right.num); break; + case Rem: { + mpz_t l, r, rem; + + left = interp_exec(b->left); + right = interp_exec(b->right); + mpz_init(l); mpz_init(r); mpz_init(rem); + mpz_tdiv_q(l, mpq_numref(left.num), mpq_denref(left.num)); + mpz_tdiv_q(r, mpq_numref(right.num), mpq_denref(right.num)); + mpz_tdiv_r(rem, l, r); + rv = val_init(Tnum); + mpq_set_z(rv.num, rem); + mpz_clear(r); mpz_clear(l); mpz_clear(rem); + break; + } case Negate: rv = interp_exec(b->right); mpq_neg(rv.num, rv.num);