Repository: asteroid-lang/asteroid (language: python)

Issue:
add 'round' function to math module
add 'round' function to math module so that something like this will work,
```
load system math.

assert (math @round 19.6 == 20).
assert (math @round 19.2 == 19).
```


Discussion / hints:
This seems like a good first issue to tackle - I'd love to take it on.

Should we introduce an optional second "precision" argument like in python, or should we avoid that to keep it consistent with the existing `floor` and `ceil` functions?
```
load system math.

assert (math @round (3.14159) == 3).
assert (math @isclose (math @round (3.14159, 2), 3.14000)).
assert (math @isclose (math @round (3.14159, 3), 3.14200)).
```
FWIW, I would expect the one-argument version to return an integer, so if we decide to include an optional precision argument then the function would have different return types depending on the argument type. That doesn't seem like a huge deal to me, but I think it's worth consideration.
@ijchen Perfect! I would like to stick to the mathematical definition of ceil/floor/round where these functions always return an integer.  If you do decide to take this on please create a branch off branch dev-2.0.1 which is our current development branch for the next release.  Also, before you create a pull request for your changes make sure that you update the documentation and generate new docs and run the test suites.  You should probably also assign this to yourself so that it is clear that you are working on it.

If you like I can also add you to our Asteroid Slack channel.

Any questions, just give me a holler!
@lutzhamel Sounds good, and I'll make sure to branch off `dev-2.0.1`.

I don't see a way to assign myself - do I have permission to do so?

Yes, please add me to the Asteroid Slack. I actually do have a question so that would be helpful. My slack email is `ijchen@uri.edu`

Fix patch:
diff --git a/asteroid/modules/math.ast b/asteroid/modules/math.ast
index 2e89c9e7..c8d32629 100644
--- a/asteroid/modules/math.ast
+++ b/asteroid/modules/math.ast
@@ -165,6 +165,21 @@ __retval__ = ('integer', math.floor(val_x[1]))
 "
 end
 
+------------------------------------------------------------------
+function round
+------------------------------------------------------------------
+-- Return x rounded to the nearest integer. If two integers are equally close,
+-- x is rounded to the nearest even integer.
+with (x:%real) do return escape
+"
+global __retval__
+
+val_x = state.symbol_table.lookup_sym('x')
+
+__retval__ = ('integer', round(val_x[1]))
+"
+end
+
 ------------------------------------------------------------------
 function gcd
 ------------------------------------------------------------------
diff --git a/docs/Reference Guide.rst b/docs/Reference Guide.rst
index 7640596c..b4a9d2f8 100644
--- a/docs/Reference Guide.rst
+++ b/docs/Reference Guide.rst
@@ -1187,6 +1187,10 @@ math **@ceil** x:%real
 math **@floor** x:%real
       Returns the floor of x: the largest integer less than or equal to x.
 
+math **@round** x:%real
+      Returns x rounded to the nearest integer. If two integers are equally
+      close, x is rounded to the nearest even integer.
+
 math **@gcd** (a:%integer, b:%integer)
       Returns the greatest common denominator that both integers share.
 
diff --git a/docs/Reference Guide.txt b/docs/Reference Guide.txt
index 05994053..a42ea083 100644
--- a/docs/Reference Guide.txt
+++ b/docs/Reference Guide.txt
@@ -1044,6 +1044,10 @@ math **@ceil** x:%real
 math **@floor** x:%real
       Returns the floor of x: the largest integer less than or equal to x.
 
+math **@round** x:%real
+      Returns x rounded to the nearest integer. If two integers are equally
+      close, x is rounded to the nearest even integer.
+
 math **@gcd** (a:%integer, b:%integer)
       Returns the greatest common denominator that both integers share.
 


Test patch:
diff --git a/asteroid/test-suites/regression-tests/test147.ast b/asteroid/test-suites/regression-tests/test147.ast
new file mode 100644
index 00000000..e0c65f14
--- /dev/null
+++ b/asteroid/test-suites/regression-tests/test147.ast
@@ -0,0 +1,29 @@
+load system math.
+
+let test_cases = [
+    (3.14, 3),
+    (3.508, 4),
+    (12.99999, 13),
+    (13.00000, 13),
+    (13.00001, 13),
+    (13.49999, 13),
+    (13.50000, 14),
+    (13.50001, 14),
+    (13.99999, 14),
+    (14.00000, 14),
+    (14.00001, 14),
+    (14.49999, 14),
+    (14.50000, 14),
+    (12.5, 12),
+    (13.5, 14),
+    (14.5, 14),
+    (15.5, 16),
+    (0.0, 0),
+    (-0.0, 0),
+    (-53.246, -53),
+    (-53.5, -54)
+].
+
+for (input, expected_output) in test_cases do
+    assert (math @round input == expected_output).
+end