Annotation of OpenXM_contrib2/asir2000/builtin/pf.c, Revision 1.9
1.2 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.9 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/builtin/pf.c,v 1.8 2004/06/27 03:15:57 noro Exp $
1.2 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include "math.h"
52: #include "parse.h"
53: #if 0
54: #include <alloca.h>
55: #endif
56:
57: double const_pi(),const_e();
58:
59: void make_ihyp(void);
60: void make_hyp(void);
61: void make_itri(void);
62: void make_tri(void);
63: void make_exp(void);
64: void simplify_pow(PFINS,Obj *);
65:
66: void Pfunctor(),Pargs(),Pfunargs(),Pvtype(),Pcall(),Pdeval();
67: void Pregister_handler();
1.4 noro 68: void Peval_quote();
1.7 noro 69: void Pmapat();
1.9 ! noro 70: void Padd_handler();
! 71: void Plist_handler();
! 72: void Pclear_handler();
1.1 noro 73:
74: struct ftab puref_tab[] = {
1.7 noro 75: {"mapat",Pmapat,-99999999},
1.1 noro 76: {"functor",Pfunctor,1},
77: {"args",Pargs,1},
78: {"funargs",Pfunargs,1},
79: {"register_handler",Pregister_handler,1},
1.9 ! noro 80: {"add_handler",Padd_handler,2},
! 81: {"list_handler",Plist_handler,1},
! 82: {"clear_handler",Pclear_handler,1},
1.1 noro 83: {"call",Pcall,2},
84: {"vtype",Pvtype,1},
85: {"deval",Pdeval,1},
1.4 noro 86: {"eval_quote",Peval_quote,1},
1.1 noro 87: {0,0,0},
88: };
89:
1.6 ohara 90: #if defined(PARI)
1.1 noro 91: int p_pi(),p_e();
92: int p_log(),p_exp(),p_pow();
93: int p_sin(),p_cos(),p_tan(),p_asin(),p_acos(),p_atan();
94: int p_sinh(),p_cosh(),p_tanh(),p_asinh(),p_acosh(),p_atanh();
95: #else
96: int p_pi,p_e;
97: int p_log,p_exp,p_pow;
98: int p_sin,p_cos,p_tan,p_asin,p_acos,p_atan;
99: int p_sinh,p_cosh,p_tanh,p_asinh,p_acosh,p_atanh;
100: #endif
101:
102: static V *uarg,*darg;
103: static P x,y;
104: static PF pidef,edef;
105: static PF logdef,expdef,powdef;
106: static PF sindef,cosdef,tandef;
107: static PF asindef,acosdef,atandef;
108: static PF sinhdef,coshdef,tanhdef;
109: static PF asinhdef,acoshdef,atanhdef;
110:
111: #define OALLOC(p,n) ((p)=(Obj *)CALLOC((n),sizeof(Obj)))
112:
113: double const_pi() { return 3.14159265358979323846264338327950288; }
114: double const_e() { return 2.718281828459045235360287471352662497; }
115:
116: void pf_init() {
117: uarg = (V *)CALLOC(1,sizeof(V));
118: uarg[0] = &oVAR[26]; MKV(uarg[0],x);
119:
120: darg = (V *)CALLOC(2,sizeof(V));
121: darg[0] = &oVAR[26];
122: darg[1] = &oVAR[27]; MKV(darg[1],y);
123:
124: mkpf("@pi",0,0,0,(int (*)())p_pi,const_pi,0,&pidef);
125: mkpf("@e",0,0,0,(int (*)())p_e,const_e,0,&edef);
126:
127: mkpf("log",0,1,uarg,(int (*)())p_log,log,0,&logdef);
128: mkpf("exp",0,1,uarg,(int (*)())p_exp,exp,0,&expdef);
129: mkpf("pow",0,2,darg,(int (*)())p_pow,pow,(int (*)())simplify_pow,&powdef);
130:
131: mkpf("sin",0,1,uarg,(int (*)())p_sin,sin,0,&sindef);
132: mkpf("cos",0,1,uarg,(int (*)())p_cos,cos,0,&cosdef);
133: mkpf("tan",0,1,uarg,(int (*)())p_tan,tan,0,&tandef);
134: mkpf("asin",0,1,uarg,(int (*)())p_asin,asin,0,&asindef);
135: mkpf("acos",0,1,uarg,(int (*)())p_acos,acos,0,&acosdef);
136: mkpf("atan",0,1,uarg,(int (*)())p_atan,atan,0,&atandef);
137:
138: mkpf("sinh",0,1,uarg,(int (*)())p_sinh,sinh,0,&sinhdef);
139: mkpf("cosh",0,1,uarg,(int (*)())p_cosh,cosh,0,&coshdef);
140: mkpf("tanh",0,1,uarg,(int (*)())p_tanh,tanh,0,&tanhdef);
141: #if !defined(VISUAL)
142: mkpf("asinh",0,1,uarg,(int (*)())p_asinh,asinh,0,&asinhdef);
143: mkpf("acosh",0,1,uarg,(int (*)())p_acosh,acosh,0,&acoshdef);
144: mkpf("atanh",0,1,uarg,(int (*)())p_atanh,atanh,0,&atanhdef);
145: #endif
146: make_exp();
147: make_tri();
148: make_itri();
149: make_hyp();
150: #if !defined(VISUAL)
151: make_ihyp();
152: #endif
153: }
154:
155: void make_exp() {
156: V v;
157: P u,vexp,vlog,vpow;
158: Obj *args;
159:
160: mkpfins(expdef,uarg,&v); MKV(v,vexp);
161: mkpfins(powdef,darg,&v); MKV(v,vpow);
162: mkpfins(logdef,uarg,&v); MKV(v,vlog);
163:
164: /* d/dx(log(x)) = 1/x */
165: OALLOC(logdef->deriv,1); divr(CO,(Obj)ONE,(Obj)x,&logdef->deriv[0]);
166:
167: /* d/dx(exp(x)) = exp(x) */
168: OALLOC(expdef->deriv,1); expdef->deriv[0] = (Obj)vexp;
169:
170: /* d/dy(x^y) = log(x)*x^y */
171: OALLOC(powdef->deriv,2); mulp(CO,vpow,vlog,(P *)&powdef->deriv[1]);
172:
173: /* d/dx(x^y) = y*x^(y-1) */
174: args = (Obj *)ALLOCA(2*sizeof(Obj));
175: args[0] = (Obj)x; subp(CO,y,(P)ONE,(P *)&args[1]);
176: _mkpfins(powdef,args,&v); MKV(v,u);
177: mulr(CO,(Obj)u,(Obj)y,&powdef->deriv[0]);
178: }
179:
180: void make_tri() {
181: V v;
182: P vcos,vsin,vtan,t;
183:
184: mkpfins(cosdef,uarg,&v); MKV(v,vcos);
185: mkpfins(sindef,uarg,&v); MKV(v,vsin);
186: mkpfins(tandef,uarg,&v); MKV(v,vtan);
187:
188: /* d/dx(sin(x)) = cos(x) */
189: OALLOC(sindef->deriv,1); sindef->deriv[0] = (Obj)vcos;
190:
191: /* d/dx(cos(x)) = -sin(x) */
192: OALLOC(cosdef->deriv,1); chsgnp(vsin,(P *)&cosdef->deriv[0]);
193:
194: /* d/dx(tan(x)) = 1+tan(x)^2 */
195: OALLOC(tandef->deriv,1);
196: mulr(CO,(Obj)vtan,(Obj)vtan,(Obj *)&t); addp(CO,(P)ONE,t,(P *)&tandef->deriv[0]);
197: }
198:
199: void make_itri() {
200: P t,xx;
201: Q mtwo;
202: V v;
203: Obj *args;
204:
205: /* d/dx(asin(x)) = (1-x^2)^(-1/2) */
206: OALLOC(asindef->deriv,1);
207: args = (Obj *)ALLOCA(2*sizeof(Obj));
208: mulp(CO,x,x,&xx); subp(CO,(P)ONE,xx,(P *)&args[0]);
209: STOQ(-2,mtwo); divq(ONE,mtwo,(Q *)&args[1]);
210: _mkpfins(powdef,args,&v); MKV(v,t);
211: asindef->deriv[0] = (Obj)t;
212:
213: /* d/dx(acos(x)) = -(1-x^2)^(-1/2) */
214: OALLOC(acosdef->deriv,1); chsgnp((P)asindef->deriv[0],(P *)&acosdef->deriv[0]);
215:
216: /* d/dx(atan(x)) = 1/(x^2+1) */
217: OALLOC(atandef->deriv,1);
218: addp(CO,(P)ONE,xx,&t); divr(CO,(Obj)ONE,(Obj)t,&atandef->deriv[0]);
219: }
220:
221: void make_hyp() {
222: V v;
223: P vcosh,vsinh,vtanh,t;
224:
225: mkpfins(coshdef,uarg,&v); MKV(v,vcosh);
226: mkpfins(sinhdef,uarg,&v); MKV(v,vsinh);
227: mkpfins(tanhdef,uarg,&v); MKV(v,vtanh);
228:
229: /* d/dx(sinh(x)) = cosh(x) */
230: OALLOC(sinhdef->deriv,1); sinhdef->deriv[0] = (Obj)vcosh;
231:
232: /* d/dx(cosh(x)) = sinh(x) */
233: OALLOC(coshdef->deriv,1); coshdef->deriv[0] = (Obj)vsinh;
234:
235: /* d/dx(tanh(x)) = 1-tanh(x)^2 */
236: OALLOC(tanhdef->deriv,1);
237: mulr(CO,(Obj)vtanh,(Obj)vtanh,(Obj *)&t); subp(CO,(P)ONE,t,(P *)&tanhdef->deriv[0]);
238: }
239:
240: void make_ihyp() {
241: P t,xx;
242: Q mtwo;
243: V v;
244: Obj *args;
245:
246: /* d/dx(asinh(x)) = (1+x^2)^(-1/2) */
247: OALLOC(asinhdef->deriv,1);
248: args = (Obj *)ALLOCA(2*sizeof(Obj));
249: mulp(CO,x,x,&xx); addp(CO,(P)ONE,xx,(P *)&args[0]);
250: STOQ(-2,mtwo); divq(ONE,mtwo,(Q *)&args[1]);
251: _mkpfins(powdef,args,&v); MKV(v,t);
252: asinhdef->deriv[0] = (Obj)t;
253:
254: /* d/dx(acosh(x)) = (x^2-1)^(-1/2) */
255: OALLOC(acoshdef->deriv,1);
256: subp(CO,xx,(P)ONE,(P *)&args[0]);
257: _mkpfins(powdef,args,&v); MKV(v,t);
258: acoshdef->deriv[0] = (Obj)t;
259:
260: /* d/dx(atanh(x)) = 1/(1-x^2) */
261: OALLOC(atanhdef->deriv,1);
262: subp(CO,(P)ONE,xx,&t); divr(CO,(Obj)ONE,(Obj)t,&atanhdef->deriv[0]);
263: }
264:
265: void mkpow(vl,a,e,r)
266: VL vl;
267: Obj a;
268: Obj e;
269: Obj *r;
270: {
271: PFINS ins;
272: PFAD ad;
273:
274: ins = (PFINS)CALLOC(1,sizeof(PF)+2*sizeof(struct oPFAD));
275: ins->pf = powdef; ad = ins->ad;
276: ad[0].d = 0; ad[0].arg = a; ad[1].d = 0; ad[1].arg = e;
277: simplify_ins(ins,r);
278: }
279:
280: void simplify_pow(ins,rp)
281: PFINS ins;
282: Obj *rp;
283: {
284: PF pf;
285: PFAD ad;
286: Obj a0,a1;
287: V v;
288: P t;
289:
290: pf = ins->pf; ad = ins->ad; a0 = ad[0].arg; a1 = ad[1].arg;
291: if ( !a1 )
292: *rp = (Obj)ONE;
1.8 noro 293: else if ( !a0 ) {
294: if ( RATN(a1) && SGN((Q)a1)>0 )
295: *rp = 0;
296: else if ( RATN(a1) && SGN((Q)a1) < 0 )
297: error("simplify_pow : division by 0");
298: else {
299: instov(ins,&v); MKV(v,t); *rp = (Obj)t;
300: }
301: } else if ( NUM(a1) && INT(a1) )
1.1 noro 302: arf_pwr(CO,a0,a1,rp);
303: else {
304: instov(ins,&v); MKV(v,t); *rp = (Obj)t;
305: }
306: }
307:
308: #define ISPFINS(p)\
309: (p)&&(ID(p) == O_P)&&((int)VR((P)p)->attr!=V_PF)&&\
310: UNIQ(DEG(DC((P)p)))&&UNIQ(COEF(DC((P)p)))
311:
312: void Pfunctor(arg,rp)
313: NODE arg;
314: P *rp;
315: {
316: P p;
317: FUNC t;
318: PF pf;
319: PFINS ins;
320:
321: p = (P)ARG0(arg);
322: if ( !ISPFINS(p) )
323: *rp = 0;
324: else {
325: ins = (PFINS)VR(p)->priv; pf = ins->pf;
326: t = (FUNC)MALLOC(sizeof(struct oFUNC));
1.7 noro 327: t->name = t->fullname = pf->name; t->id = A_PURE; t->argc = pf->argc;
1.1 noro 328: t->f.puref = pf;
329: makesrvar(t,rp);
330: }
331: }
332:
333: void Pargs(arg,rp)
334: NODE arg;
335: LIST *rp;
336: {
337: P p;
338: PF pf;
339: PFAD ad;
340: PFINS ins;
341: NODE n,n0;
342: int i;
343:
344: p = (P)ARG0(arg);
345: if ( !ISPFINS(p) )
346: *rp = 0;
347: else {
348: ins = (PFINS)VR(p)->priv; ad = ins->ad; pf = ins->pf;
349: for ( i = 0, n0 = 0; i < pf->argc; i++ ) {
350: NEXTNODE(n0,n); BDY(n) = (pointer)ad[i].arg;
351: }
352: if ( n0 )
353: NEXT(n) = 0;
354: MKLIST(*rp,n0);
355: }
356: }
357:
358: void Pfunargs(arg,rp)
359: NODE arg;
360: LIST *rp;
361: {
362: P p;
363: P f;
364: FUNC t;
365: PF pf;
366: PFINS ins;
367: PFAD ad;
368: NODE n,n0;
369: int i;
370:
371: p = (P)ARG0(arg);
372: if ( !ISPFINS(p) )
373: *rp = 0;
374: else {
375: ins = (PFINS)VR(p)->priv; ad = ins->ad; pf = ins->pf;
376: t = (FUNC)MALLOC(sizeof(struct oFUNC));
1.7 noro 377: t->name = t->fullname = pf->name; t->id = A_PURE; t->argc = pf->argc;
1.1 noro 378: t->f.puref = pf;
379: makesrvar(t,&f);
1.5 noro 380: n = n0 = 0; NEXTNODE(n0,n); BDY(n) = (pointer)f;
1.1 noro 381: for ( i = 0; i < pf->argc; i++ ) {
382: NEXTNODE(n0,n); BDY(n) = (pointer)ad[i].arg;
383: }
384: NEXT(n) = 0;
385: MKLIST(*rp,n0);
386: }
387: }
388:
389: void Pvtype(arg,rp)
390: NODE arg;
391: Q *rp;
392: {
393: P p;
394:
395: p = (P)ARG0(arg);
396: if ( !p || ID(p) != O_P )
397: *rp = 0;
398: else
399: STOQ((int)VR(p)->attr,*rp);
400: }
401:
1.9 ! noro 402: extern NODE user_int_handler,user_quit_handler;
1.1 noro 403:
404: void Pregister_handler(arg,rp)
405: NODE arg;
406: Q *rp;
407: {
408: P p;
409: V v;
1.9 ! noro 410: NODE n;
1.1 noro 411: FUNC func;
412:
413: p = (P)ARG0(arg);
1.9 ! noro 414: if ( !p ) {
! 415: user_int_handler = 0;
! 416: *rp = 0;
! 417: return;
! 418: } else if ( OID(p) != 2 )
1.1 noro 419: error("register_hanlder : invalid argument");
420: v = VR(p);
421: if ( (int)v->attr != V_SR )
422: error("register_hanlder : no such function");
423: else {
424: func = (FUNC)v->priv;
425: if ( func->argc )
426: error("register_hanlder : the function must be with no argument");
427: else {
1.9 ! noro 428: MKNODE(n,(pointer)func,user_int_handler);
! 429: user_int_handler = n;
1.1 noro 430: *rp = ONE;
1.9 ! noro 431: }
! 432: }
! 433: }
! 434:
! 435: void Padd_handler(arg,rp)
! 436: NODE arg;
! 437: Q *rp;
! 438: {
! 439: P p;
! 440: V v;
! 441: NODE n;
! 442: FUNC func;
! 443: char *name;
! 444: NODE *hlistp;
! 445:
! 446: asir_assert(ARG0(arg),O_STR,"add_handler");
! 447: name = BDY((STRING)ARG0(arg));
! 448: p = (P)ARG1(arg);
! 449: if ( !strcmp(name,"intr") )
! 450: hlistp = &user_int_handler;
! 451: else if ( !strcmp(name,"quit") )
! 452: hlistp = &user_quit_handler;
! 453: else
! 454: error("add_handler : invalid keyword (must be \"intr\" or \"quit\")");
! 455: if ( !p ) {
! 456: *hlistp = 0; *rp = 0;
! 457: return;
! 458: }
! 459: if ( OID(p) == 2 ) {
! 460: v = VR(p);
! 461: if ( (int)v->attr != V_SR )
! 462: error("add_hanlder : no such function");
! 463: func = (FUNC)v->priv;
! 464: } else if ( OID(p) == O_STR ) {
! 465: gen_searchf_searchonly(BDY((STRING)p),&func);
! 466: if ( !func )
! 467: error("add_hanlder : no such function");
1.1 noro 468: }
1.9 ! noro 469: if ( func->argc )
! 470: error("register_hanlder : the function must be with no argument");
! 471: else {
! 472: MKNODE(n,(pointer)func,*hlistp);
! 473: *hlistp = n;
! 474: *rp = ONE;
! 475: }
! 476: }
! 477:
! 478: void Plist_handler(arg,rp)
! 479: NODE arg;
! 480: LIST *rp;
! 481: {
! 482: NODE r0,r,t;
! 483: char *name;
! 484: NODE hlist;
! 485: STRING fname;
! 486:
! 487: asir_assert(ARG0(arg),O_STR,"list_handler");
! 488: name = BDY((STRING)ARG0(arg));
! 489: if ( !strcmp(name,"intr") )
! 490: hlist = user_int_handler;
! 491: else if ( !strcmp(name,"quit") )
! 492: hlist = user_quit_handler;
! 493: else
! 494: error("list_handler : invalid keyword (must be \"intr\" or \"quit\")");
! 495: for ( r0 = 0, t = hlist; t; t = NEXT(t) ) {
! 496: NEXTNODE(r0,r);
! 497: MKSTR(fname,((FUNC)BDY(t))->fullname);
! 498: BDY(r) = (pointer)fname;
! 499: }
! 500: if ( r0 ) NEXT(r) = 0;
! 501: MKLIST(*rp,r0);
! 502: }
! 503:
! 504: void Pclear_handler(arg,rp)
! 505: NODE arg;
! 506: Q *rp;
! 507: {
! 508: NODE r0,r,t;
! 509: char *name;
! 510: NODE hlist;
! 511: STRING fname;
! 512:
! 513: asir_assert(ARG0(arg),O_STR,"clear_handler");
! 514: name = BDY((STRING)ARG0(arg));
! 515: if ( !strcmp(name,"intr") )
! 516: user_int_handler = 0;
! 517: else if ( !strcmp(name,"quit") )
! 518: user_quit_handler = 0;
! 519: else
! 520: error("clear_handler : invalid keyword (must be \"intr\" or \"quit\")");
! 521: *rp = 0;
1.1 noro 522: }
523:
1.7 noro 524: void Pcall(NODE arg,Obj *rp)
1.1 noro 525: {
526: P p;
527: V v;
528:
529: p = (P)ARG0(arg);
530: if ( !p || OID(p) != 2 )
531: error("call : invalid argument");
532: v = VR(p);
533: if ( (int)v->attr != V_SR )
534: error("call : no such function");
535:
536: else
537: *rp = (Obj)bevalf((FUNC)v->priv,BDY((LIST)ARG1(arg)));
1.7 noro 538: }
539:
540: /* at=position of arg to be used for iteration */
541:
542: void Pmapat(NODE arg,Obj *rp)
543: {
544: LIST args;
545: NODE node,rest,t0,t,n,r,r0;
546: P fpoly;
547: V fvar;
548: FUNC f;
549: VECT v,rv;
550: MAT m,rm;
551: LIST rl;
552: int len,row,col,i,j,pos;
553: Obj iter;
554: pointer val;
555:
556: if ( argc(arg) < 3 )
557: error("mapat : too few arguments");
558:
559: fpoly = (P)ARG0(arg);
560: if ( !fpoly || OID(fpoly) != O_P )
561: error("mapat : invalid function specification");
562: fvar = VR(fpoly);
563: if ( fvar->attr != (pointer)V_SR || !(f=(FUNC)fvar->priv) )
564: error("mapat : invalid function specification");
565: if ( !INT(ARG1(arg)) )
566: error("mapat : invalid position");
567: pos = QTOS((Q)ARG1(arg));
568: node = NEXT(NEXT(arg));
569: len = length(node);
570: if ( pos >= len )
571: error("evalmapatf : invalid position");
572: r0 = 0;
573: for ( i = 0, t = node; i < pos; i++, t = NEXT(t) ) {
574: NEXTNODE(r0,r);
575: BDY(r) = BDY(t);
576: }
577: NEXTNODE(r0,r);
578: iter = BDY(t); rest = NEXT(t);
579: if ( !iter ) {
580: *rp = bevalf(f,node);
581: return;
582: }
583: switch ( OID(iter) ) {
584: case O_VECT:
585: v = (VECT)iter; len = v->len; MKVECT(rv,len);
586: for ( i = 0; i < len; i++ ) {
587: BDY(r) = BDY(v)[i]; NEXT(r) = rest;
588: BDY(rv)[i] = bevalf(f,r0);
589: }
590: *rp = (Obj)rv;
591: break;
592: case O_MAT:
593: m = (MAT)iter; row = m->row; col = m->col; MKMAT(rm,row,col);
594: for ( i = 0; i < row; i++ )
595: for ( j = 0; j < col; j++ ) {
596: BDY(r) = BDY(m)[i][j]; NEXT(r) = rest;
597: BDY(rm)[i][j] = bevalf(f,r0);
598: }
599: *rp = (Obj)rm;
600: break;
601: case O_LIST:
602: n = BDY((LIST)iter);
603: for ( t0 = t = 0; n; n = NEXT(n) ) {
604: BDY(r) = BDY(n); NEXT(r) = rest;
605: NEXTNODE(t0,t); BDY(t) = bevalf(f,r0);
606: }
607: if ( t0 )
608: NEXT(t) = 0;
609: MKLIST(rl,t0);
610: *rp = (Obj)rl;
611: break;
612: default:
613: *rp = bevalf(f,node);
614: break;
615: }
1.1 noro 616: }
617:
618: void Pdeval(arg,rp)
619: NODE arg;
620: Obj *rp;
621: {
622: asir_assert(ARG0(arg),O_R,"deval");
623: devalr(CO,(Obj)ARG0(arg),rp);
624: }
625:
1.4 noro 626: void Peval_quote(arg,rp)
627: NODE arg;
628: Obj *rp;
629: {
630: asir_assert(ARG0(arg),O_QUOTE,"eval_quote");
631: *rp = eval((FNODE)BDY((QUOTE)ARG0(arg)));
632: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>