From f55de4d6fa390e97cb11bcb13786e47bf5dd2db2 Mon Sep 17 00:00:00 2001 From: Rick L Bird Date: Thu, 5 May 2011 18:07:26 -0400 Subject: [PATCH] PennMUSH 1.8.3p11 Author: captdeaf@gmail.com Date: Fri Oct 16 02:38:04 2009 +0000 lmath()-able versions of lt, gt, lte, gte, eq and neq. And similarly, they can now accept more than 2 args. Fixes #146 --- src/function.c | 12 ++-- src/funmath.c | 139 ++++++++++++++++++++++++++++++++++----------- src/lmathtab.gperf | 14 ++++- 3 files changed, 124 insertions(+), 41 deletions(-) diff --git a/src/function.c b/src/function.c index f8e7db3..26939ec 100644 --- a/src/function.c +++ b/src/function.c @@ -414,7 +414,7 @@ FUNTAB flist[] = { {"EMPOWER", fun_empower, 2, 2, FN_REG}, {"ENTRANCES", fun_entrances, 0, 4, FN_REG}, {"ETIMEFMT", fun_etimefmt, 2, 2, FN_REG}, - {"EQ", fun_eq, 2, 2, FN_REG}, + {"EQ", fun_eq, 2, INT_MAX, FN_REG}, {"EVAL", fun_eval, 2, 2, FN_REG}, {"ESCAPE", fun_escape, 1, -1, FN_REG}, {"EXIT", fun_exit, 1, 1, FN_REG}, @@ -445,8 +445,8 @@ FUNTAB flist[] = { {"GRABALL", fun_graball, 2, 4, FN_REG}, {"GREP", fun_grep, 3, 3, FN_REG}, {"GREPI", fun_grep, 3, 3, FN_REG}, - {"GT", fun_gt, 2, 2, FN_REG}, - {"GTE", fun_gte, 2, 2, FN_REG}, + {"GT", fun_gt, 2, INT_MAX, FN_REG}, + {"GTE", fun_gte, 2, INT_MAX, FN_REG}, {"HASATTR", fun_hasattr, 1, 2, FN_REG}, {"HASATTRP", fun_hasattr, 1, 2, FN_REG}, {"HASATTRPVAL", fun_hasattr, 1, 2, FN_REG}, @@ -519,8 +519,8 @@ FUNTAB flist[] = { {"LSEARCH", fun_lsearch, 1, INT_MAX, FN_REG}, {"LSEARCHR", fun_lsearch, 1, INT_MAX, FN_REG}, {"LSTATS", fun_lstats, 0, 1, FN_REG}, - {"LT", fun_lt, 2, 2, FN_REG}, - {"LTE", fun_lte, 2, 2, FN_REG}, + {"LT", fun_lt, 2, INT_MAX, FN_REG}, + {"LTE", fun_lte, 2, INT_MAX, FN_REG}, {"LVCON", fun_dbwalker, 1, 1, FN_REG}, {"LVEXITS", fun_dbwalker, 1, 1, FN_REG}, {"LVPLAYERS", fun_dbwalker, 1, 1, FN_REG}, @@ -577,7 +577,7 @@ FUNTAB flist[] = { {"NVPLAYERS", fun_dbwalker, 1, 1, FN_REG}, {"NVTHINGS", fun_dbwalker, 1, 1, FN_REG}, {"NEARBY", fun_nearby, 2, 2, FN_REG}, - {"NEQ", fun_neq, 2, 2, FN_REG}, + {"NEQ", fun_neq, 2, INT_MAX, FN_REG}, {"NEXT", fun_next, 1, 1, FN_REG}, {"NEXTDBREF", fun_nextdbref, 0, 0, FN_REG}, {"NLSEARCH", fun_lsearch, 1, INT_MAX, FN_REG}, diff --git a/src/funmath.c b/src/funmath.c index 3688c58..7e11185 100644 --- a/src/funmath.c +++ b/src/funmath.c @@ -47,7 +47,9 @@ static double frac(double v, double *restrict n, double *restrict d, double error); int format_long(intmax_t n, char *buff, char **bp, int maxlen, int base); - +static void lmathcomp(char **ptr, int nptr, char *buff, char **bp, + int eqokay, int isgt); + extern int roman_numeral_table[256]; /* Generated by gperf */ @@ -203,64 +205,42 @@ FUNCTION(fun_mul) /* ARGSUSED */ FUNCTION(fun_gt) { - if (!is_number(args[0]) || !is_number(args[1])) { - safe_str(T(e_nums), buff, bp); - return; - } - safe_boolean(parse_number(args[0]) > parse_number(args[1]), buff, bp); + math_gt(args, nargs, buff, bp); } /* ARGSUSED */ FUNCTION(fun_gte) { - if (!is_number(args[0]) || !is_number(args[1])) { - safe_str(T(e_nums), buff, bp); - return; - } - safe_boolean(parse_number(args[0]) >= parse_number(args[1]), buff, bp); + math_gte(args, nargs, buff, bp); } -/* ARGSUSED */ + /* ARGSUSED */ FUNCTION(fun_lt) { - if (!is_number(args[0]) || !is_number(args[1])) { - safe_str(T(e_nums), buff, bp); - return; - } - safe_boolean(parse_number(args[0]) < parse_number(args[1]), buff, bp); + math_lt(args, nargs, buff, bp); } + /* ARGSUSED */ FUNCTION(fun_lte) { - if (!is_number(args[0]) || !is_number(args[1])) { - safe_str(T(e_nums), buff, bp); - return; - } - safe_boolean(parse_number(args[0]) <= parse_number(args[1]), buff, bp); + math_lte(args, nargs, buff, bp); } + /* ARGSUSED */ FUNCTION(fun_eq) { - if (!is_number(args[0]) || !is_number(args[1])) { - safe_str(T(e_nums), buff, bp); - return; - } - safe_boolean(EQ(parse_number(args[0]), parse_number(args[1])), buff, bp); + math_eq(args, nargs, buff, bp); } -/* ARGSUSED */ + /* ARGSUSED */ FUNCTION(fun_neq) { - if (!is_number(args[0]) || !is_number(args[1])) { - safe_str(T(e_nums), buff, bp); - return; - } - safe_boolean(!EQ(parse_number(args[0]), parse_number(args[1])), buff, bp); + math_neq(args, nargs, buff, bp); } -/* ARGSUSED */ + /* ARGSUSED */ FUNCTION(fun_max) { math_max(args, nargs, buff, bp); @@ -1485,6 +1465,97 @@ FUNCTION(fun_xor) math_xor(args, nargs, buff, bp); } +MATH_FUNC(math_lt) { + lmathcomp(ptr, nptr, buff, bp, 0, 0); +} + +MATH_FUNC(math_gt) { + lmathcomp(ptr, nptr, buff, bp, 0, 1); +} + +MATH_FUNC(math_lte) { + lmathcomp(ptr, nptr, buff, bp, 1, 0); +} + +MATH_FUNC(math_gte) { + lmathcomp(ptr, nptr, buff, bp, 1, 1); +} + +MATH_FUNC(math_eq) { + // Yes, I'm evil. :D + lmathcomp(ptr, nptr, buff, bp, 1, -1); +} + +// This is used for lt, gt, lte, gte, eq +static void +lmathcomp(char **ptr, int nptr, char *buff, char **bp, int eqokay, int isgt) +{ + NVAL prev = 0; + NVAL next = 0; + int n; + + if (nptr < 2) { + safe_str(T("#-1 COMPARISON REQUIRES 2 OR MORE NUMBERS"), buff, bp); + return; + } + + if (!is_number(ptr[1])) { + safe_str(T(e_nums), buff, bp); + return; + } + prev = parse_number(ptr[0]); + for (n = 1; n < nptr; n++, prev = next) { + if (!is_number(ptr[n])) { + safe_str(T(e_nums), buff, bp); + return; + } + next = parse_number(ptr[n]); + // Is eqok? + if (EQ(next, prev)) { + if (eqokay) continue; + safe_chr('0', buff, bp); + return; + } + if ((prev > next) != isgt) { + safe_chr('0', buff, bp); + return; + } + } + + safe_chr('1', buff, bp); +} + +MATH_FUNC(math_neq) { + NVAL prev = 0; + NVAL next = 0; + int n; + + if (nptr < 2) { + safe_str(T("#-1 COMPARISON REQUIRES 2 OR MORE NUMBERS"), buff, bp); + return; + } + + if (!is_number(ptr[1])) { + safe_str(T(e_nums), buff, bp); + return; + } + prev = parse_number(ptr[0]); + for (n = 1; n < nptr; n++, prev = next) { + if (!is_number(ptr[n])) { + safe_str(T(e_nums), buff, bp); + return; + } + next = parse_number(ptr[n]); + if (!EQ(next,prev)) { + safe_chr('1', buff, bp); + return; + } + } + + safe_chr('0', buff, bp); +} + + /** Return the spelled-out version of an integer. * \param num string containing an integer to spell out. * \param len length of num, which must be a multiple of 3, max 15. diff --git a/src/lmathtab.gperf b/src/lmathtab.gperf index 6c61d70..b7022ea 100644 --- a/src/lmathtab.gperf +++ b/src/lmathtab.gperf @@ -43,7 +43,13 @@ MATH_PROTO(math_median); MATH_PROTO(math_stddev); MATH_PROTO(math_dist2d); MATH_PROTO(math_dist3d); - +MATH_PROTO(math_lt); +MATH_PROTO(math_lte); +MATH_PROTO(math_gt); +MATH_PROTO(math_gte); +MATH_PROTO(math_eq); +MATH_PROTO(math_neq); + /** A math function. */ %} struct math { @@ -76,6 +82,12 @@ MEDIAN, math_median STDDEV, math_stddev DIST2D, math_dist2d DIST3D, math_dist3d +LT, math_lt +LTE, math_lte +GT, math_gt +GTE, math_gte +EQ, math_eq +NEQ, math_neq %% typedef struct math MATH; -- 2.30.2