+static naRef f_floor(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ if(naIsNil(a))
+ naRuntimeError(c, "non numeric argument to floor()");
+ a.num = floor(a.num);
+ return VALIDATE(a);
+}
+
+static naRef f_ceil(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ if(naIsNil(a))
+ naRuntimeError(c, "non numeric argument to ceil()");
+ a.num = ceil(a.num);
+ return VALIDATE(a);
+}
+
+static naRef f_fmod(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ naRef b = naNumValue(argc > 1 ? args[1] : naNil());
+ if(naIsNil(a) || naIsNil(b))
+ naRuntimeError(c, "non numeric arguments to fmod()");
+
+ a.num = fmod(a.num, b.num);
+ return VALIDATE(a);
+}
+
+static naRef f_clamp(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ naRef b = naNumValue(argc > 1 ? args[1] : naNil());
+ naRef x = naNumValue(argc > 2 ? args[2] : naNil());
+
+ if(naIsNil(a) || naIsNil(b) || naIsNil(x))
+ naRuntimeError(c, "non numeric arguments to clamp()");
+
+ if (a.num < b.num) b.num = a.num;
+ if (b.num > x.num) b.num = x.num;
+ return VALIDATE(b);
+}
+
+static naRef f_periodic(naContext c, naRef me, int argc, naRef* args)
+{
+ double range;
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ naRef b = naNumValue(argc > 1 ? args[1] : naNil());
+ naRef x = naNumValue(argc > 2 ? args[2] : naNil());
+
+ if(naIsNil(a) || naIsNil(b) || naIsNil(x))
+ naRuntimeError(c, "non numeric arguments to periodic()");
+
+ range = b.num - a.num;
+ x.num = x.num - range*floor((x.num - a.num)/range);
+ // two security checks that can only happen due to roundoff
+ if (x.num <= a.num)
+ x.num = a.num;
+ if (b.num <= x.num)
+ x.num = b.num;
+ return VALIDATE(x);
+
+// x.num = SGMiscd::normalizePeriodic(a, b, x);
+ return VALIDATE(x);
+}
+
+static naRef f_round(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ naRef b = naNumValue(argc > 1 ? args[1] : naNil());
+#ifdef _MSC_VER
+ double x,y;
+#endif
+ if(naIsNil(a))
+ naRuntimeError(c, "non numeric arguments to round()");
+ if (naIsNil(b))
+ b.num = 1.0;
+
+#ifdef _MSC_VER // MSVC is not C99-compatible, no round() in math.h
+ y = a.num / b.num;
+ x = floor(y + 0.5);
+#else
+ double x = round(a.num / b.num);
+#endif
+ a.num = x * b.num;
+
+ return VALIDATE(a);
+}
+
+
+static naRef f_tan(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ if(naIsNil(a))
+ naRuntimeError(c, "non numeric arguments to tan()");
+
+ a.num = tan(a.num);
+ return VALIDATE(a);
+}
+
+static naRef f_asin(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ if(naIsNil(a))
+ naRuntimeError(c, "non numeric argument to asin()");
+ a.num = asin(a.num);
+ return VALIDATE(a);
+}
+
+static naRef f_acos(naContext c, naRef me, int argc, naRef* args)
+{
+ naRef a = naNumValue(argc > 0 ? args[0] : naNil());
+ if(naIsNil(a))
+ naRuntimeError(c, "non numeric argument to acos()");
+ a.num = acos(a.num);
+ return VALIDATE(a);
+}
+
+static naCFuncItem funcs[] = {