/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* $Header: b3fpr.c,v 1.4 85/08/22 16:58:15 timo Exp $ */ /* B formula/predicate invocation */ #include "b.h" #include "b0fea.h" #include "b1obj.h" #include "b3err.h" #include "b3sem.h" #include "b3sou.h" #define Other 0 #define Nume 1 #define In 1 #define Not_in 2 #ifdef EXT_COMMAND #define Char_ready 3 #endif /* * Table defining all predefined functions (but not propositions). */ #ifdef EXT_COMMAND extern value e_getchar(); extern value e_screensize(); extern outcome e_ch_ready(); #endif EXT_COMMAND struct funtab { string f_name; literal f_adic, f_kind; value (*f_fun)(); bool f_extended; } funtab[] = { {"~", Mon, Nume, approximate}, {"+", Mon, Nume, copy}, {"+", Dya, Nume, sum}, {"-", Mon, Nume, negated}, {"-", Dya, Nume, diff}, {"*/", Mon, Nume, numerator}, {"/*", Mon, Nume, denominator}, {"*", Dya, Nume, prod}, {"/", Dya, Nume, quot}, {"**", Dya, Nume, power}, {"^", Dya, Other, concat}, {"^^", Dya, Other, repeat}, {"<<", Dya, Other, adjleft}, {"><", Dya, Other, centre}, {">>", Dya, Other, adjright}, {"#", Mon, Other, size}, {"#", Dya, Other, size2}, {"pi", Zer, Other, pi}, {"e", Zer, Other, e}, {"abs", Mon, Nume, absval}, {"sign", Mon, Nume, signum}, {"floor", Mon, Nume, floorf}, {"ceiling",Mon, Nume, ceilf}, {"round", Mon, Nume, round1}, {"round", Dya, Nume, round2}, {"mod", Dya, Nume, mod}, {"root", Mon, Nume, root1}, {"root", Dya, Nume, root2}, {"sin", Mon, Nume, sin1}, {"cos", Mon, Nume, cos1}, {"tan", Mon, Nume, tan1}, {"atan",Mon, Nume, atn1}, {"atan",Dya, Nume, atn2}, {"exp", Mon, Nume, exp1}, {"log", Mon, Nume, log1}, {"log", Dya, Nume, log2}, {"keys", Mon, Other, keys}, {"th'of",Dya, Other, th_of}, {"min", Mon, Other, min1}, {"min", Dya, Other, min2}, {"max", Mon, Other, max1}, {"max", Dya, Other, max2}, #ifdef EXT_COMMAND /* Extended group: */ {"get'char", Zer, Other, e_getchar, Yes}, {"screen'size", Zer, Other, e_screensize, Yes}, #endif {"", Dya, Other, NULL} /*sentinel*/ }; Visible Procedure initfpr() { struct funtab *fp; value r, f, pname; extern bool extcmds; /* Flag set by -E option */ for (fp= funtab; *(fp->f_name) != '\0'; ++fp) { #ifdef EXT_COMMAND if (fp->f_extended && !extcmds) continue; #endif /* Define function */ r= mk_text(fp->f_name); f= mk_fun(fp->f_adic, (intlet) (fp-funtab), NilTree, Yes); pname= permkey(r, fp->f_adic); def_unit(pname, f); release(f); release(r); release(pname); } defprd("in", Dya, In); defprd("not'in", Dya, Not_in); #ifdef EXT_COMMAND if (extcmds) defprd("char'ready", Zer, Char_ready); #endif } Hidden Procedure defprd(repr, adic, pre) string repr; literal adic; intlet pre; { value r= mk_text(repr), p= mk_prd(adic, pre, NilTree, Yes), pname; pname= permkey(r, adic); def_unit(pname, p); release(p); release(r); release(pname); } /* returns if a given test/yield exists *without faults* */ Hidden bool is_funprd(t, f, adicity, func) value t, *f; literal adicity; bool func; { value *aa; if (!is_unit(t, adicity, &aa)) return No; if (still_ok) { if (func) { if (!Is_function(*aa)) return No; } else { if (!Is_predicate(*aa)) return No; } *f= *aa; return Yes; } else return No; } Visible bool is_zerfun(t, f) value t, *f; { return is_funprd(t, f, Zer, Yes); } Visible bool is_monfun(t, f) value t, *f; { return is_funprd(t, f, Mon, Yes); } Visible bool is_dyafun(t, f) value t, *f; { return is_funprd(t, f, Dya, Yes); } Visible bool is_zerprd(t, p) value t, *p; { return is_funprd(t, p, Zer, No); } Visible bool is_monprd(t, p) value t, *p; { return is_funprd(t, p, Mon, No); } Visible bool is_dyaprd(t, p) value t, *p; { return is_funprd(t, p, Dya, No); } Visible value pre_fun(nd1, pre, nd2) value nd1, nd2; intlet pre; { struct funtab *fp= &funtab[pre]; literal adic= fp->f_adic; if (fp->f_kind == Nume && adic != Zer) { /* check types */ if (adic == Dya && !Is_number(nd1)) { error3(MESSMAKE(fp->f_name), Vnil, MESS(4500, " has a non-numeric left operand")); return Vnil; } else if (!Is_number(nd2)) { error3(MESSMAKE(fp->f_name), Vnil, MESS(4501, " has a non-numeric right operand")); return Vnil; } } switch (adic) { case Zer: return((*fp->f_fun)()); case Mon: return((*fp->f_fun)(nd2)); case Dya: return((*fp->f_fun)(nd1, nd2)); default: syserr(MESS(3300, "pre-defined fpr wrong")); /*NOTREACHED*/ } } Visible outcome pre_prop(nd1, pre, nd2) value nd1, nd2; intlet pre; { switch (pre) { case In: return in(nd1, nd2); case Not_in: return !in(nd1, nd2); #ifdef EXT_COMMAND case Char_ready: return e_ch_ready(); #endif default: syserr(MESS(3301, "predicate not covered by proposition")); /*NOTREACHED*/ } }