=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/parse/eval.c,v retrieving revision 1.3 retrieving revision 1.18 diff -u -p -r1.3 -r1.18 --- OpenXM_contrib2/asir2000/parse/eval.c 2000/07/13 05:09:03 1.3 +++ OpenXM_contrib2/asir2000/parse/eval.c 2001/12/25 02:39:06 1.18 @@ -1,28 +1,70 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/parse/eval.c,v 1.2 2000/02/08 04:47:12 noro Exp $ */ +/* + * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED + * All rights reserved. + * + * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited, + * non-exclusive and royalty-free license to use, copy, modify and + * redistribute, solely for non-commercial and non-profit purposes, the + * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and + * conditions of this Agreement. For the avoidance of doubt, you acquire + * only a limited right to use the SOFTWARE hereunder, and FLL or any + * third party developer retains all rights, including but not limited to + * copyrights, in and to the SOFTWARE. + * + * (1) FLL does not grant you a license in any way for commercial + * purposes. You may use the SOFTWARE only for non-commercial and + * non-profit purposes only, such as academic, research and internal + * business use. + * (2) The SOFTWARE is protected by the Copyright Law of Japan and + * international copyright treaties. If you make copies of the SOFTWARE, + * with or without modification, as permitted hereunder, you shall affix + * to all such copies of the SOFTWARE the above copyright notice. + * (3) An explicit reference to this SOFTWARE and its copyright owner + * shall be made on your publication or presentation in any form of the + * results obtained by use of the SOFTWARE. + * (4) In the event that you modify the SOFTWARE, you shall notify FLL by + * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification + * for such modification or the source code of the modified part of the + * SOFTWARE. + * + * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL + * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND + * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES' + * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY + * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY. + * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT, + * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL + * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES + * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES + * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY + * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF + * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART + * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY + * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, + * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. + * + * $OpenXM: OpenXM_contrib2/asir2000/parse/eval.c,v 1.17 2001/12/21 08:23:15 noro Exp $ +*/ #include #include "ca.h" #include "al.h" #include "base.h" #include "parse.h" -#if !defined(THINK_C) #include #include -#endif #if PARI #include "genpari.h" #endif -extern jmp_buf timer_env; +extern JMP_BUF timer_env; int f_break,f_return,f_continue; int evalstatline; int recv_intr; -pointer bevalf(), evalmapf(), evall(); -Obj getopt_from_cpvs(); - -pointer eval(f) -FNODE f; +pointer eval(FNODE f) { LIST t; STRING str; @@ -35,8 +77,11 @@ FNODE f; FNODE f1; UP2 up2; UP up; + UM um; + Obj obj; GF2N gf2n; GFPN gfpn; + GFSN gfsn; #if defined(VISUAL) if ( recv_intr ) { @@ -53,10 +98,18 @@ FNODE f; if ( !f ) return ( 0 ); switch ( f->id ) { + case I_PAREN: + val = eval((FNODE)(FA0(f))); + break; + case I_MINUS: + a1 = eval((FNODE)(FA0(f))); + arf_chsgn((Obj)a1,&obj); + val = (pointer)obj; + break; case I_BOP: a1 = eval((FNODE)FA1(f)); a2 = eval((FNODE)FA2(f)); (*((ARF)FA0(f))->fp)(CO,a1,a2,&val); - break; + break; case I_COP: a1 = eval((FNODE)FA1(f)); a2 = eval((FNODE)FA2(f)); c = arf_comp(CO,a1,a2); @@ -115,6 +168,8 @@ FNODE f; break; case I_MAP: val = evalmapf((FUNC)FA0(f),(FNODE)FA1(f)); break; + case I_RECMAP: + val = eval_rec_mapf((FUNC)FA0(f),(FNODE)FA1(f)); break; case I_IFUNC: val = evalif((FNODE)FA0(f),(FNODE)FA1(f)); break; #if !defined(VISUAL) @@ -127,7 +182,7 @@ FNODE f; expired = (Obj)eval((FNODE)FA2(f)); set_timer(interval); savepvs(); - if ( !setjmp(timer_env) ) + if ( !SETJMP(timer_env) ) val = eval((FNODE)FA1(f)); else { val = (pointer)expired; @@ -137,15 +192,6 @@ FNODE f; } break; #endif -#if 0 - case I_PRESELF: case I_POSTSELF: - val = evalpv(f->id,FA1(f),FA0(f)); break; - case I_PVAR: - val = evalpv(f->id,FA0(f),0); break; - case I_ASSPVAR: - val = evalpv(f->id,FA0(f),FA1(f)); break; -#endif -#if 1 case I_PRESELF: f1 = (FNODE)FA1(f); if ( ID(f1) == I_PVAR ) { @@ -157,7 +203,7 @@ FNODE f; (*((ARF)FA0(f))->fp)(CO,u,ONE,&val); putarray(a,tn,val); } } else - val = evalpv(f->id,(FNODE)FA1(f),FA0(f)); + error("++ : not implemented yet"); break; case I_POSTSELF: f1 = (FNODE)FA1(f); @@ -171,10 +217,8 @@ FNODE f; val = a; } } else - val = evalpv(f->id,(FNODE)FA1(f),FA0(f)); + error("-- : not implemented yet"); break; - case I_CAST: - getmember((FNODE)f,(Obj *)&val); break; case I_PVAR: pv = (int)FA0(f); ind = (NODE)FA1(f); GETPV(pv,a); if ( !ind ) @@ -194,10 +238,19 @@ FNODE f; evalnodebody(ind,&tn); putarray(a,tn,val = eval((FNODE)FA1(f))); } - } else - val = evalpv(ID(f),(FNODE)FA0(f),FA1(f)); + } else if ( ID(f1) == I_POINT ) { + /* f1 <-> FA0(f1)->FA1(f1) */ + a = eval(FA0(f1)); + assign_to_member(a,(char *)FA1(f1),val = eval((FNODE)FA1(f))); + } else if ( ID(f1) == I_INDEX ) { + /* f1 <-> FA0(f1)[FA1(f1)] */ + a = eval((FNODE)FA0(f1)); ind = (NODE)FA1(f1); + evalnodebody(ind,&tn); + putarray(a,tn,val = eval((FNODE)FA1(f))); + } else { + error("eval : invalid assignment"); + } break; -#endif case I_ANS: if ( (pv =(int)FA0(f)) < (int)APVS->n ) val = APVS->va[pv].priv; @@ -211,12 +264,20 @@ FNODE f; break; case I_GFPNGEN: up = UPALLOC(1); - up->d=1; - up->c[0] = 0; - up->c[1] = (Num)ONELM; + DEG(up)=1; + COEF(up)[0] = 0; + COEF(up)[1] = (Num)ONELM; MKGFPN(up,gfpn); val = (pointer)gfpn; break; + case I_GFSNGEN: + um = UMALLOC(1); + DEG(um) = 1; + COEF(um)[0] = 0; + COEF(um)[1] = _onesf(); + MKGFSN(um,gfsn); + val = (pointer)gfsn; + break; case I_STR: MKSTR(str,FA0(f)); val = (pointer)str; break; case I_FORMULA: @@ -257,6 +318,10 @@ FNODE f; case I_GETOPT: val = (pointer)getopt_from_cpvs((char *)FA0(f)); break; + case I_POINT: + a = (pointer)eval(FA0(f)); + val = (pointer)memberofstruct(a,(char *)FA1(f)); + break; default: error("eval : unknown id"); break; @@ -264,8 +329,7 @@ FNODE f; return ( val ); } -pointer evalstat(f) -SNODE f; +pointer evalstat(SNODE f) { pointer val = 0,t,s,s1; P u; @@ -370,8 +434,7 @@ SNODE f; return ( val ); } -pointer evalnode(node) -NODE node; +pointer evalnode(NODE node) { NODE tn; pointer val; @@ -385,17 +448,16 @@ NODE node; extern FUNC cur_binf; extern NODE PVSS; -pointer evalf(f,a,opt) -FUNC f; -FNODE a; -FNODE opt; +pointer evalf(FUNC f,FNODE a,FNODE opt) { LIST args; pointer val; int i,n,level; - NODE tn,sn,opts; + NODE tn,sn,opts,opt1; VS pvs; char errbuf[BUFSIZ]; + static int stack_size; + static void *stack_base; if ( f->id == A_UNDEF ) { sprintf(errbuf,"evalf : %s undefined",NAME(f)); @@ -427,10 +489,32 @@ FNODE opt; cur_binf = 0; break; case A_USR: + /* stack check */ +#if !defined(VISUAL) && !defined(__CYGWIN__) + if ( !stack_size ) { + struct rlimit rl; + getrlimit(RLIMIT_STACK,&rl); + stack_size = rl.rlim_cur; + } + if ( !stack_base ) + stack_base = (void *)GC_get_stack_base(); + if ( (stack_base - (void *)&args) +0x100000 > stack_size ) + error("stack overflow"); +#endif args = (LIST)eval(a); - if ( opt ) + if ( opt ) { opts = BDY((LIST)eval(opt)); - else + /* opts = ["opt1",arg1],... */ + opt1 = BDY((LIST)BDY(opts)); + if ( !strcmp(BDY((STRING)BDY(opt1)),"option_list") ) { + /* + * the special option specification: + * option_list=[["o1","a1"],...] + */ + asir_assert(BDY(NEXT(opt1)),O_LIST,"evalf"); + opts = BDY((LIST)BDY(NEXT(opt1))); + } + } else opts = 0; pvs = f->f.usrf->pvs; if ( PVSS ) { @@ -468,9 +552,7 @@ FNODE opt; return val; } -pointer evalmapf(f,a) -FUNC f; -FNODE a; +pointer evalmapf(FUNC f,FNODE a) { LIST args; NODE node,rest,t,n,r,r0; @@ -520,16 +602,70 @@ FNODE a; return val; } -pointer bevalf(f,a) -FUNC f; -NODE a; +pointer eval_rec_mapf(FUNC f,FNODE a) { + LIST args; + + args = (LIST)eval(a); + return beval_rec_mapf(f,BDY(args)); +} + +pointer beval_rec_mapf(FUNC f,NODE node) +{ + NODE rest,t,n,r,r0; + Obj head; + VECT v,rv; + MAT m,rm; + LIST rl; + int len,row,col,i,j; pointer val; + + head = (Obj)BDY(node); rest = NEXT(node); + if ( !head ) { + val = bevalf(f,node); + return val; + } + switch ( OID(head) ) { + case O_VECT: + v = (VECT)head; len = v->len; MKVECT(rv,len); + for ( i = 0; i < len; i++ ) { + MKNODE(t,BDY(v)[i],rest); BDY(rv)[i] = beval_rec_mapf(f,t); + } + val = (pointer)rv; + break; + case O_MAT: + m = (MAT)head; row = m->row; col = m->col; MKMAT(rm,row,col); + for ( i = 0; i < row; i++ ) + for ( j = 0; j < col; j++ ) { + MKNODE(t,BDY(m)[i][j],rest); + BDY(rm)[i][j] = beval_rec_mapf(f,t); + } + val = (pointer)rm; + break; + case O_LIST: + n = BDY((LIST)head); + for ( r0 = r = 0; n; n = NEXT(n) ) { + NEXTNODE(r0,r); MKNODE(t,BDY(n),rest); + BDY(r) = beval_rec_mapf(f,t); + } + if ( r0 ) + NEXT(r) = 0; + MKLIST(rl,r0); + val = (pointer)rl; + break; + default: + val = bevalf(f,node); + break; + } + return val; +} + +pointer bevalf(FUNC f,NODE a) +{ + pointer val; int i,n; NODE tn,sn; VS pvs; - struct oLIST list; - struct oFNODE fnode; char errbuf[BUFSIZ]; if ( f->id == A_UNDEF ) { @@ -591,8 +727,7 @@ NODE a; return val; } -pointer evalif(f,a) -FNODE f,a; +pointer evalif(FNODE f,FNODE a) { Obj g; @@ -601,19 +736,18 @@ FNODE f,a; return evalf((FUNC)VR((P)g)->priv,a,0); else { error("invalid function pointer"); + /* NOTREACHED */ + return (pointer)-1; } } -pointer evalpf(pf,args) -PF pf; -NODE args; +pointer evalpf(PF pf,NODE args) { Obj s,s1; int i; NODE node; PFINS ins; PFAD ad; - char errbuf[BUFSIZ]; if ( !pf->body ) { ins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD)); @@ -632,9 +766,7 @@ NODE args; return (pointer)s; } -void evalnodebody(sn,dnp) -NODE sn; -NODE *dnp; +void evalnodebody(NODE sn,NODE *dnp) { NODE n,n0,tn; int line; @@ -652,11 +784,24 @@ NODE *dnp; NEXT(n) = 0; *dnp = n0; } -void searchf(fn,name,r) -NODE fn; -char *name; -FUNC *r; +void gen_searchf(char *name,FUNC *r) { + FUNC val; + + searchf(sysf,name,&val); + if ( !val ) + searchf(ubinf,name,&val); + if ( !val ) + searchpf(name,&val); + if ( !val ) + searchf(usrf,name,&val); + if ( !val ) + appenduf(name,&val); + *r = val; +} + +void searchf(NODE fn,char *name,FUNC *r) +{ NODE tn; for ( tn = fn; @@ -668,9 +813,7 @@ FUNC *r; *r = 0; } -void appenduf(name,r) -char *name; -FUNC *r; +void appenduf(char *name,FUNC *r) { NODE tn; FUNC f; @@ -681,9 +824,7 @@ FUNC *r; *r = f; } -void mkparif(name,r) -char *name; -FUNC *r; +void mkparif(char *name,FUNC *r) { FUNC f; @@ -691,12 +832,7 @@ FUNC *r; f->name = name; f->id = A_PARI; f->argc = 0; f->f.binf = 0; } -void mkuf(name,fname,args,body,startl,endl,desc) -char *name,*fname; -NODE args; -SNODE body; -int startl,endl; -char *desc; +void mkuf(char *name,char *fname,NODE args,SNODE body,int startl,int endl,char *desc) { FUNC f; USRF t; @@ -743,19 +879,24 @@ char *desc; CVS->opt = BDY([[key,value],[key,value],...]) */ -Obj getopt_from_cpvs(key) -char *key; +Obj getopt_from_cpvs(char *key) { NODE opts,opt; - Obj value; + LIST r; extern Obj VOIDobj; opts = CPVS->opt; - for ( ; opts; opts = NEXT(opts) ) { - opt = BDY((LIST)BDY(opts)); - if ( !strcmp(key,BDY((STRING)BDY(opt))) ) - return (Obj)BDY(NEXT(opt)); + if ( !key ) { + MKLIST(r,opts); + return (Obj)r; + } else { + for ( ; opts; opts = NEXT(opts) ) { + asir_assert(BDY(opts),O_LIST,"getopt_from_cvps"); + opt = BDY((LIST)BDY(opts)); + if ( !strcmp(key,BDY((STRING)BDY(opt))) ) + return (Obj)BDY(NEXT(opt)); + } + return VOIDobj; } - return VOIDobj; }