static Lisp_Object plusir(Lisp_Object a, Lisp_Object b) /* * fixnum and ratio, but also valid for bignum and ratio. * Note that if the inputs were in lowest terms there is no need for * and GCD calculations here. */ { Lisp_Object nil; push(b); a = times2(a, denominator(b)); nil = C_nil; if (!exception_pending()) a = plus2(a, numerator(stack[0])); pop(b); errexit(); return make_ratio(a, denominator(b)); }
char *look_in_lisp_variable(char *o, int prefix) { Lisp_Object nil, var; /* * I will start by tagging a '$' (or whatever) on in front of the * parameter name. */ o[0] = (char)prefix; var = make_undefined_symbol(o); nil = C_nil; /* * make_undefined_symbol() could fail either if we had utterly run out * of memory or if somebody generated an interrupt (eg ^C) around now. Ugh. */ if (exception_pending()) { flip_exception(); return NULL; } /* * If the variable $name was undefined then I use an empty replacement * text for it. Otherwise I need to look harder at its value. */ if (qvalue(var) == unset_var) return o; else { Header h; intptr_t len; var = qvalue(var); /* * Mostly I expect that the value will be a string or symbol. */ #ifdef COMMON if (complex_stringp(var)) { var = simplify_string(var); nil = C_nil; if (exception_pending()) { flip_exception(); return NULL; } } #endif /* COMMON */ if (symbolp(var)) { var = get_pname(var); nil = C_nil; if (exception_pending()) { flip_exception(); return NULL; } h = vechdr(var); } else if (!is_vector(var) || type_of_header(h = vechdr(var)) != TYPE_STRING) return NULL; len = length_of_header(h) - CELL; /* * Copy the characters from the string or from the name of the variable * into the file-name buffer. There could at present be a crash here * if the expansion was very very long and overflowed my buffer. Tough * luck for now - people doing that (maybe) get what they (maybe) deserve. */ memcpy(o, (char *)var + (CELL - TAG_VECTOR), (size_t)len); o = o + len; return o; } }
static Lisp_Object plusrr(Lisp_Object a, Lisp_Object b) /* * Adding two ratios involves some effort to keep the result in * lowest terms. */ { Lisp_Object nil = C_nil; Lisp_Object na = numerator(a), nb = numerator(b); Lisp_Object da = denominator(a), db = denominator(b); Lisp_Object w = nil; push5(na, nb, da, db, nil); #define g stack[0] #define db stack[-1] #define da stack[-2] #define nb stack[-3] #define na stack[-4] g = gcd(da, db); nil = C_nil; if (exception_pending()) goto fail; /* * all the calls to quot2() in this procedure are expected - nay required - * to give exact integer quotients. */ db = quot2(db, g); nil = C_nil; if (exception_pending()) goto fail; g = quot2(da, g); nil = C_nil; if (exception_pending()) goto fail; na = times2(na, db); nil = C_nil; if (exception_pending()) goto fail; nb = times2(nb, g); nil = C_nil; if (exception_pending()) goto fail; na = plus2(na, nb); nil = C_nil; if (exception_pending()) goto fail; da = times2(da, db); nil = C_nil; if (exception_pending()) goto fail; g = gcd(na, da); nil = C_nil; if (exception_pending()) goto fail; na = quot2(na, g); nil = C_nil; if (exception_pending()) goto fail; da = quot2(da, g); nil = C_nil; if (exception_pending()) goto fail; w = make_ratio(na, da); /* * All the goto statements and the label seem a fair way of expressing * the common action that has to be taken if an error or interrupt is * detected during any of the intermediate steps here. Anyone who * objects can change it if they really want... */ fail: popv(5); return w; #undef na #undef nb #undef da #undef db #undef g }