Add more math functions

This commit is contained in:
2025-09-24 05:35:45 -07:00
parent 02736718dc
commit 1118d143fc
2 changed files with 59 additions and 7 deletions

View File

@ -2711,7 +2711,7 @@ static inline LispVal *copy_number(LispVal *v) {
} else if (INTEGERP(v)) { } else if (INTEGERP(v)) {
return make_lisp_integer(((LispInteger *) v)->value); return make_lisp_integer(((LispInteger *) v)->value);
} else { } else {
abort(); Fthrow(Qtype_error, Qnil);
} }
} }
@ -2719,10 +2719,10 @@ DEFUN(add, "+", (LispVal * args)) {
if (NILP(args)) { if (NILP(args)) {
return make_lisp_integer(0); return make_lisp_integer(0);
} }
LispVal *out = copy_number(Fhead(args)); LispVal *out = copy_number(HEAD(args));
FOREACH(arg, Ftail(args)) { FOREACH(arg, TAIL(args)) {
LispVal *old_out = out; LispVal *old_out = out;
WITH_CLEANUP_DOUBLE_PTR(old_out, { WITH_CLEANUP(old_out, {
ONE_MATH_OPERAION(+, out, out, arg); // ONE_MATH_OPERAION(+, out, out, arg); //
}); });
} }
@ -2733,16 +2733,64 @@ DEFUN(sub, "-", (LispVal * args)) {
if (NILP(args)) { if (NILP(args)) {
return make_lisp_integer(0); return make_lisp_integer(0);
} }
LispVal *out = copy_number(Fhead(args)); LispVal *out = copy_number(HEAD(args));
FOREACH(arg, Ftail(args)) { FOREACH(arg, TAIL(args)) {
LispVal *old_out = out; LispVal *old_out = out;
WITH_CLEANUP_DOUBLE_PTR(old_out, { WITH_CLEANUP(old_out, {
ONE_MATH_OPERAION(-, out, out, arg); // ONE_MATH_OPERAION(-, out, out, arg); //
}); });
} }
return out; return out;
} }
DEFUN(mul, "*", (LispVal * args)) {
if (NILP(args)) {
return make_lisp_integer(1);
}
LispVal *out = copy_number(HEAD(args));
FOREACH(arg, TAIL(args)) {
LispVal *old_out = out;
WITH_CLEANUP(old_out, {
ONE_MATH_OPERAION(*, out, out, arg); //
});
}
return out;
}
DEFUN(div, "/", (LispVal * first, LispVal *rest)) {
if (NILP(rest)) {
if (INTEGERP(first)) {
return make_lisp_float(1.0 / ((LispInteger *) first)->value);
} else if (FLOATP(first)) {
return make_lisp_float(1.0 / ((LispFloat *) first)->value);
} else {
Fthrow(Qtype_error, Qnil);
}
}
LispVal *out = copy_number(HEAD(rest));
FOREACH(arg, TAIL(rest)) {
LispVal *old_out = out;
WITH_CLEANUP(old_out, {
ONE_MATH_OPERAION(*, out, out, arg); //
});
}
if (FLOATP(first)) {
LispVal *old_out = out;
ONE_MATH_OPERAION(/, out, first, out);
refcount_unref(old_out);
} else if (INTEGERP(first)) {
LispVal *old_out = out;
LispVal *ff = make_lisp_float(((LispInteger *) first)->value);
ONE_MATH_OPERAION(/, out, ff, out);
refcount_unref(ff);
refcount_unref(old_out);
} else {
refcount_unref(out);
Fthrow(Qtype_error, Qnil);
}
return out;
}
// #################### // ####################
// # Vector Functions # // # Vector Functions #
// #################### // ####################
@ -3434,6 +3482,8 @@ static void register_symbols_and_functions(void) {
REGISTER_FUNCTION(add, "(&rest nums)", "Return the sun of NUMS."); REGISTER_FUNCTION(add, "(&rest nums)", "Return the sun of NUMS.");
REGISTER_FUNCTION(sub, "(&rest nums)", REGISTER_FUNCTION(sub, "(&rest nums)",
"Return (head NUMS) - (apply '+ (tail NUMS))."); "Return (head NUMS) - (apply '+ (tail NUMS)).");
REGISTER_FUNCTION(mul, "(&rest nums)", "");
REGISTER_FUNCTION(div, "(first &rest rest)", "");
REGISTER_FUNCTION( REGISTER_FUNCTION(
if, "(cond then &rest else)", if, "(cond then &rest else)",
"Evaluate THEN if COND is non-nil, otherwise evaluate ELSE."); "Evaluate THEN if COND is non-nil, otherwise evaluate ELSE.");

View File

@ -540,6 +540,8 @@ DECLARE_FUNCTION(num_eq, (LispVal * n1, LispVal *n2));
DECLARE_FUNCTION(num_gt, (LispVal * n1, LispVal *n2)); DECLARE_FUNCTION(num_gt, (LispVal * n1, LispVal *n2));
DECLARE_FUNCTION(add, (LispVal * args)); DECLARE_FUNCTION(add, (LispVal * args));
DECLARE_FUNCTION(sub, (LispVal * args)); DECLARE_FUNCTION(sub, (LispVal * args));
DECLARE_FUNCTION(mul, (LispVal * args));
DECLARE_FUNCTION(div, (LispVal * first, LispVal *rest));
// #################### // ####################
// # Vector Functions # // # Vector Functions #