Annotation of OpenXM_contrib2/asir2000/parse/quote.c, Revision 1.21
1.21 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/parse/quote.c,v 1.20 2004/08/09 06:42:53 noro Exp $ */
1.3 noro 2:
1.1 noro 3: #include "ca.h"
4: #include "parse.h"
5:
1.6 noro 6: void addquote(VL vl,QUOTE a,QUOTE b,QUOTE *c)
1.1 noro 7: {
8: FNODE fn;
9:
10: fn = mkfnode(3,I_BOP,addfs,BDY(a),BDY(b));
11: MKQUOTE(*c,fn);
12: }
13:
1.6 noro 14: void subquote(VL vl,QUOTE a,QUOTE b,QUOTE *c)
1.1 noro 15: {
16: FNODE fn;
17:
18: fn = mkfnode(3,I_BOP,subfs,BDY(a),BDY(b));
19: MKQUOTE(*c,fn);
20: }
21:
1.6 noro 22: void mulquote(VL vl,QUOTE a,QUOTE b,QUOTE *c)
1.1 noro 23: {
24: FNODE fn;
25:
26: fn = mkfnode(3,I_BOP,mulfs,BDY(a),BDY(b));
27: MKQUOTE(*c,fn);
28: }
29:
1.6 noro 30: void divquote(VL vl,QUOTE a,QUOTE b,QUOTE *c)
1.1 noro 31: {
32: FNODE fn;
33:
34: fn = mkfnode(3,I_BOP,divfs,BDY(a),BDY(b));
35: MKQUOTE(*c,fn);
36: }
37:
1.6 noro 38: void pwrquote(VL vl,QUOTE a,QUOTE b,QUOTE *c)
1.1 noro 39: {
40: FNODE fn;
41:
42: if ( !b || OID(b) != O_QUOTE )
43: error("pwrquote : invalid argument");
44: fn = mkfnode(3,I_BOP,pwrfs,BDY(a),BDY(b));
45: MKQUOTE(*c,fn);
46: }
47:
1.6 noro 48: void chsgnquote(QUOTE a,QUOTE *c)
1.1 noro 49: {
50: FNODE fn;
51:
1.17 noro 52: fn = mkfnode(1,I_MINUS,BDY(a));
1.1 noro 53: MKQUOTE(*c,fn);
54: }
1.2 noro 55:
1.6 noro 56: void objtoquote(Obj a,QUOTE *c)
1.2 noro 57: {
58: QUOTE nm,dn;
1.4 noro 59: NODE arg,t0,t,t1,t2,t3;
60: FNODE fn;
1.5 noro 61: Obj obj;
1.4 noro 62: Obj *b;
63: Obj **m;
64: int i,j,len,row,col;
65: Q q,qrow,qcol;
66: FUNC f;
1.2 noro 67:
68: if ( !a ) {
69: MKQUOTE(*c,mkfnode(1,I_FORMULA,(pointer)a));
70: return;
71: }
72: switch ( OID(a) ) {
73: case O_N:
1.5 noro 74: if ( negative_number((Num)a) ) {
75: arf_chsgn(a,&obj);
76: MKQUOTE(*c,mkfnode(1,I_MINUS,
77: mkfnode(1,I_FORMULA,(pointer)obj)));
78: } else {
79: MKQUOTE(*c,mkfnode(1,I_FORMULA,(pointer)a));
80: }
81: break;
1.4 noro 82: case O_STR:
1.2 noro 83: MKQUOTE(*c,mkfnode(1,I_FORMULA,(pointer)a));
84: break;
85: case O_P:
86: polytoquote((P)a,c);
87: break;
88: case O_R:
89: polytoquote(NM((R)a),&nm);
90: polytoquote(DN((R)a),&dn);
91: divquote(CO,nm,dn,c);
92: break;
1.4 noro 93: case O_LIST:
94: t0 = 0;
95: for ( arg = BDY((LIST)a); arg; arg = NEXT(arg) ) {
96: NEXTNODE(t0,t);
97: objtoquote(BDY(arg),&nm);
98: BDY(t) = BDY(nm);
99: }
100: if ( t0 )
101: NEXT(t) = 0;
102: MKQUOTE(*c,mkfnode(1,I_LIST,t0));
103: break;
104: case O_VECT:
105: len = ((VECT)a)->len;
106: b = (Obj *)BDY(((VECT)a));
107: t = 0;
108: for ( i = len-1; i >= 0; i-- ) {
109: objtoquote(b[i],&nm);
110: MKNODE(t1,BDY(nm),t);
111: t = t1;
112: }
113: STOQ(len,q);
114: t = mknode(2,mkfnode(1,I_FORMULA,q),mkfnode(1,I_LIST,t));
115: gen_searchf("vector",&f);
116: MKQUOTE(*c,mkfnode(2,I_FUNC,f,mkfnode(1,I_LIST,t)));
117: break;
118: case O_MAT:
119: row = ((MAT)a)->row;
120: col = ((MAT)a)->row;
121: m = (Obj **)BDY(((MAT)a));
122: t2 = 0;
123: for ( i = row-1; i >= 0; i-- ) {
124: t = 0;
125: for ( j = col-1; j >= 0; j-- ) {
126: objtoquote(m[i][j],&nm);
127: MKNODE(t1,BDY(nm),t);
128: t = t1;
129: }
130: fn = mkfnode(1,I_LIST,t);
131: MKNODE(t3,fn,t2);
132: t2 = t3;
133: }
134: fn = mkfnode(1,I_LIST,t2);
135:
136: STOQ(row,qrow);
137: STOQ(col,qcol);
138: t = mknode(3,
139: mkfnode(1,I_FORMULA,qrow),mkfnode(1,I_FORMULA,qcol),fn);
140: gen_searchf("matrix",&f);
141: MKQUOTE(*c,mkfnode(2,I_FUNC,f,mkfnode(1,I_LIST,t)));
142: break;
143: case O_DP:
144: dptoquote((DP)a,c);
145: break;
1.2 noro 146: case O_QUOTE:
147: *c = (QUOTE)a;
148: break;
149: default:
150: error("objtoquote : not implemented");
151: }
152: }
153:
1.6 noro 154: void polytoquote(P a,QUOTE *c)
1.2 noro 155: {
156: DCP dc,t;
157: DCP *dca;
1.7 noro 158: int n,i,sgn;
1.2 noro 159: QUOTE v,r,s,u;
160:
1.10 noro 161: if ( !a ) {
162: MKQUOTE(*c,mkfnode(1,I_FORMULA,(pointer)a));
163: return;
164: } else if ( OID(a) == O_N ) {
1.2 noro 165: MKQUOTE(*c,mkfnode(1,I_FORMULA,(pointer)a));
166: return;
167: }
1.7 noro 168: vartoquote(VR((P)a),&v);
1.2 noro 169: dc = DC((P)a);
1.7 noro 170: dctoquote(dc,v,&r,&sgn);
171: if ( sgn == -1 ) {
172: MKQUOTE(u,mkfnode(1,I_MINUS,BDY(r)));
173: r = u;
174: }
175: for (dc = NEXT(dc); dc; dc = NEXT(dc) ) {
176: dctoquote(dc,v,&s,&sgn);
177: if ( sgn == -1 )
178: subquote(CO,r,s,&u);
179: else
180: addquote(CO,r,s,&u);
1.2 noro 181: r = u;
182: }
183: *c = r;
184: }
185:
1.6 noro 186: void dptoquote(DP a,QUOTE *c)
1.4 noro 187: {
188: MP t;
1.8 noro 189: MP m;
190: int i,n,nv,sgn;
1.4 noro 191: QUOTE s,r,u;
192:
193: if ( !a ) {
194: MKQUOTE(*c,mkfnode(1,I_FORMULA,(pointer)a));
195: return;
196: }
197: nv = NV(a);
1.8 noro 198: m = BDY(a);
199: mptoquote(m,nv,&r,&sgn);
200: if ( sgn == -1 ) {
201: MKQUOTE(u,mkfnode(1,I_MINUS,BDY(r)));
202: r = u;
203: }
204: for ( m = NEXT(m); m; m = NEXT(m) ) {
205: mptoquote(m,nv,&s,&sgn);
206: if ( sgn < 0 )
207: subquote(CO,r,s,&u);
208: else
209: addquote(CO,r,s,&u);
1.4 noro 210: r = u;
211: }
212: *c = r;
213: }
214:
1.7 noro 215: void dctoquote(DCP dc,QUOTE v,QUOTE *q,int *sgn)
1.2 noro 216: {
1.7 noro 217: QUOTE t,s,u,r;
218: P c;
219: Q d;
220:
221: if ( mmono(COEF(dc)) ) {
222: /* -xyz... */
223: chsgnp(COEF(dc),&c);
224: *sgn = -1;
225: } else {
226: c = COEF(dc);
227: *sgn = 1;
228: }
229: d = DEG(dc);
230: if ( UNIQ(c) ) {
231: if ( d ) {
232: if ( UNIQ(d) )
233: r = v;
1.4 noro 234: else {
1.7 noro 235: objtoquote((Obj)d,&t);
236: pwrquote(CO,v,t,&r);
1.4 noro 237: }
238: } else
1.7 noro 239: objtoquote((Obj)ONE,&r);
1.4 noro 240: } else {
1.7 noro 241: objtoquote((Obj)c,&u);
1.12 noro 242: if ( !NUM(c) && NEXT(DC(c)) && d ) {
1.7 noro 243: MKQUOTE(t,mkfnode(1,I_PAREN,BDY(u)));
244: u = t;
245: }
246: if ( d ) {
247: if ( UNIQ(d) )
1.4 noro 248: s = v;
249: else {
1.7 noro 250: objtoquote((Obj)d,&t);
251: pwrquote(CO,v,t,&s);
1.4 noro 252: }
1.7 noro 253: mulquote(CO,u,s,&r);
1.4 noro 254: } else
1.7 noro 255: r = u;
1.4 noro 256: }
1.7 noro 257: *q = r;
1.4 noro 258: }
259:
1.8 noro 260: void mptoquote(MP m,int n,QUOTE *r,int *sgn)
1.4 noro 261: {
262: QUOTE s,u;
1.8 noro 263: P c;
1.4 noro 264: NODE t,t1;
265: FNODE f;
266: Q q;
267: DL dl;
268: int i;
269:
1.8 noro 270: if ( mmono(C(m)) ) {
271: chsgnp(C(m),&c);
272: *sgn = -1;
273: } else {
274: c = C(m);
275: *sgn = 1;
276: }
277: objtoquote((Obj)c,&s);
278: if ( !NUM(c) && NEXT(DC(c)) ) {
279: MKQUOTE(u,mkfnode(1,I_PAREN,BDY(s)));
280: s = u;
281: }
1.4 noro 282: dl = m->dl;
1.9 noro 283: for ( i = n-1, t = 0; i >= 0; i-- ) {
284: STOQ(dl->d[i],q);
285: f = mkfnode(1,I_FORMULA,q);
286: MKNODE(t1,f,t);
287: t = t1;
288: }
289: MKQUOTE(u,mkfnode(1,I_EV,t));
290: if ( UNIQ(c) )
291: *r = u;
292: else
293: mulquote(CO,s,u,r);
1.2 noro 294: }
295:
1.6 noro 296: void vartoquote(V v,QUOTE *c)
1.2 noro 297: {
298: P x;
299: PF pf;
300: PFAD ad;
1.13 noro 301: QUOTE a,b,u;
1.2 noro 302: int i;
303: FUNC f;
304: NODE t,t1;
305:
306: if ( NAME(v) ) {
307: MKV(v,x);
308: MKQUOTE(*c,mkfnode(1,I_FORMULA,(pointer)x));
309: } else if ( (vid)v->attr == V_PF ) {
310: /* pure function */
311: pf = ((PFINS)v->priv)->pf;
312: ad = ((PFINS)v->priv)->ad;
313: if ( !strcmp(NAME(pf),"pow") ) {
314: /* pow(a,b) = a^b */
1.13 noro 315: objtoquote(ad[0].arg,&a);
316: x = (P)ad[0].arg;
317: /* check whether x is a variable */
318: if ( x && OID(x)==O_P && !NEXT(DC(x))
319: && UNIQ(DEG(DC(x))) && UNIQ(COEF(DC(x))) ) {
320: /* use a as is */
321: } else {
322: /* a => (a) */
1.19 noro 323: MKQUOTE(u,mkfnode(1,I_PAREN,BDY(a))); a = u;
1.13 noro 324: }
325: objtoquote(ad[1].arg,&b);
1.19 noro 326: pwrquote(CO,a,b,c);
1.2 noro 327: } else {
328: for ( i = 0; i < pf->argc; i++ )
329: if ( ad[i].d )
330: break;
331: if ( i < pf->argc )
332: error("vartoquote : not implemented");
333: gen_searchf(NAME(pf),&f);
334: t = 0;
335: for ( i = pf->argc-1; i >= 0; i-- ) {
336: objtoquote(ad[i].arg,&a);
337: MKNODE(t1,BDY(a),t);
338: t = t1;
339: }
340: MKQUOTE(*c,mkfnode(2,I_FUNC,f,mkfnode(1,I_LIST,t)));
341: }
1.14 noro 342: }
343: }
344:
1.21 ! noro 345: /*
! 346: * A_arf : arithmetic function
! 347: * A_int : machine integer
! 348: * A_fnode : FNODE
! 349: * A_node : NODE with FNODE bodies
! 350: * A_internal : internal object
! 351: * A_str : string
! 352: * A_end : terminal
! 353: * A_func : FUNC
! 354: * A_notimpl : not implemented
! 355: */
! 356:
1.14 noro 357: struct fid_spec fid_spec_tab[] = {
1.17 noro 358: {I_BOP,A_arf,A_fnode,A_fnode,A_end},
359: {I_COP,A_int,A_fnode,A_fnode,A_end},
360: {I_AND,A_fnode,A_fnode,A_end},
361: {I_OR,A_fnode,A_fnode,A_end},
362: {I_NOT,A_fnode,A_end},
363: {I_CE,A_fnode,A_fnode,A_end},
364: {I_PRESELF,A_arf,A_fnode,A_end},
365: {I_POSTSELF,A_arf,A_fnode,A_end},
366: {I_FUNC,A_func,A_fnode,A_end},
367: {I_FUNC_OPT,A_func,A_fnode,A_fnode,A_end},
368: {I_IFUNC,A_fnode,A_fnode,A_end},
369: {I_MAP,A_func,A_fnode,A_end},
370: {I_RECMAP,A_func,A_fnode,A_end},
1.14 noro 371: {I_PFDERIV,A_notimpl,A_end},
372: {I_ANS,A_int,A_end},
373: {I_PVAR,A_int,A_node,A_end},
1.17 noro 374: {I_ASSPVAR,A_fnode,A_fnode,A_end},
1.14 noro 375: {I_FORMULA,A_internal,A_end},
376: {I_LIST,A_node,A_end},
377: {I_STR,A_str,A_end},
378: {I_NEWCOMP,A_int,A_end},
1.17 noro 379: {I_CAR,A_fnode,A_end},
380: {I_CDR,A_fnode,A_end},
1.14 noro 381: {I_CAST,A_notimpl,A_end},
1.17 noro 382: {I_INDEX,A_fnode,A_node,A_end},
1.14 noro 383: {I_EV,A_node,A_end},
1.17 noro 384: {I_TIMER,A_fnode,A_fnode,A_fnode,A_end},
1.14 noro 385: {I_GF2NGEN,A_end},
386: {I_GFPNGEN,A_end},
387: {I_GFSNGEN,A_end},
1.17 noro 388: {I_LOP,A_int,A_fnode,A_fnode,A_end},
389: {I_OPT,A_str,A_fnode,A_end},
1.14 noro 390: {I_GETOPT,A_str,A_end},
1.17 noro 391: {I_POINT,A_fnode,A_str,A_end},
392: {I_PAREN,A_fnode,A_end},
393: {I_MINUS,A_fnode,A_end},
1.14 noro 394: {I_NARYOP,A_notimpl,A_end}
395: };
396:
397: #define N_FID_SPEC (sizeof(fid_spec_tab)/sizeof(struct fid_spec))
398:
399: void get_fid_spec(fid id,fid_spec_p *spec)
400: {
401: int i;
402:
403: for ( i = 0; i < N_FID_SPEC; i++ )
404: if ( fid_spec_tab[i].id == id ) {
405: *spec = &fid_spec_tab[i];
406: return;
407: }
408: *spec = 0;
409: }
410:
1.15 noro 411: FNODE strip_paren(FNODE f)
412: {
413: if ( !f || f->id != I_PAREN ) return f;
414: else {
415: return strip_paren((FNODE)FA0(f));
416: }
417: }
418:
1.18 noro 419: NODE flatten_fnodenode(NODE n,char *opname);
420: FNODE flatten_fnode(FNODE f,char *opname);
421:
422: NODE flatten_fnodenode(NODE n,char *opname)
423: {
424: NODE r0,r,t;
425:
426: r0 = 0;
427: for ( t = n; t; t = NEXT(t) ) {
428: NEXTNODE(r0,r);
429: BDY(r) = (pointer)flatten_fnode((FNODE)BDY(t),opname);
430: }
431: if ( r0 ) NEXT(r) = 0;
432: return r0;
433: }
434:
1.14 noro 435: FNODE flatten_fnode(FNODE f,char *opname)
436: {
437: fid_spec_p spec;
438: farg_type *type;
439: fid id;
440: FNODE f1,f2,r;
441: int i;
442:
443: if ( !f ) return f;
444: id = f->id;
445: get_fid_spec(id,&spec);
446: /* unknown fid */
447: if ( !spec ) return f;
448: if ( id == I_BOP && !strcmp(((ARF)FA0(f))->name,opname) ) {
449: f1 = (pointer)flatten_fnode(FA1(f),opname);
1.15 noro 450: f1 = strip_paren(f1);
1.14 noro 451: f2 = (pointer)flatten_fnode(FA2(f),opname);
1.15 noro 452: f2 = strip_paren(f2);
1.14 noro 453: if ( f1->id == I_BOP && !strcmp(((ARF)FA0(f1))->name,opname) ) {
1.16 noro 454: /* [op [op A B] C] => [op A [op B C]] */
1.14 noro 455: return mkfnode(3,I_BOP,(ARF)FA0(f),FA1(f1),
456: mkfnode(3,I_BOP,(ARF)FA0(f),FA2(f1),f2));
457: } else
458: return mkfnode(3,I_BOP,(ARF)FA0(f),f1,f2);
459: } else {
460: type = spec->type;
461: for ( i = 0; type[i] != A_end; i++ );
462: NEWFNODE(r,i); ID(r) = f->id;
463: for ( i = 0; type[i] != A_end; i++ ) {
1.17 noro 464: if ( type[i] == A_fnode )
1.14 noro 465: r->arg[i] = (pointer)flatten_fnode(f->arg[i],opname);
1.18 noro 466: else if ( type[i] == A_node )
467: r->arg[i] = (pointer)flatten_fnodenode(f->arg[i],opname);
1.14 noro 468: else
469: r->arg[i] = f->arg[i];
470: }
471: return r;
1.2 noro 472: }
1.21 ! noro 473: }
! 474:
! 475: /* comparison of QUOTE */
! 476:
! 477: int compquote(VL vl,QUOTE q1,QUOTE q2)
! 478: {
! 479: return compfnode(BDY(q1),BDY(q2));
! 480: }
! 481:
! 482: /* comparison of QUOTEARG */
! 483: /* XXX : executes a non-sense comparison for bodies */
! 484:
! 485: int compqa(VL vl,QUOTEARG q1,QUOTEARG q2)
! 486: {
! 487: if ( !q1 ) return q2?-1:0;
! 488: else if ( !q2 ) return 1;
! 489: else if ( OID(q1) > OID(q2) ) return 1;
! 490: else if ( OID(q1) < OID(q2) ) return -1;
! 491: else if ( q1->type > q2->type ) return 1;
! 492: else if ( q1->type < q2->type ) return -1;
! 493: else switch ( q1->type ) {
! 494: case A_func:
! 495: return strcmp(((FUNC)q1->body)->name,((FUNC)q2->body)->name);
! 496: case A_arf:
! 497: return strcmp(((ARF)q1->body)->name,((ARF)q2->body)->name);
! 498: default:
! 499: if ( (unsigned)q1->body > (unsigned)q2->body ) return 1;
! 500: else if ( (unsigned)q1->body < (unsigned)q2->body ) return -1;
! 501: else return 0;
! 502: }
! 503: }
! 504:
! 505: int compfnode(FNODE f1,FNODE f2)
! 506: {
! 507: fid_spec_p spec;
! 508: int t,s1,s2,i;
! 509: NODE n1,n2;
! 510:
! 511: if ( !f1 ) return f2 ? -1 : 1;
! 512: else if ( !f2 ) return 1;
! 513: else if ( f1->id > f2->id ) return 1;
! 514: else if ( f1->id < f2->id ) return -1;
! 515: spec = fid_spec_tab+f1->id;
! 516: for ( i = 0; spec->type[i] != A_end; i++ ) {
! 517: switch ( spec->type[i] ) {
! 518: case A_fnode:
! 519: return compfnode((FNODE)f1->arg[i],(FNODE)f2->arg[i]);
! 520: break;
! 521: case A_int:
! 522: s1 = (int)f1->arg[i];
! 523: s2 = (int)f2->arg[i];
! 524: if ( s1 > s2 ) return 1;
! 525: else if ( s1 < s2 ) return -1;
! 526: break;
! 527: case A_str:
! 528: t = strcmp((char *)f1->arg[i],(char *)f2->arg[i]);
! 529: if ( t ) return t;
! 530: break;
! 531: case A_internal:
! 532: t = arf_comp(CO,(Obj)f1->arg[i],(Obj)f2->arg[i]);
! 533: if ( t ) return t;
! 534: break;
! 535: case A_node:
! 536: n1 = (NODE)f1->arg[i];
! 537: n2 = (NODE)f2->arg[i];
! 538: for ( ; n1 && n2; n1 = NEXT(n1), n2 = NEXT(n2) ) {
! 539: t = compfnode(BDY(n1),BDY(n2));
! 540: if ( t ) return t;
! 541: }
! 542: if ( n1 ) return 1;
! 543: else if ( n2 ) return -1;
! 544: break;
! 545: case A_arf:
! 546: t = strcmp(((ARF)f1->arg[i])->name,((ARF)f2->arg[i])->name);
! 547: if ( t ) return t;
! 548: break;
! 549: case A_func:
! 550: t = strcmp(((FUNC)f1->arg[i])->name,((FUNC)f2->arg[i])->name);
! 551: if ( t ) return t;
! 552: break;
! 553: case A_notimpl:
! 554: default:
! 555: error("compfnode : not implemented");
! 556: break;
! 557: }
! 558: }
! 559: return 0;
1.2 noro 560: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>