Bill Allombert on Tue, 21 Aug 2007 17:16:17 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[patch] lexically-scoped variables v2 |
Dear PARI-dev, This patch is an implementation of lexically-scoped variables in GP. This patch cause the following changes: 1) The new keyword my() allow to declare lexically scoped variables. 2) Functions parameters are lexically scoped. (This is an incompatibility with GP 2.3) 3) my() and local() can now happen anywhere in the code and the scope of the variables is limited to the current closure. 4) Variables defined through the prototype code V are dynamically scoped. (This is an incompatibility with GP 2.3) The code V is handled this way: 1) functions do not get any argument for V (used to be an entree*), but the corresponding closure use the variable name as a lexical variable to be created by the caller, see below. 2) the following functions are available to handle lexical variables: void push_lex(GEN val) Create a new lexical variable with initial value val. void pop_lex(void) Destroy the last lexical variable created. GEN get_lex(long vn) if vn=-1, get the value of the last lexical variable created, if vn=-2, get the value of the last but one lexical variable created, etc. void set_lex(long vn, GEN x); if vn=-1, set the value of the last lexical variable created, if vn=-2, set the value of the last but one lexical variable created, etc. vn=-2 is used for the function matrix() which needs two lexical variables. Known limitations: 1) The memory model was preserved so we essentially get the same set of bugs as with GP 2.3. 2) This is slightly slower than it should be. 3) This breaks most usage of trap() for debugging: ? f(z)=1/z ? trap ? f(0) *** _/_: division by zero *** Break loop (type 'break' or Control-d to go back to GP) break> z z instead of 0,because the lexical variable z is not defined in this scope. Maybe we should ditch trap completly and start again and implement: 1) a true iferr() facility. 2) a true debugging facility. Cheers, Bill.
Index: config/Makefile.SH =================================================================== RCS file: /home/cvs/pari/config/Makefile.SH,v retrieving revision 1.181 diff -u -r1.181 Makefile.SH --- config/Makefile.SH 2 Aug 2007 21:56:06 -0000 1.181 +++ config/Makefile.SH 21 Aug 2007 15:04:50 -0000 @@ -608,7 +608,7 @@ cflags="$cflags \$(PLOTCFLAGS)" depend="$src/graph/rect.h" ;; - es|sumiter) + es|sumiter|intnum) depend="$src/language/anal.h" cflags="$cflags \$(DLCFLAGS)" ;; Index: src/basemath/subgroup.c =================================================================== RCS file: /home/cvs/pari/src/basemath/subgroup.c,v retrieving revision 1.68 diff -u -r1.68 subgroup.c --- src/basemath/subgroup.c 1 Aug 2007 01:11:08 -0000 1.68 +++ src/basemath/subgroup.c 21 Aug 2007 15:04:50 -0000 @@ -92,9 +92,9 @@ std_fun(subgp_iter *T, GEN x) { pari_sp ltop=avma; - exprdat *E = (exprdat *)T->fundata; - E->ep->value = (void*)x; - closure_evalvoid(E->code); T->countsub++; + GEN code = (GEN) T->fundata; + set_lex(-1,x); + closure_evalvoid(code); T->countsub++; avma=ltop; } /* ----subgp_iter 'fun' associated to subgrouplist ------------- */ @@ -548,10 +548,9 @@ } void -forsubgroup(entree *ep, GEN cyc, GEN bound, GEN code) +forsubgroup(GEN cyc, GEN bound, GEN code) { subgp_iter T; - exprdat E; long N; T.fun = &std_fun; @@ -559,13 +558,12 @@ if (!cyc) pari_err(typeer,"forsubgroup"); T.bound = bound; T.cyc = cyc; - E.code = code; - E.ep= ep; T.fundata = (void*)&E; - push_val(ep, gen_0); + T.fundata = (void*)code; + push_lex(gen_0); subgroup_engine(&T); - pop_val(ep); + pop_lex(); } static GEN Index: src/desc/doc_make =================================================================== RCS file: /home/cvs/pari/src/desc/doc_make,v retrieving revision 1.7 diff -u -r1.7 doc_make --- src/desc/doc_make 3 Apr 2007 08:24:20 -0000 1.7 +++ src/desc/doc_make 21 Aug 2007 15:04:50 -0000 @@ -71,7 +71,7 @@ next; } if ($c eq 'V') { - $args .= ", entree *". shift(@ARGS) ." = NULL"; next; + next; } if ($c =~ /^[EI]$/) { $args .= ", char *". shift(@ARGS) ." = NULL"; next; Index: src/graph/plotport.c =================================================================== RCS file: /home/cvs/pari/src/graph/plotport.c,v retrieving revision 1.60 diff -u -r1.60 plotport.c --- src/graph/plotport.c 17 May 2007 11:14:37 -0000 1.60 +++ src/graph/plotport.c 21 Aug 2007 15:05:02 -0000 @@ -106,13 +106,13 @@ static GEN quark_gen; static GEN -READ_EXPR(GEN code, entree *ep, GEN x) { +READ_EXPR(GEN code, GEN x) { if (code == QUARK) return gsubst(quark_gen,0,x); - ep->value = x; return closure_evalgen(code); + set_lex(-1,x); return closure_evalgen(code); } void -plot(entree *ep, GEN a, GEN b, GEN code, GEN ysmlu,GEN ybigu, long prec) +plot(GEN a, GEN b, GEN code, GEN ysmlu,GEN ybigu, long prec) { long jz, j, i, sig; pari_sp av = avma, av2, limite; @@ -124,7 +124,7 @@ sig=gcmp(b,a); if (!sig) return; if (sig<0) { x=a; a=b; b=x; } - x = gtofp(a, prec); push_val(ep, x); + x = gtofp(a, prec); push_lex(x); dx = divru(gtofp(gsub(b,a),prec), ISCR-1); ysml = ybig = 0.; for (j=1; j<=JSCR; j++) scr[1][j]=scr[ISCR][j]=YY; @@ -137,7 +137,7 @@ av2 = avma; limite=stack_lim(av2,1); for (i=1; i<=ISCR; i++) { - y[i] = gtodouble( READ_EXPR(code,ep,x) ); + y[i] = gtodouble( READ_EXPR(code,x) ); if (y[i] < ysml) ysml = y[i]; if (y[i] > ybig) ybig = y[i]; x = addrr(x,dx); @@ -178,7 +178,7 @@ for (i=1; i<=ISCR; i++) pariputc(scr[i][1]); pariputc('\n'); pariprintf("%10s%-9.7g%*.7g\n"," ",todbl(a),ISCR-9,todbl(b)); - pop_val(ep); + pop_lex(); } /********************************************************************/ @@ -1205,7 +1205,7 @@ } static void -single_recursion(dblPointList *pl,GEN code,entree *ep,GEN xleft,double yleft, +single_recursion(dblPointList *pl,GEN code,GEN xleft,double yleft, GEN xright,double yright,long depth) { GEN xx; @@ -1215,20 +1215,20 @@ if (depth==RECUR_MAXDEPTH) return; xx = addrr(xleft,xright); setexpo(xx, expo(xx)-1); - yy = gtodouble(READ_EXPR(code,ep,xx)); + yy = gtodouble(READ_EXPR(code,xx)); if (dy && fabs(yleft+yright-2*yy)< dy*RECUR_PREC) return; - single_recursion(pl,code,ep, xleft,yleft, xx,yy, depth+1); + single_recursion(pl,code, xleft,yleft, xx,yy, depth+1); Appendx(&pl[0],&pl[0],rtodbl(xx)); Appendy(&pl[0],&pl[1],yy); - single_recursion(pl,code,ep, xx,yy, xright,yright, depth+1); + single_recursion(pl,code, xx,yy, xright,yright, depth+1); avma = av; } static void -param_recursion(dblPointList *pl,GEN code,entree *ep, GEN tleft,double xleft, +param_recursion(dblPointList *pl,GEN code,GEN tleft,double xleft, double yleft, GEN tright,double xright,double yright, long depth) { GEN tt, p1; @@ -1239,25 +1239,25 @@ if (depth==PARAMR_MAXDEPTH) return; tt = addrr(tleft,tright); setexpo(tt, expo(tt)-1); - p1 = READ_EXPR(code,ep,tt); + p1 = READ_EXPR(code,tt); xx = gtodouble(gel(p1,1)); yy = gtodouble(gel(p1,2)); if (dx && dy && fabs(xleft+xright-2*xx) < dx*RECUR_PREC && fabs(yleft+yright-2*yy) < dy*RECUR_PREC) return; - param_recursion(pl,code,ep, tleft,xleft,yleft, tt,xx,yy, depth+1); + param_recursion(pl,code, tleft,xleft,yleft, tt,xx,yy, depth+1); Appendx(&pl[0],&pl[0],xx); Appendy(&pl[0],&pl[1],yy); - param_recursion(pl,code,ep, tt,xx,yy, tright,xright,yright, depth+1); + param_recursion(pl,code, tt,xx,yy, tright,xright,yright, depth+1); avma = av; } /* Pure graphing. If testpoints is 0, it is set to the default. * Returns a dblPointList of (absolute) coordinates. */ static dblPointList * -rectplothin(entree *ep, GEN a, GEN b, GEN code, long prec, ulong flags, +rectplothin(GEN a, GEN b, GEN code, long prec, ulong flags, long testpoints) { long single_c; @@ -1283,8 +1283,8 @@ if (sig<0) swap(a, b); dx = divru(gtofp(gsub(b,a),prec), testpoints-1); - x = gtofp(a, prec); push_val(ep, x); - av2=avma; t=READ_EXPR(code,ep,x); tx=typ(t); + x = gtofp(a, prec); push_lex(x); + av2=avma; t=READ_EXPR(code,x); tx=typ(t); if (!is_matvec_t(tx)) { xsml = gtodouble(a); @@ -1337,14 +1337,14 @@ GEN tleft = cgetr(prec), tright = cgetr(prec); double xleft, xright = 0; av2 = avma; - affgr(a,tleft); t=READ_EXPR(code,ep,tleft); + affgr(a,tleft); t=READ_EXPR(code,tleft); xleft = gtodouble(gel(t,1)); yleft = gtodouble(gel(t,2)); for (i=0; i<testpoints-1; i++) { if (i) { affrr(tright,tleft); xleft = xright; yleft = yright; } addrrz(tleft,dx,tright); - t = READ_EXPR(code,ep,tright); + t = READ_EXPR(code,tright); if (lg(t) != 3) pari_err(talker,"inconsistent data in rectplothin"); xright = gtodouble(gel(t,1)); yright = gtodouble(gel(t,2)); @@ -1352,7 +1352,7 @@ Appendx(&pl[0],&pl[0],xleft); Appendy(&pl[0],&pl[1],yleft); - param_recursion(pl,code,ep, tleft,xleft,yleft, tright,xright,yright, 0); + param_recursion(pl,code, tleft,xleft,yleft, tright,xright,yright, 0); avma = av2; } Appendx(&pl[0],&pl[0],xright); @@ -1363,16 +1363,16 @@ GEN xleft = cgetr(prec), xright = cgetr(prec); av2 = avma; affgr(a,xleft); - yleft = gtodouble(READ_EXPR(code,ep,xleft)); + yleft = gtodouble(READ_EXPR(code,xleft)); for (i=0; i<testpoints-1; i++) { addrrz(xleft,dx,xright); - yright = gtodouble(READ_EXPR(code,ep,xright)); + yright = gtodouble(READ_EXPR(code,xright)); Appendx(&pl[0],&pl[0],rtodbl(xleft)); Appendy(&pl[0],&pl[1],yleft); - single_recursion(pl,code,ep,xleft,yleft,xright,yright,0); + single_recursion(pl,code,xleft,yleft,xright,yright,0); avma = av2; affrr(xright,xleft); yleft = yright; } @@ -1385,7 +1385,7 @@ if (single_c) for (i=0; i<testpoints; i++) { - t = READ_EXPR(code,ep,x); + t = READ_EXPR(code,x); pl[0].d[i]=gtodouble(x); Appendy(&pl[0],&pl[1],gtodouble(t)); addrrz(x,dx,x); avma=av2; @@ -1397,7 +1397,7 @@ for (i=0; i<testpoints; i++) { - t = READ_EXPR(code,ep,x); + t = READ_EXPR(code,x); if (lg(t) != nl+1) pari_err(talker,"inconsistent data in rectplothin"); for (j=0; j<nl; j=k) { @@ -1413,14 +1413,14 @@ else /* plothmult */ for (i=0; i<testpoints; i++) { - t = READ_EXPR(code,ep,x); + t = READ_EXPR(code,x); if (lg(t) != nl) pari_err(talker,"inconsistent data in rectplothin"); pl[0].d[i]=gtodouble(x); for (j=1; j<nl; j++) { Appendy(&pl[0],&pl[j],gtodouble(gel(t,j))); } addrrz(x,dx,x); avma=av2; } } - pl[0].nb=nc; pop_val(ep); avma = av; + pl[0].nb=nc; pop_lex(); avma = av; return pl; } @@ -1434,7 +1434,6 @@ long i, j; pari_sp oldavma = avma; GEN tas, X = pol_x(0), xa = cgetg(lx+1, t_VEC), ya = cgetg(lx+1, t_VEC); - entree *var0 = varentries[0]; if (lx < 4) pari_err(talker, "Too few points (%ld) for spline plot", lx); for (i = 1; i <= lx; i++) { @@ -1458,7 +1457,7 @@ quark_gen = polint_i(xa, ya, X, 4, NULL); tas = xa; } - rectploth(ne, var0, + rectploth(ne, i==0 ? gel(tas,0) : gel(tas,1), i==lx-4 ? gel(tas,3) : gel(tas,2), QUARK, DEFAULTPREC, @@ -1648,10 +1647,10 @@ /*************************************************************************/ GEN -rectploth(long drawrect,entree *ep,GEN a,GEN b,GEN code, +rectploth(long drawrect,GEN a,GEN b,GEN code, long prec,ulong flags,long testpoints) { - dblPointList *pl=rectplothin(ep, a,b, code, prec, flags,testpoints); + dblPointList *pl=rectplothin(a,b, code, prec, flags,testpoints); return rectplothrawin(0,drawrect, pl, flags,NULL); } @@ -1672,11 +1671,11 @@ } static GEN -ploth0(long stringrect,long drawrect,entree *ep,GEN a,GEN b,GEN code, +ploth0(long stringrect,long drawrect,GEN a,GEN b,GEN code, long prec,ulong flags,long testpoints) { PARI_plot *output = init_output(flags); - dblPointList *pl=rectplothin(ep, a,b, code, prec, flags,testpoints); + dblPointList *pl=rectplothin(a,b, code, prec, flags,testpoints); return rectplothrawin(stringrect,drawrect, pl, flags, output); } @@ -1702,21 +1701,21 @@ } GEN -ploth(entree *ep, GEN a, GEN b, GEN code, long prec,long flags,long numpoints) +ploth(GEN a, GEN b, GEN code, long prec,long flags,long numpoints) { - return ploth0(STRINGRECT, DRAWRECT, ep,a,b,code,prec,flags,numpoints); + return ploth0(STRINGRECT, DRAWRECT, a,b,code,prec,flags,numpoints); } GEN -ploth2(entree *ep, GEN a, GEN b, GEN code, long prec) +ploth2(GEN a, GEN b, GEN code, long prec) { - return ploth0(STRINGRECT, DRAWRECT, ep,a,b,code,prec,PLOT_PARAMETRIC,0); + return ploth0(STRINGRECT, DRAWRECT, a,b,code,prec,PLOT_PARAMETRIC,0); } GEN -plothmult(entree *ep, GEN a, GEN b, GEN code, long prec) +plothmult(GEN a, GEN b, GEN code, long prec) { - return ploth0(STRINGRECT, DRAWRECT, ep,a,b,code,prec,0,0); + return ploth0(STRINGRECT, DRAWRECT, a,b,code,prec,0,0); } GEN @@ -1727,18 +1726,17 @@ } GEN -postploth(entree *ep, GEN a, GEN b, GEN code, long prec,long flags, - long numpoints) +postploth(GEN a, GEN b, GEN code, long prec,long flags, long numpoints) { - return ploth0(STRINGRECT,DRAWRECT,ep,a,b,code,prec,flags|PLOT_POSTSCRIPT, + return ploth0(STRINGRECT,DRAWRECT,a,b,code,prec,flags|PLOT_POSTSCRIPT, numpoints); } GEN -postploth2(entree *ep, GEN a, GEN b, GEN code, long prec, +postploth2(GEN a, GEN b, GEN code, long prec, long numpoints) { - return ploth0(STRINGRECT,DRAWRECT,ep,a,b,code,prec, + return ploth0(STRINGRECT,DRAWRECT,a,b,code,prec, PLOT_PARAMETRIC|PLOT_POSTSCRIPT,numpoints); } Index: src/graph/rect.h =================================================================== RCS file: /home/cvs/pari/src/graph/rect.h,v retrieving revision 1.24 diff -u -r1.24 rect.h --- src/graph/rect.h 10 May 2007 22:30:30 -0000 1.24 +++ src/graph/rect.h 21 Aug 2007 15:05:02 -0000 @@ -266,17 +266,17 @@ void initrect_gen(long ne, GEN x, GEN y, long flag); void killrect(long ne); void plot_count(long *w, long lw, col_counter rcolcnt); -void plot(entree *ep, GEN a, GEN b, GEN code, GEN ysmlu, GEN ybigu, long prec); -GEN ploth(entree *ep, GEN a, GEN b, GEN code, long prec, long flag, long numpoints); -GEN ploth2(entree *ep, GEN a, GEN b, GEN code, long prec); -GEN plothmult(entree *ep, GEN a, GEN b, GEN code, long prec); +void plot(GEN a, GEN b, GEN code, GEN ysmlu, GEN ybigu, long prec); +GEN ploth(GEN a, GEN b, GEN code, long prec, long flag, long numpoints); +GEN ploth2(GEN a, GEN b, GEN code, long prec); +GEN plothmult(GEN a, GEN b, GEN code, long prec); GEN plothraw(GEN listx, GEN listy, long flag); GEN plothsizes(void); GEN plothsizes_flag(long flag); void postdraw(GEN list); void postdraw_flag(GEN list, long flag); -GEN postploth(entree *ep,GEN a,GEN b,GEN code,long prec,long flag,long numpoints); -GEN postploth2(entree *ep,GEN a,GEN b,GEN code,long prec,long numpoints); +GEN postploth(GEN a,GEN b,GEN code,long prec,long flag,long numpoints); +GEN postploth2(GEN a,GEN b,GEN code,long prec,long numpoints); GEN postplothraw(GEN listx, GEN listy, long flag); void rectbox(long ne, GEN gx2, GEN gy2); void rectcolor(long ne, long color); @@ -289,7 +289,7 @@ void rectlines(long ne, GEN listx, GEN listy, long flag); void rectlinetype(long ne, long t); void rectmove(long ne, GEN x, GEN y); -GEN rectploth(long drawrect,entree *ep, GEN a, GEN b, GEN code, long prec, ulong flags, long testpoints); +GEN rectploth(long drawrect,GEN a, GEN b, GEN code, long prec, ulong flags, long testpoints); GEN rectplothraw(long drawrect, GEN data, long flags); void rectpoint(long ne, GEN x, GEN y); void rectpoints(long ne, GEN listx, GEN listy); Index: src/headers/paridecl.h =================================================================== RCS file: /home/cvs/pari/src/headers/paridecl.h,v retrieving revision 1.689 diff -u -r1.689 paridecl.h --- src/headers/paridecl.h 17 Aug 2007 14:25:07 -0000 1.689 +++ src/headers/paridecl.h 21 Aug 2007 15:05:04 -0000 @@ -1914,8 +1914,8 @@ GEN sumpos(void *E, GEN (*eval)(GEN,void*), GEN a, long prec); GEN sumpos2(void *E, GEN (*eval)(GEN,void*), GEN a, long prec); GEN suminf(void *E, GEN (*eval)(GEN,void*), GEN a, long prec); -GEN vecteur(GEN nmax, entree *ep, GEN n); -GEN vvecteur(GEN nmax, entree *ep, GEN n); +GEN vecteur(GEN nmax, GEN n); +GEN vvecteur(GEN nmax, GEN n); GEN zbrent(void *E, GEN (*eval)(GEN,void*), GEN a, GEN b, long prec); /* thue.c */ Index: src/headers/paripriv.h =================================================================== RCS file: /home/cvs/pari/src/headers/paripriv.h,v retrieving revision 1.159 diff -u -r1.159 paripriv.h --- src/headers/paripriv.h 17 Aug 2007 14:25:07 -0000 1.159 +++ src/headers/paripriv.h 21 Aug 2007 15:05:42 -0000 @@ -64,7 +64,7 @@ GEN setloop(GEN a); /* parser */ -void forpari(entree *ep, GEN a, GEN b, GEN node); +void forpari(GEN a, GEN b, GEN node); void untilpari(GEN a, GEN b); void whilepari(GEN a, GEN b); GEN ifpari(GEN g, GEN a, GEN b); @@ -86,39 +86,39 @@ GEN gsub1e(GEN *x); GEN gshift_right(GEN x, long n); -GEN derivnum0(entree *ep, GEN a, GEN code, long prec); -GEN direuler0(entree *ep, GEN a, GEN b, GEN code, GEN c); -GEN divsum(GEN num,entree *ep, GEN code); -void fordiv(GEN a, entree *ep, GEN code); -void forell(entree *ep, long a, long b, GEN code); -void forprime(entree *ep, GEN a, GEN b, GEN code); -void forstep(entree *ep, GEN a, GEN b, GEN s, GEN code); -void forsubgroup(entree *oep, GEN cyc, GEN bound, GEN code); -void forvec(entree *ep, GEN x, GEN code, long flag); -GEN intcirc0(entree *ep, GEN a, GEN R, GEN code, GEN tab, long prec); -GEN intfourcos0(entree *ep, GEN a, GEN b, GEN x, GEN code, GEN tab, long prec); -GEN intfourexp0(entree *ep, GEN a, GEN b, GEN x, GEN code, GEN tab, long prec); -GEN intfoursin0(entree *ep, GEN a, GEN b, GEN x, GEN code, GEN tab, long prec); -GEN intfuncinit0(entree *ep, GEN a, GEN b, GEN code, long flag, long m, long prec); -GEN intlaplaceinv0(entree *ep, GEN sig, GEN x, GEN code, GEN tab, long prec); -GEN intmellininv0(entree *ep, GEN sig, GEN x, GEN code, GEN tab, long prec); -GEN intnum0(entree *ep, GEN a, GEN b, GEN code, GEN tab, long prec); +GEN derivnum0(GEN a, GEN code, long prec); +GEN direuler0(GEN a, GEN b, GEN code, GEN c); +GEN divsum(GEN num, GEN code); +void fordiv(GEN a, GEN code); +void forell(long a, long b, GEN code); +void forprime(GEN a, GEN b, GEN code); +void forstep(GEN a, GEN b, GEN s, GEN code); +void forsubgroup(GEN cyc, GEN bound, GEN code); +void forvec(GEN x, GEN code, long flag); +GEN intcirc0(GEN a, GEN R, GEN code, GEN tab, long prec); +GEN intfourcos0(GEN a, GEN b, GEN x, GEN code, GEN tab, long prec); +GEN intfourexp0(GEN a, GEN b, GEN x, GEN code, GEN tab, long prec); +GEN intfoursin0(GEN a, GEN b, GEN x, GEN code, GEN tab, long prec); +GEN intfuncinit0(GEN a, GEN b, GEN code, long flag, long m, long prec); +GEN intlaplaceinv0(GEN sig, GEN x, GEN code, GEN tab, long prec); +GEN intmellininv0(GEN sig, GEN x, GEN code, GEN tab, long prec); +GEN intnum0(GEN a, GEN b, GEN code, GEN tab, long prec); GEN intnuminit0(GEN a, GEN b, GEN tab, long prec); -GEN intnuminitgen0(entree *ep, GEN a, GEN b, GEN code, long m, long flag, long prec); -GEN intnumromb0(entree *ep, GEN a, GEN b, GEN code, long flag, long prec); -GEN matrice(GEN nlig, GEN ncol,entree *ep1, entree *ep2, GEN code); -GEN prodeuler0(entree *ep, GEN a, GEN b, GEN code, long prec); -GEN prodinf0(entree *ep, GEN a, GEN code, long flag, long prec); -GEN produit(entree *ep, GEN a, GEN b, GEN code, GEN x); -GEN somme(entree *ep, GEN a, GEN b, GEN code, GEN x); -GEN sumalt0(entree *ep, GEN a, GEN code,long flag, long prec); -GEN suminf0(entree *ep, GEN a, GEN code, long prec); -GEN sumnum0(entree *ep, GEN a, GEN sig, GEN code, GEN tab, long flag, long prec); -GEN sumnumalt0(entree *ep, GEN a, GEN sig, GEN code, GEN tab, long flag, long prec); +GEN intnuminitgen0(GEN a, GEN b, GEN code, long m, long flag, long prec); +GEN intnumromb0(GEN a, GEN b, GEN code, long flag, long prec); +GEN matrice(GEN nlig, GEN ncol, GEN code); +GEN prodeuler0(GEN a, GEN b, GEN code, long prec); +GEN prodinf0(GEN a, GEN code, long flag, long prec); +GEN produit(GEN a, GEN b, GEN code, GEN x); +GEN somme(GEN a, GEN b, GEN code, GEN x); +GEN sumalt0(GEN a, GEN code,long flag, long prec); +GEN suminf0(GEN a, GEN code, long prec); +GEN sumnum0(GEN a, GEN sig, GEN code, GEN tab, long flag, long prec); +GEN sumnumalt0(GEN a, GEN sig, GEN code, GEN tab, long flag, long prec); GEN sumnuminit0(GEN a, GEN tab, long sgn, long prec); -GEN sumpos0(entree *ep, GEN a, GEN code, long flag,long prec); -GEN vecteursmall(GEN nmax, entree *ep, GEN code); -GEN zbrent0(entree *ep, GEN a, GEN b, GEN code, long prec); +GEN sumpos0(GEN a, GEN code, long flag,long prec); +GEN vecteursmall(GEN nmax, GEN code); +GEN zbrent0(GEN a, GEN b, GEN code, long prec); /* multiprecision */ GEN icopy_spec(GEN x, long nx); @@ -414,7 +414,6 @@ void print_functions_hash(const char *s); void print_all_user_fun(void); void pop_val(entree *ep); -void push_val(entree *ep, GEN a); GEN readbin(const char *name, FILE *f, int *vector); void recover(int flag); int term_height(void); Index: src/headers/paristio.h =================================================================== RCS file: /home/cvs/pari/src/headers/paristio.h,v retrieving revision 1.40 diff -u -r1.40 paristio.h --- src/headers/paristio.h 1 Aug 2007 22:00:12 -0000 1.40 +++ src/headers/paristio.h 21 Aug 2007 15:05:42 -0000 @@ -37,7 +37,6 @@ char *help; void *pvalue; long arity; - GEN lvars; struct entree *next; } entree; Index: src/language/anal.c =================================================================== RCS file: /home/cvs/pari/src/language/anal.c,v retrieving revision 1.281 diff -u -r1.281 anal.c --- src/language/anal.c 7 Aug 2007 14:55:16 -0000 1.281 +++ src/language/anal.c 21 Aug 2007 15:05:42 -0000 @@ -246,7 +246,6 @@ case 'M': case 'P': case 'S': - case 'V': case 'f': case 'n': case 'p': @@ -262,12 +261,13 @@ if (*s == 'G' || *s == '&' || *s == 'n' || *s == 'I' || *s == 'E' || *s == 'V') { - arity++; + if (*s != 'V') arity++; s++; break; } old = s; while (*s != ',') s++; if (*s != ',') pari_err(talker2, "missing comma", old, code); break; + case 'V': case '=': case ',': break; case '\n': return arity; /* Before the mnemonic */ @@ -306,7 +306,6 @@ ep->help = NULL; ep->pvalue = NULL; ep->arity = 0; - ep->lvars = NULL; ep->next = *table; return *table = ep; } Index: src/language/anal.h =================================================================== RCS file: /home/cvs/pari/src/language/anal.h,v retrieving revision 1.93 diff -u -r1.93 anal.h --- src/language/anal.h 4 Aug 2007 13:45:23 -0000 1.93 +++ src/language/anal.h 21 Aug 2007 15:05:42 -0000 @@ -21,15 +21,11 @@ BEGINEXTERN /* GP control structures */ -typedef struct { - entree *ep; - GEN code; -} exprdat; GEN gp_eval(GEN x, void *dat); -#define EXPR_WRAP(ep, ch, call) \ -{ GEN z; exprdat __E; __E.code = ch; __E.ep = ep;\ - push_val(ep,NULL); z = call; pop_val(ep); return z; } -#define EXPR_ARG &__E, &gp_eval +#define EXPR_WRAP(code, call) \ +{ GEN z; GEN __E = code; \ + push_lex(NULL); z = call; pop_lex(); return z; } +#define EXPR_ARG __E, &gp_eval /* to manipulate 'blocs' */ #define BL_HEAD 4 @@ -224,4 +220,9 @@ void stack_init(gp2c_stack *s, size_t size, void **data); long stack_new(gp2c_stack *s); +void push_lex(GEN a); +void set_lex(long vn, GEN x); +GEN get_lex(long vn); +void pop_lex(void); + ENDEXTERN Index: src/language/compat.c =================================================================== RCS file: /home/cvs/pari/src/language/compat.c,v retrieving revision 1.75 diff -u -r1.75 compat.c --- src/language/compat.c 14 Aug 2007 15:27:07 -0000 1.75 +++ src/language/compat.c 21 Aug 2007 15:05:51 -0000 @@ -28,10 +28,10 @@ polylogp(long m, GEN x, long prec) { return polylog0(m,x,3,prec); } static GEN -prod0(GEN x, entree *ep, GEN a, GEN b, GEN ch) {return produit(ep,a,b,ch,x);} +prod0(GEN x, GEN a, GEN b, GEN ch) {return produit(a,b,ch,x);} static GEN -sum0(GEN x, entree *ep, GEN a, GEN b, GEN ch) {return somme(ep,a,b,ch,x);} +sum0(GEN x, GEN a, GEN b, GEN ch) {return somme(a,b,ch,x);} static long sturm0(GEN x) {return sturm(x);} Index: src/language/compile.c =================================================================== RCS file: /home/cvs/pari/src/language/compile.c,v retrieving revision 1.18 diff -u -r1.18 compile.c --- src/language/compile.c 15 Aug 2007 16:41:46 -0000 1.18 +++ src/language/compile.c 21 Aug 2007 15:05:57 -0000 @@ -26,12 +26,20 @@ ** ** ***************************************************************************/ +typedef enum {Lglobal, Llocal, Lmy} Ltype; + +struct vars_s +{ + Ltype type; /*Only Llocal and Lmy are allowed */ + entree *ep; +}; + static THREAD gp2c_stack s_opcode, s_operand, s_data, s_lvar; static THREAD char *opcode; static THREAD long *operand; static THREAD GEN *data; static THREAD long offset=-1; -static THREAD long *localvars; +static THREAD struct vars_s *localvars; void pari_init_compiler(void) @@ -94,6 +102,7 @@ gunclone(data[i+pos->data-1]); } s_data.n=pos->data; + s_lvar.n=pos->localvars; offset=pos->offset; return cl; } @@ -116,13 +125,14 @@ } static void -var_push(long x) +var_push(entree *ep, Ltype type) { long n=stack_new(&s_lvar); - localvars[n] = x; + localvars[n].ep = ep; + localvars[n].type = type; } -enum FLflag {FLnocopy=1}; +enum FLflag {FLnocopy=1, FLreturn=2}; static void compilenode(long n, int mode, long flag); @@ -259,6 +269,21 @@ return ep; } +static long +getmvar(entree *ep) +{ + long i; + long vn=0; + for(i=s_lvar.n-1;i>=0;i--) + { + if(localvars[i].type==Lmy) + vn--; + if(localvars[i].ep==ep) + return localvars[i].type==Lmy?vn:0; + } + return 0; +} + static entree * getfunc(long n) { @@ -273,6 +298,14 @@ return !strncmp(tree[x].str, s, tree[x].len); } +INLINE int +is_node_zero(long n) +{ + while (tree[n].f==Ftag) + n=tree[n].x; + return (tree[n].f==Fsmall && tree[n].x==0); +} + static GEN listtogen(long n, long f) { @@ -474,8 +507,9 @@ PPproto mod; GEN arg=listtogen(y,Flistarg); long nbpointers=0; - long nb=lg(arg)-1, lnc; + long nb=lg(arg)-1, lnc, lev=0; entree *ep = getfunc(n); + entree *ev[8]; if (EpVALENCE(ep)==EpVAR || EpVALENCE(ep)==EpGVAR) pari_err(talker2,"not a function in function call", tree[n].str, get_origin()); @@ -497,23 +531,55 @@ } if (is_func_named(x,"if") && mode==Gvoid) ep=is_entry("_void_if"); + if (is_func_named(x,"my")) + { + if (tree[n].f==Fderfunc) + pari_err(talker2,"can't derive this",tree[n].str,get_origin()); + if (nb) + { + op_push(OCnewframe,nb); + for(i=1;i<=nb;i++) + var_push(NULL,Lmy); + } + for (i=1;i<=nb;i++) + { + long a=arg[i]; + if (tree[a].f==Faffect) + { + if (!is_node_zero(tree[a].y)) + { + compilenode(tree[a].y,Ggen,0); + op_push(OCstorelex,-nb+i-1); + } + a=tree[a].x; + } + localvars[s_lvar.n-nb+i-1].ep=getvar(a); + } + compilecast(n,Gvoid,mode); + avma=ltop; + return; + } if (is_func_named(x,"local")) { if (tree[n].f==Fderfunc) pari_err(talker2,"can't derive this",tree[n].str,get_origin()); for (i=1;i<=nb;i++) { - long en, a=arg[i]; + entree *en; + long a=arg[i]; + op_code op=OClocalvar0; if (tree[a].f==Faffect) { - compilenode(tree[a].y,Ggen,0); + if (!is_node_zero(tree[a].y)) + { + compilenode(tree[a].y,Ggen,0); + op=OClocalvar; + } a=tree[a].x; } - else - op_push(OCpushlong,(long)gen_0); - en=(long)getvar(a); - op_push(OCgetarg,en); - var_push(en); + en=getvar(a); + op_push(op,(long)en); + var_push(en,Llocal); } compilecast(n,Gvoid,mode); avma=ltop; @@ -592,7 +658,7 @@ while((mod=parseproto(&p,&c))!=PPend) { if (j<=nb && tree[arg[j]].f!=Fnoarg - && (mod==PPdefault || mod==PPdefaultmulti)) + && (mod==PPdefault || mod==PPdefaultmulti)) mod=PPstd; switch(mod) { @@ -618,7 +684,7 @@ break; case '&': case '*': { - long a=arg[j++]; + long vn, a=arg[j++]; entree *ep; if (c=='&') { @@ -628,11 +694,20 @@ a=tree[a].x; } ep=getlvalue(a); + vn=getmvar(ep); if (tree[a].f==Fentry) - op_push(OCsimpleptr, (long) ep); + { + if (vn) + op_push(OCsimpleptrlex, vn); + else + op_push(OCsimpleptrdyn, (long) ep); + } else { - op_push(OCnewptr, (long) ep); + if (vn) + op_push(OCnewptrlex, vn); + else + op_push(OCnewptrdyn, (long) ep); compilelvalue(a); op_push(OCpushptr, 0); } @@ -645,18 +720,25 @@ struct codepos pos; long a=arg[j++]; int type=c=='I'?Gvoid:Ggen; + long flag=c=='I'?0:FLreturn; getcodepos(&pos); + for(i=0;i<lev;i++) + { + if (!ev[i]) + pari_err(talker2,"missing variable name", + tree[a].str-1, get_origin()); + var_push(ev[i],Lmy); + } if (tree[a].f==Fnoarg) compilecast(a,Gvoid,type); else - compilenode(a,type,0); + compilenode(a,type,flag); op_push(OCpushgen, data_push(getclosure(&pos))); break; } case 'V': { - entree *ep = getvar(arg[j++]); - op_push(OCpushlong, (long)ep); + ev[lev++] = getvar(arg[j++]); break; } case 'S': @@ -669,12 +751,10 @@ { long x=tree[arg[j]].x; long y=tree[arg[j]].y; - entree *ep; if (tree[arg[j]].f!=Faffect) pari_err(talker2,"expected character: '=' instead of", tree[n].str+tree[n].len, get_origin()); - ep = getvar(x); - op_push(OCpushlong, (long)ep); + ev[lev++] = getvar(x); compilenode(y,Ggen,0); i++; j++; } @@ -731,7 +811,6 @@ { case 'G': case '&': - case 'V': case 'r': case 'E': case 'I': @@ -740,6 +819,9 @@ case 'n': op_push(OCpushlong,-1); break; + case 'V': + ev[lev++] = NULL; + break; default: pari_err(talker,"Unknown prototype code `%c' for `%*s'",c, tree[x].len, tree[x].str); @@ -878,7 +960,7 @@ case Fseq: if (tree[x].f!=Fnoarg) compilenode(x,Gvoid,0); - compilenode(y,mode,0); + compilenode(y,mode,flag&FLreturn); return; case Ffacteurmat: compilefacteurmat(n,mode); @@ -889,11 +971,20 @@ if (tree[x].f==Fentry) { entree *ep=getvar(x); + long vn=getmvar(ep); compilenode(y,Ggen,FLnocopy); - op_push(OCstore,(long)ep); + if (vn) + op_push(OCstorelex,vn); + else + op_push(OCstoredyn,(long)ep); if (mode!=Gvoid) { - op_push(OCpushvalue,(long)ep); + if (vn) + op_push(OCpushlex,vn); + else + op_push(OCpushdyn,(long)ep); + if (flag&FLreturn) + op_push(OCcopyifclone,0); compilecast(n,Ggen,mode); } } @@ -972,9 +1063,20 @@ case Fentry: { entree *ep=getentry(n); - if (!EpSTATIC(do_alias(ep))) + long vn=getmvar(ep); + if (vn) { - op_push(OCpushvalue,(long)ep); + op_push(OCpushlex,(long)vn); + if (flag&FLreturn) + op_push(OCcopyifclone,0); + compilecast(n,Ggen,mode); + break; + } + else if (!EpSTATIC(do_alias(ep))) + { + op_push(OCpushdyn,(long)ep); + if (flag&FLreturn) + op_push(OCcopyifclone,0); compilecast(n,Ggen,mode); break; } @@ -991,8 +1093,6 @@ GEN arg2=listtogen(tree[x].y,Flistarg); entree *ep=getfunc(x); long loc=y; - long nbvar; - GEN lvar; long arity=lg(arg2)-1; if (loc>=0) while (tree[loc].f==Fseq) loc=tree[loc].x; @@ -1006,16 +1106,17 @@ tree[n].str,get_origin()); } getcodepos(&pos); + if (arity) op_push(OCnewframe,arity); for (i=1;i<=arity;i++) { long a = arg2[lg(arg2)-i]; - long en; + entree *en; switch (tree[a].f) { case Fentry: case Ftag: - en=(long)getvar(a); - op_push(OCgetarg,en); - var_push(en); + en=getvar(a); + var_push(en,Lmy); + op_push(OCgetarg,-arity+i-1); break; case Faffect: { @@ -1023,9 +1124,9 @@ getcodepos(&lpos); compilenode(tree[a].y,Ggen,0); op_push(OCpushgen, data_push(getclosure(&lpos))); - en=(long)getvar(tree[a].x); - op_push(OCdefaultarg,en); - var_push(en); + en=getvar(tree[a].x); + var_push(en,Lmy); + op_push(OCdefaultarg,-arity+i-1); break; } default: @@ -1033,25 +1134,11 @@ tree[a].str,get_origin()); } } - if (y>=0 && tree[y].f!=Fnoarg) compilenode(y,Ggen,0); - else compilecast(n,Gvoid,Ggen); - nbvar=s_lvar.n-pos.localvars; - s_lvar.n=pos.localvars; - lvar=cgetg(nbvar+1,t_VECSMALL); - for(i=1;i<=nbvar;i++) - lvar[i]=localvars[pos.localvars+i-1]; - if (nbvar > 1) - { /* check for duplicates */ - GEN x = vecsmall_copy(lvar); - long k; - vecsmall_sort(x); - for (k=x[1],i=2; i<lg(x); k=x[i],i++) - if (x[i] == k) - pari_err(talker,"user function %s: variable %s declared twice", - ep->name, ((entree*)x[i])->name); - } + if (y>=0 && tree[y].f!=Fnoarg) + compilenode(y,Ggen,FLreturn); + else + compilecast(n,Gvoid,Ggen); op_push(OCpushgen, data_push(getclosure(&pos))); - op_push(OCpushgen, data_push(lvar)); op_push(OCpushgen, data_push( strntoGENstr(tree[n].str,tree[n].len))); op_push(OCpushlong, arity); Index: src/language/eval.c =================================================================== RCS file: /home/cvs/pari/src/language/eval.c,v retrieving revision 1.25 diff -u -r1.25 eval.c --- src/language/eval.c 18 Aug 2007 21:12:59 -0000 1.25 +++ src/language/eval.c 21 Aug 2007 15:05:57 -0000 @@ -158,7 +158,6 @@ switch(EpVALENCE(ep)) { case EpUSER: - gunclone(ep->lvars); ep->lvars=NULL; while (ep->pvalue!=INITIAL) pop_val(ep); gunclone((GEN)ep->value); ep->value=NULL; break; @@ -171,12 +170,6 @@ } } -void -push_val(entree *ep, GEN a) -{ - new_val_cell(ep, a, PUSH_VAL); -} - /* kill ep->value and replace by preceding one, poped from value stack */ void pop_val(entree *ep) @@ -196,6 +189,20 @@ new_val_cell(ep, x, typ(x) >= t_VEC ? COPY_VAL: PUSH_VAL); } +INLINE void +zerovalue (entree *ep) +{ + var_cell *v = (var_cell*) gpmalloc(sizeof(var_cell)); + v->value = (GEN)ep->value; + v->prev = (var_cell*) ep->pvalue; + v->flag = PUSH_VAL; + v->valence= ep->valence; + ep->value = gen_0; + ep->pvalue= (char*)v; + ep->valence=EpVAR; +} + + /* as above IF ep->value was PUSHed, or was created after block number 'loc' return 0 if not deleted, 1 otherwise [for recover()] */ int @@ -305,6 +312,7 @@ matcomp c; GEN x; entree *ep; + long vn; } gp_pointer; @@ -349,10 +357,82 @@ ** ** ***************************************************************************/ -static THREAD long *st; +struct var_lex +{ + long flag; + GEN value; +}; + static THREAD long sp, rp; +static THREAD long *st; static THREAD gp_pointer *ptrs; -static THREAD gp2c_stack s_st,s_ptrs; +static THREAD entree **lvars; +static THREAD struct var_lex *var; +static THREAD gp2c_stack s_st, s_ptrs, s_var, s_lvars; + +static void +changelex(long vn, GEN x) +{ + struct var_lex *v=var+s_var.n+vn; + x = gclone(x); /* beware: killbloc may destroy old x */ + if (v->flag == COPY_VAL) killbloc(v->value); else v->flag = COPY_VAL; + v->value = x; +} + +INLINE void +zerolex(long vn) +{ + struct var_lex *v=var+s_var.n+vn; + v->flag = PUSH_VAL; + v->value = gen_0; +} + +INLINE void +copylex(long vn, GEN x) +{ + struct var_lex *v=var+s_var.n+vn; + v->flag = typ(x) >= t_VEC ? COPY_VAL: PUSH_VAL; + v->value = (v->flag == COPY_VAL)? gclone(x): + (isclone(x))? gcopy(x): x; +} + +INLINE void +freelex(long vn) +{ + struct var_lex *v=var+s_var.n+vn; + if (v->flag == COPY_VAL) killbloc(v->value); +} + +void +push_lex(GEN a) +{ + long vn=stack_new(&s_var); + struct var_lex *v=var+vn; + v->flag = PUSH_VAL; + v->value = a; +} + +GEN +get_lex(long vn) +{ + struct var_lex *v=var+s_var.n+vn; + return v->value; +} + +void +set_lex(long vn, GEN x) +{ + struct var_lex *v=var+s_var.n+vn; + if (v->flag == COPY_VAL) { killbloc(v->value); v->flag = PUSH_VAL; } + v->value = x; +} + +void +pop_lex(void) +{ + freelex(-1); + s_var.n--; +} void pari_init_evaluator(void) @@ -365,6 +445,8 @@ stack_init(&s_ptrs,sizeof(*ptrs),(void**)&ptrs); stack_alloc(&s_ptrs,16); s_ptrs.n=s_ptrs.alloc; + stack_init(&s_var,sizeof(*var),(void**)&var); + stack_init(&s_lvars,sizeof(*lvars),(void**)&lvars); } static void closure_eval(GEN C); @@ -400,12 +482,7 @@ reset_break(); } else - { z = gerepileupto(ltop, gel(st,--sp)); - if (isclone(z)) z = gcopy(z); - } - for(j=1;j<lg(ep->lvars);j++) - pop_val((entree*)ep->lvars[j]); return z; } @@ -465,7 +542,7 @@ GEN data=gel(C,3); long saved_sp=sp; long saved_rp=rp; - long pc, j; + long pc, j, nbmvar=0, nblvar=0; for(pc=1;pc<lg(oper);pc++) { op_code opcode=(op_code) code[pc]; @@ -497,7 +574,7 @@ pari_var_create(ep); gel(st,sp++)=(GEN)initial_value(ep); break; - case OCpushvalue: + case OCpushdyn: ep=(entree*)operand; switch(ep->valence) { @@ -511,12 +588,16 @@ goto calluser; /*Maybe it is a function*/ } break; - case OCsimpleptr: + case OCpushlex: + gel(st,sp++)=var[s_var.n+operand].value; + break; + case OCsimpleptrdyn: { gp_pointer *g; if (rp==s_ptrs.n-1) stack_new(&s_ptrs); g = &ptrs[rp++]; + g->vn=0; g->ep = (entree*) operand; switch (g->ep->valence) { @@ -531,14 +612,25 @@ gel(st,sp++) = (GEN)&(g->x); break; } - case OCnewptr: + case OCsimpleptrlex: + { + gp_pointer *g; + if (rp==s_ptrs.n-1) + stack_new(&s_ptrs); + g = &ptrs[rp++]; + g->vn=operand; + g->ep=(entree *)0x1L; + g->x = (GEN) var[s_var.n+operand].value; + gel(st,sp++) = (GEN)&(g->x); + break; + } + case OCnewptrdyn: { gp_pointer *g; matcomp *C; if (rp==s_ptrs.n-1) stack_new(&s_ptrs); g = &ptrs[rp++]; - C=&g->c; ep = (entree*) operand; switch (ep->valence) { @@ -552,7 +644,25 @@ pari_err(varer1,"variable name expected",NULL,NULL); } g->x = (GEN) ep->value; + g->vn=0; + g->ep=NULL; + C=&g->c; + C->full_col = C->full_row = 0; + C->parent = (GEN) g->x; + C->ptcell = (GEN *) &g->x; + break; + } + case OCnewptrlex: + { + gp_pointer *g; + matcomp *C; + if (rp==s_ptrs.n-1) + stack_new(&s_ptrs); + g = &ptrs[rp++]; + g->x = (GEN) var[s_var.n+operand].value; + g->vn=0; g->ep=NULL; + C=&g->c; C->full_col = C->full_row = 0; C->parent = (GEN) g->x; C->ptcell = (GEN *) &g->x; @@ -568,11 +678,17 @@ for(j=0;j<operand;j++) { gp_pointer *g = &ptrs[--rp]; - if (g->ep) changevalue(g->ep, g->x); + if (g->ep) + { + if (g->vn) + changelex(g->vn,g->x); + else + changevalue(g->ep, g->x); + } else change_compo(&(g->c), g->x); } break; - case OCstore: + case OCstoredyn: ep=(entree *)operand; switch (ep->valence) { @@ -585,6 +701,9 @@ pari_err(varer1,"variable name expected",NULL,NULL); } break; + case OCstorelex: + changelex(operand,gel(st,--sp)); + break; case OCstackgen: gmael(st,sp-2,operand)=copyupto(gel(st,sp-1),gel(st,sp-2)); sp--; @@ -619,6 +738,10 @@ case OCcopy: gel(st,sp-1) = gcopy(gel(st,sp-1)); break; + case OCcopyifclone: + if (isclone(gel(st,sp-1))) + gel(st,sp-1) = gcopy(gel(st,sp-1)); + break; case OCcompo1: { GEN p=gel(st,sp-2); @@ -768,25 +891,38 @@ break; } case OCgetarg: - ep=(entree *)operand; if (gel(st,sp-1)) - copyvalue(ep,gel(st,sp-1)); + copylex(operand,gel(st,sp-1)); else - copyvalue(ep,gen_0); + zerolex(operand); sp--; break; case OCdefaultarg: ep=(entree *)operand; if (gel(st,sp-2)) - copyvalue(ep,gel(st,sp-2)); + copylex(operand,gel(st,sp-2)); else { GEN z = closure_evalgen(gel(st,sp-1)); if (!z) pari_err(talker,"break not allowed in function parameter"); - copyvalue(ep,z); + copylex(operand,z); } sp-=2; break; + case OClocalvar: + ep=(entree *)operand; + j=stack_new(&s_lvars); + lvars[j]=ep; + nblvar++; + copyvalue(ep,gel(st,--sp)); + break; + case OClocalvar0: + ep=(entree *)operand; + j=stack_new(&s_lvars); + lvars[j]=ep; + nblvar++; + zerovalue(ep); + break; case OCglobalvar: ep=(entree *)operand; if (ep->valence==EpNEW) pari_var_create(ep); @@ -891,7 +1027,7 @@ pari_sp ltop; long n=st[--sp]; entree *ep = (entree*) operand; - GEN z, lvars=ep->lvars; + GEN z; if (ep->valence!=EpUSER) { int w; @@ -920,15 +1056,20 @@ reset_break(); } else - { z = gerepileupto(ltop, gel(st,--sp)); - if (isclone(z)) z = gcopy(z); - } - for(j=1;j<lg(lvars);j++) - pop_val((entree*)lvars[j]); gel(st, sp++) = z; break; } + case OCnewframe: + stack_alloc(&s_var,operand); + s_var.n+=operand; + nbmvar+=operand; + for(j=1;j<=operand;j++) + { + var[s_var.n-j].flag=PUSH_VAL; + var[s_var.n-j].value=gen_0; + } + break; case OCvec: gel(st,sp++)=cgetg(operand,t_VEC); break; @@ -953,7 +1094,6 @@ gpfree(ep->code); /*FIXME: the function might be in use... gunclone(ep->value); - gunclone(ep->lvars); */ break; case EpNEW: @@ -962,21 +1102,28 @@ default: pari_err(talker,"function name expected"); } - ep->value = (void *) gclone(gel(st,sp-4)); - ep->lvars = gclone(gel(st,sp-3)); + ep->value = (void *) gclone(gel(st,sp-3)); ep->code = pari_strdup(GSTR(gel(st,sp-2))); ep->arity = st[sp-1]; - sp-=4; + sp-=3; break; case OCpop: sp-=operand; break; } } - return; -endeval: - sp = saved_sp; - rp = saved_rp; + if (0) + { + endeval: + sp = saved_sp; + rp = saved_rp; + } + for(j=1;j<=nbmvar;j++) + freelex(-j); + s_var.n-=nbmvar; + for(j=1;j<=nblvar;j++) + pop_val(lvars[s_lvars.n-j]); + s_lvars.n-=nblvar; } GEN @@ -1066,17 +1213,34 @@ ep=(entree*)operand; pariprintf("pushvar\t%s\n",ep->name); break; - case OCpushvalue: + case OCpushdyn: + ep=(entree*)operand; + pariprintf("pushdyn\t\t%s\n",ep->name); + break; + case OCpushlex: + pariprintf("pushlex\t\t%ld\n",operand); + break; + case OCstoredyn: + ep=(entree *)operand; + pariprintf("storedyn\t%s\n",ep->name); + break; + case OCstorelex: + pariprintf("storelex\t%ld\n",operand); + break; + case OCsimpleptrdyn: ep=(entree*)operand; - pariprintf("pushvalue\t%s\n",ep->name); + pariprintf("simpleptrdyn\t%s\n",ep->name); break; - case OCsimpleptr: + case OCsimpleptrlex: ep=(entree*)operand; - pariprintf("simpleptr\t%s\n",ep->name); + pariprintf("simpleptrlex\t%ld\n",operand); break; - case OCnewptr: + case OCnewptrdyn: ep=(entree*)operand; - pariprintf("newptr\t\t%s\n",ep->name); + pariprintf("newptrdyn\t%s\n",ep->name); + break; + case OCnewptrlex: + pariprintf("newptrlex\t%ld\n",operand); break; case OCpushptr: pariprintf("pushptr\n"); @@ -1087,10 +1251,6 @@ case OCendptr: pariprintf("endptr\t\t%ld\n",operand); break; - case OCstore: - ep=(entree *)operand; - pariprintf("store\t\t%s\n",ep->name); - break; case OCprecreal: pariprintf("precreal\n"); break; @@ -1112,6 +1272,9 @@ case OCcopy: pariprintf("copy\n"); break; + case OCcopyifclone: + pariprintf("copyifclone\n"); + break; case OCcompo1: pariprintf("compo1\t\t%s\n",disassemble_cast(operand)); break; @@ -1137,12 +1300,18 @@ pariprintf("compoLptr\n"); break; case OCgetarg: - ep=(entree*)operand; - pariprintf("getarg\t\t%s\n",ep->name); + pariprintf("getarg\t\t%ld\n",operand); break; case OCdefaultarg: + pariprintf("defaultarg\t%ld\n",operand); + break; + case OClocalvar: ep=(entree*)operand; - pariprintf("defaultarg\t%s\n",ep->name); + pariprintf("localvar\t%s\n",ep->name); + break; + case OClocalvar0: + ep=(entree*)operand; + pariprintf("localvar0\t%s\n",ep->name); break; case OCglobalvar: ep=(entree*)operand; @@ -1193,6 +1362,9 @@ ep=(entree*)operand; pariprintf("deffunc\t\t%s\n",ep->name); break; + case OCnewframe: + pariprintf("newframe\t%ld\n",operand); + break; case OCpop: pariprintf("pop\t\t%ld\n",operand); break; Index: src/language/init.c =================================================================== RCS file: /home/cvs/pari/src/language/init.c,v retrieving revision 1.355 diff -u -r1.355 init.c --- src/language/init.c 10 Aug 2007 08:51:36 -0000 1.355 +++ src/language/init.c 21 Aug 2007 15:06:04 -0000 @@ -2028,8 +2028,8 @@ * E closure whose value is used, like in sum() loop * G GEN * L long - * S symbol (i.e GP function name) - * V variable (same as S, but valence must equal EpVAR/EpGVAR) + * S symbol (i.e GP function name) as a entree * + * V lexical variable * n variable number * & *GEN * f Fake *long (function requires it, but we don't use the resulting long) Index: src/language/intnum.c =================================================================== RCS file: /home/cvs/pari/src/language/intnum.c,v retrieving revision 1.35 diff -u -r1.35 intnum.c --- src/language/intnum.c 6 Jun 2007 09:36:57 -0000 1.35 +++ src/language/intnum.c 21 Aug 2007 15:06:11 -0000 @@ -30,9 +30,9 @@ GEN gp_eval(GEN x, void *dat) { - exprdat *E = (exprdat*)dat; - E->ep->value = x; - return closure_evalnobrk(E->code); + GEN code = (GEN)dat; + set_lex(-1,x); + return closure_evalnobrk(code); } #if 0 @@ -1605,38 +1605,38 @@ } GEN -intnumromb0(entree *ep, GEN a, GEN b, GEN code, long flag, long prec) -{ EXPR_WRAP(ep,code, intnumromb(EXPR_ARG, a, b, flag, prec)); } +intnumromb0(GEN a, GEN b, GEN code, long flag, long prec) +{ EXPR_WRAP(code, intnumromb(EXPR_ARG, a, b, flag, prec)); } GEN -intnum0(entree *ep, GEN a, GEN b, GEN code, GEN tab, long prec) -{ EXPR_WRAP(ep,code, intnum(EXPR_ARG, a, b, tab, prec)); } +intnum0(GEN a, GEN b, GEN code, GEN tab, long prec) +{ EXPR_WRAP(code, intnum(EXPR_ARG, a, b, tab, prec)); } GEN -intcirc0(entree *ep, GEN a, GEN R, GEN code, GEN tab, long prec) -{ EXPR_WRAP(ep,code, intcirc(EXPR_ARG, a, R, tab, prec)); } +intcirc0(GEN a, GEN R, GEN code, GEN tab, long prec) +{ EXPR_WRAP(code, intcirc(EXPR_ARG, a, R, tab, prec)); } GEN -intmellininv0(entree *ep, GEN sig, GEN x, GEN code, GEN tab, long prec) -{ EXPR_WRAP(ep,code, intmellininv(EXPR_ARG, sig, x, tab, prec)); } +intmellininv0(GEN sig, GEN x, GEN code, GEN tab, long prec) +{ EXPR_WRAP(code, intmellininv(EXPR_ARG, sig, x, tab, prec)); } GEN -intlaplaceinv0(entree *ep, GEN sig, GEN x, GEN code, GEN tab, long prec) -{ EXPR_WRAP(ep,code, intlaplaceinv(EXPR_ARG, sig, x, tab, prec)); } +intlaplaceinv0(GEN sig, GEN x, GEN code, GEN tab, long prec) +{ EXPR_WRAP(code, intlaplaceinv(EXPR_ARG, sig, x, tab, prec)); } GEN -intfourcos0(entree *ep, GEN a, GEN b, GEN x, GEN code, GEN tab, long prec) -{ EXPR_WRAP(ep,code, intfouriercos(EXPR_ARG, a, b, x, tab, prec)); } +intfourcos0(GEN a, GEN b, GEN x, GEN code, GEN tab, long prec) +{ EXPR_WRAP(code, intfouriercos(EXPR_ARG, a, b, x, tab, prec)); } GEN -intfoursin0(entree *ep, GEN a, GEN b, GEN x, GEN code, GEN tab, long prec) -{ EXPR_WRAP(ep,code, intfouriersin(EXPR_ARG, a, b, x, tab, prec)); } +intfoursin0(GEN a, GEN b, GEN x, GEN code, GEN tab, long prec) +{ EXPR_WRAP(code, intfouriersin(EXPR_ARG, a, b, x, tab, prec)); } GEN -intfourexp0(entree *ep, GEN a, GEN b, GEN x, GEN code, GEN tab, long prec) -{ EXPR_WRAP(ep,code, intfourierexp(EXPR_ARG, a, b, x, tab, prec)); } +intfourexp0(GEN a, GEN b, GEN x, GEN code, GEN tab, long prec) +{ EXPR_WRAP(code, intfourierexp(EXPR_ARG, a, b, x, tab, prec)); } GEN -intnuminitgen0(entree *ep, GEN a, GEN b, GEN code, long m, long flag, long prec) -{ EXPR_WRAP(ep,code, intnuminitgen(EXPR_ARG, a, b, m, flag, prec)); } +intnuminitgen0(GEN a, GEN b, GEN code, long m, long flag, long prec) +{ EXPR_WRAP(code, intnuminitgen(EXPR_ARG, a, b, m, flag, prec)); } /* m and flag reversed on purpose */ GEN -intfuncinit0(entree *ep, GEN a, GEN b, GEN code, long flag, long m, long prec) -{ EXPR_WRAP(ep,code, intfuncinit(EXPR_ARG, a, b, m, flag? 1: 0, prec)); } +intfuncinit0(GEN a, GEN b, GEN code, long flag, long m, long prec) +{ EXPR_WRAP(code, intfuncinit(EXPR_ARG, a, b, m, flag? 1: 0, prec)); } #if 0 /* Two variable integration */ @@ -1701,20 +1701,13 @@ } GEN -intnumdoub0(entree *epx, GEN a, GEN b, entree *epy, int nc, int nd, int nf, GEN tabext, GEN tabint, long prec) +intnumdoub0(GEN a, GEN b, int nc, int nd, int nf, GEN tabext, GEN tabint, long prec) { - exprdat Ec, Ed; - exprdoub Ef; GEN z; - - Ec.ep = epx; Ec.ch = chc; - Ed.ep = epx; Ed.ch = chd; - Ef.epx = epx; push_val(epx, NULL); - Ef.epy = epy; push_val(epy, NULL); - Ef.ch = chf; - z = intnumdoub(&Ef, &gp_eval2, &Ec, &gp_eval, &Ed, &gp_eval, a, b, tabext, tabint, prec); - pop_val(epy); - pop_val(epx); return z; + push_lex(NULL); + push_lex(NULL); + z = intnumdoub(chf, &gp_eval2, chc, &gp_eval, chd, &gp_eval, a, b, tabext, tabint, prec); + pop_lex(); pop_lex(); return z; } #endif @@ -1816,8 +1809,8 @@ { return sumnumall(E,f,a,s,tab,flag,-1,prec); } GEN -sumnum0(entree *ep, GEN a, GEN sig, GEN code, GEN tab, long flag, long prec) -{ EXPR_WRAP(ep,code, sumnum(EXPR_ARG, a, sig, tab, flag, prec)); } +sumnum0(GEN a, GEN sig, GEN code, GEN tab, long flag, long prec) +{ EXPR_WRAP(code, sumnum(EXPR_ARG, a, sig, tab, flag, prec)); } GEN -sumnumalt0(entree *ep, GEN a, GEN sig, GEN code, GEN tab, long flag, long prec) -{ EXPR_WRAP(ep,code, sumnumalt(EXPR_ARG, a, sig, tab, flag, prec)); } +sumnumalt0(GEN a, GEN sig, GEN code, GEN tab, long flag, long prec) +{ EXPR_WRAP(code, sumnumalt(EXPR_ARG, a, sig, tab, flag, prec)); } Index: src/language/opcode.h =================================================================== RCS file: /home/cvs/pari/src/language/opcode.h,v retrieving revision 1.5 diff -u -r1.5 opcode.h --- src/language/opcode.h 15 Aug 2007 16:41:46 -0000 1.5 +++ src/language/opcode.h 21 Aug 2007 15:06:11 -0000 @@ -16,19 +16,20 @@ typedef enum {Gvoid, Gsmall, Gvec, Gvar, Ggen} Gtype; -typedef enum {OCpushlong='A',OCpushgen,OCpushreal,OCpushstoi, - OCpushvalue,OCpushvar, +typedef enum {OCpushlong='A',OCpushgen,OCpushreal,OCpushstoi,OCpushvar, OCpop, - OCstoi,OCitos,OCtostr,OCvarn,OCcopy, + OCstoi,OCitos,OCtostr,OCvarn,OCcopy,OCcopyifclone, OCprecreal,OCprecdl, OCvec,OCmat,OCcol, - OCstackgen,OCstore, + OCstackgen, OCcompo1,OCcompo2,OCcompoC,OCcompoL, - OCnewptr,OCpushptr,OCendptr,OCsimpleptr, + OCpushptr,OCendptr, OCcompo1ptr,OCcompo2ptr,OCcompoCptr,OCcompoLptr, OCcalllong,OCcallgen,OCcallgen2,OCcallint,OCcallvoid,OCcalluser, OCderivgen,OCderivuser, - OCdeffunc,OCgetarg,OCdefaultarg, - OCglobalvar} op_code; + OCdeffunc,OCnewframe, + OCpushdyn,OCstoredyn,OCnewptrdyn,OCsimpleptrdyn, + OCpushlex,OCstorelex,OCnewptrlex,OCsimpleptrlex, + OCgetarg,OCdefaultarg,OClocalvar,OClocalvar0,OCglobalvar} op_code; ENDEXTERN Index: src/language/sumiter.c =================================================================== RCS file: /home/cvs/pari/src/language/sumiter.c,v retrieving revision 1.122 diff -u -r1.122 sumiter.c --- src/language/sumiter.c 13 Aug 2007 11:30:46 -0000 1.122 +++ src/language/sumiter.c 21 Aug 2007 15:06:11 -0000 @@ -23,27 +23,24 @@ /********************************************************************/ void -forpari(entree *ep, GEN a, GEN b, GEN code) +forpari(GEN a, GEN b, GEN code) { - pari_sp av, av0 = avma, lim; + pari_sp av=avma, lim; - b = gcopy(b); av=avma; lim = stack_lim(av,1); - /* gcopy nedeed in case b gets overwritten in ch, as in - * b=10; for(a=1,b, print(a);b=1) - */ - push_val(ep, a); + lim = stack_lim(av,1); + push_lex(a); while (gcmp(a,b) <= 0) { closure_evalvoid(code); if (loop_break()) break; - a = (GEN) ep->value; a = typ(a) == t_INT? addis(a, 1): gadd(a,gen_1); + a = get_lex(-1); a = typ(a) == t_INT? addis(a, 1): gaddgs(a,1); if (low_stack(lim, stack_lim(av,1))) { if (DEBUGMEM>1) pari_warn(warnmem,"forpari"); a = gerepileupto(av,a); } - changevalue_p(ep,a); + set_lex(-1, a); } - pop_val(ep); avma = av0; + pop_lex(); avma = av; } void @@ -78,7 +75,7 @@ static int negcmp(GEN x, GEN y) { return gcmp(y,x); } void -forstep(entree *ep, GEN a, GEN b, GEN s, GEN code) +forstep(GEN a, GEN b, GEN s, GEN code) { long ss, i; pari_sp av, av0 = avma, lim; @@ -86,7 +83,7 @@ int (*cmp)(GEN,GEN); b = gcopy(b); av=avma; lim = stack_lim(av,1); - push_val(ep, a); + push_lex(a); if (is_vec_t(typ(s))) { v = s; s = gen_0; @@ -104,16 +101,16 @@ if (++i >= lg(v)) i = 1; s = gel(v,i); } - a = (GEN) ep->value; a = gadd(a,s); + a = get_lex(-1); a = gadd(a,s); if (low_stack(lim, stack_lim(av,1))) { if (DEBUGMEM>1) pari_warn(warnmem,"forstep"); a = gerepileupto(av,a); } - changevalue_p(ep,a); + set_lex(-1,a); } - pop_val(ep); avma = av0; + pop_lex(); avma = av0; } /* assume ptr is the address of a diffptr containing the succesive @@ -132,9 +129,9 @@ /* value changed during the loop, replace by the first prime whose value is strictly larger than new value */ static void -update_p(entree *ep, byteptr *ptr, ulong prime[]) +update_p(byteptr *ptr, ulong prime[]) { - GEN z = (GEN)ep->value; + GEN z = get_lex(-1); ulong a, c; if (typ(z) == t_INT) a = 1; else { z = gceil(z); a = 0; } @@ -147,7 +144,7 @@ *ptr = diffptr; prime[2] = sinitp(a, 0, ptr); } - changevalue_p(ep, (GEN)prime); + set_lex(-1,(GEN)prime); } static byteptr @@ -172,7 +169,7 @@ } void -forprime(entree *ep, GEN ga, GEN gb, GEN code) +forprime(GEN ga, GEN gb, GEN code) { long p[] = {evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 0}; ulong *prime = (ulong*)p; @@ -183,37 +180,37 @@ d = prime_loop_init(ga,gb, &a,&b, (ulong*)&prime[2]); if (!d) { avma = av; return; } - avma = av; push_val(ep, (GEN)prime); + avma = av; push_lex((GEN)prime); while (prime[2] < b) { closure_evalvoid(code); if (loop_break()) break; - if (ep->value == prime) + if (get_lex(-1) == (GEN) prime) NEXT_PRIME_VIADIFF(prime[2], d); else - update_p(ep, &d, prime); + update_p(&d, prime); avma = av; } /* if b = P --> *d = 0 now and the loop wouldn't end if it read 'while * (prime[2] <= b)' */ if (prime[2] == b) { closure_evalvoid(code); (void)loop_break(); avma = av; } - pop_val(ep); + pop_lex(); } void -fordiv(GEN a, entree *ep, GEN code) +fordiv(GEN a, GEN code) { long i, l; pari_sp av2, av = avma; GEN t = divisors(a); - push_val(ep, NULL); l=lg(t); av2 = avma; + push_lex(NULL); l=lg(t); av2 = avma; for (i=1; i<l; i++) { - ep->value = (void*) t[i]; + set_lex(-1,gel(t,i)); closure_evalvoid(code); if (loop_break()) break; avma = av2; } - pop_val(ep); avma=av; + pop_lex(); avma=av; } /* Embedded for loops: @@ -473,18 +470,18 @@ } void -forvec(entree *ep, GEN x, GEN code, long flag) +forvec(GEN x, GEN code, long flag) { pari_sp av = avma; GEN D; GEN (*next)(GEN,GEN); GEN v = forvec_start(x, flag, &D, &next); - push_val(ep, v); + push_lex(v); while (v) { closure_evalvoid(code); if (loop_break()) break; v = next(D, v); } - pop_val(ep); avma = av; + pop_lex(); avma = av; } /********************************************************************/ @@ -494,7 +491,7 @@ /********************************************************************/ GEN -somme(entree *ep, GEN a, GEN b, GEN code, GEN x) +somme(GEN a, GEN b, GEN code, GEN x) { pari_sp av, av0 = avma, lim; GEN p1; @@ -506,7 +503,7 @@ b = gfloor(b); a = setloop(a); av=avma; lim = stack_lim(av,1); - push_val(ep, a); + push_lex(a); for(;;) { p1 = closure_evalnobrk(code); @@ -517,9 +514,9 @@ if (DEBUGMEM>1) pari_warn(warnmem,"sum"); x = gerepileupto(av,x); } - ep->value = (void*) a; + set_lex(-1,a); } - pop_val(ep); return gerepileupto(av0,x); + pop_lex(); return gerepileupto(av0,x); } GEN @@ -549,23 +546,23 @@ return gerepileupto(av0, gaddgs(x,-1)); } GEN -suminf0(entree *ep, GEN a, GEN code, long prec) -{ EXPR_WRAP(ep,code, suminf(EXPR_ARG, a, prec)); } +suminf0(GEN a, GEN code, long prec) +{ EXPR_WRAP(code, suminf(EXPR_ARG, a, prec)); } GEN -divsum(GEN num, entree *ep, GEN code) +divsum(GEN num, GEN code) { pari_sp av = avma; GEN y = gen_0, t = divisors(num); long i, l = lg(t); - push_val(ep, NULL); + push_lex(NULL); for (i=1; i<l; i++) { - ep->value = (void*)t[i]; + set_lex(-1,gel(t,i)); y = gadd(y, closure_evalnobrk(code)); } - pop_val(ep); return gerepileupto(av,y); + pop_lex(); return gerepileupto(av,y); } /********************************************************************/ @@ -575,7 +572,7 @@ /********************************************************************/ GEN -produit(entree *ep, GEN a, GEN b, GEN code, GEN x) +produit(GEN a, GEN b, GEN code, GEN x) { pari_sp av, av0 = avma, lim; GEN p1; @@ -587,7 +584,7 @@ b = gfloor(b); a = setloop(a); av=avma; lim = stack_lim(av,1); - push_val(ep, a); + push_lex(a); for(;;) { p1 = closure_evalnobrk(code); @@ -598,9 +595,9 @@ if (DEBUGMEM>1) pari_warn(warnmem,"prod"); x = gerepileupto(av,x); } - ep->value = (void*) a; + set_lex(-1,a); } - pop_val(ep); return gerepileupto(av0,x); + pop_lex(); return gerepileupto(av0,x); } GEN @@ -654,12 +651,12 @@ return gerepilecopy(av0,x); } GEN -prodinf0(entree *ep, GEN a, GEN code, long flag, long prec) +prodinf0(GEN a, GEN code, long flag, long prec) { switch(flag) { - case 0: EXPR_WRAP(ep,code, prodinf (EXPR_ARG, a, prec)); - case 1: EXPR_WRAP(ep,code, prodinf1(EXPR_ARG, a, prec)); + case 0: EXPR_WRAP(code, prodinf (EXPR_ARG, a, prec)); + case 1: EXPR_WRAP(code, prodinf1(EXPR_ARG, a, prec)); } pari_err(flagerr); return NULL; /* not reached */ @@ -694,8 +691,8 @@ return gerepilecopy(av0,x); } GEN -prodeuler0(entree *ep, GEN a, GEN b, GEN code, long prec) -{ EXPR_WRAP(ep,code, prodeuler(EXPR_ARG, a, b, prec)); } +prodeuler0(GEN a, GEN b, GEN code, long prec) +{ EXPR_WRAP(code, prodeuler(EXPR_ARG, a, b, prec)); } GEN direuler(void *E, GEN (*eval)(GEN,void*), GEN ga, GEN gb, GEN c) @@ -786,8 +783,8 @@ return gerepilecopy(av0,x); } GEN -direuler0(entree *ep, GEN a, GEN b, GEN code, GEN c) -{ EXPR_WRAP(ep,code, direuler(EXPR_ARG, a, b, c)); } +direuler0(GEN a, GEN b, GEN code, GEN c) +{ EXPR_WRAP(code, direuler(EXPR_ARG, a, b, c)); } /********************************************************************/ /** **/ @@ -796,7 +793,7 @@ /********************************************************************/ GEN -vecteur(GEN nmax, entree *ep, GEN code) +vecteur(GEN nmax, GEN code) { GEN y,p1; long i,m; @@ -804,19 +801,19 @@ m = gtos(nmax); if (m < 0) pari_err(talker,"negative number of components in vector"); - if (!ep || !code) return zerovec(m); - y = cgetg(m+1,t_VEC); push_val(ep, c); + if (!code) return zerovec(m); + y = cgetg(m+1,t_VEC); push_lex(c); for (i=1; i<=m; i++) { c[2] = i; p1 = closure_evalnobrk(code); gel(y,i) = isonstack(p1)? p1 : gcopy(p1); - changevalue_p(ep,c); + set_lex(-1,c); } - pop_val(ep); return y; + pop_lex(); return y; } GEN -vecteursmall(GEN nmax, entree *ep, GEN code) +vecteursmall(GEN nmax, GEN code) { GEN y; long i,m; @@ -824,41 +821,40 @@ m = gtos(nmax); if (m < 0) pari_err(talker,"negative number of components in vector"); - if (!ep || !code) return const_vecsmall(m, 0); - y = cgetg(m+1,t_VECSMALL); push_val(ep, c); + if (!code) return const_vecsmall(m, 0); + y = cgetg(m+1,t_VECSMALL); push_lex(c); for (i=1; i<=m; i++) { c[2] = i; y[i] = gtos(closure_evalnobrk(code)); - changevalue_p(ep,c); + set_lex(-1,c); } - pop_val(ep); return y; + pop_lex(); return y; } GEN -vvecteur(GEN nmax, entree *ep, GEN n) +vvecteur(GEN nmax, GEN n) { - GEN y = vecteur(nmax,ep,n); + GEN y = vecteur(nmax,n); settyp(y,t_COL); return y; } GEN -matrice(GEN nlig, GEN ncol,entree *ep1, entree *ep2, GEN code) +matrice(GEN nlig, GEN ncol, GEN code) { GEN y, z, p1; long i, j, m, n; long c1[]={evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 1}; long c2[]={evaltyp(t_INT)|_evallg(3), evalsigne(1)|evallgefint(3), 1}; - if (ep1 == ep2 && ep1) pari_err(talker, "identical index variables in matrix"); m = gtos(ncol); n = gtos(nlig); if (m < 0) pari_err(talker,"negative number of columns in matrix"); if (n < 0) pari_err(talker,"negative number of rows in matrix"); if (!m) return cgetg(1,t_MAT); - if (!ep1 || !ep2 || !code || !n) return zeromatcopy(n, m); - push_val(ep1, c1); - push_val(ep2, c2); y = cgetg(m+1,t_MAT); + if (!code || !n) return zeromatcopy(n, m); + push_lex(c1); + push_lex(c2); y = cgetg(m+1,t_MAT); for (i=1; i<=m; i++) { c2[2] = i; z = cgetg(n+1,t_COL); gel(y,i) = z; @@ -866,12 +862,11 @@ { c1[2] = j; p1 = closure_evalnobrk(code); gel(z,j) = isonstack(p1)? p1 : gcopy(p1); - changevalue_p(ep1,c1); - changevalue_p(ep2,c2); + set_lex(-2,c1); + set_lex(-1,c2); } } - pop_val(ep2); - pop_val(ep1); return y; + pop_lex(); pop_lex(); return y; } /********************************************************************/ @@ -994,12 +989,12 @@ } GEN -sumalt0(entree *ep, GEN a, GEN code, long flag, long prec) +sumalt0(GEN a, GEN code, long flag, long prec) { switch(flag) { - case 0: EXPR_WRAP(ep,code, sumalt (EXPR_ARG,a,prec)); - case 1: EXPR_WRAP(ep,code, sumalt2(EXPR_ARG,a,prec)); + case 0: EXPR_WRAP(code, sumalt (EXPR_ARG,a,prec)); + case 1: EXPR_WRAP(code, sumalt2(EXPR_ARG,a,prec)); default: pari_err(flagerr); } return NULL; /* not reached */ @@ -1097,12 +1092,12 @@ } GEN -sumpos0(entree *ep, GEN a, GEN code, long flag, long prec) +sumpos0(GEN a, GEN code, long flag, long prec) { switch(flag) { - case 0: EXPR_WRAP(ep,code, sumpos (EXPR_ARG,a,prec)); - case 1: EXPR_WRAP(ep,code, sumpos2(EXPR_ARG,a,prec)); + case 0: EXPR_WRAP(code, sumpos (EXPR_ARG,a,prec)); + case 1: EXPR_WRAP(code, sumpos2(EXPR_ARG,a,prec)); default: pari_err(flagerr); } return NULL; /* not reached */ @@ -1181,8 +1176,8 @@ } GEN -zbrent0(entree *ep, GEN a, GEN b, GEN code, long prec) -{ EXPR_WRAP(ep,code, zbrent(EXPR_ARG, a,b, prec)); } +zbrent0(GEN a, GEN b, GEN code, long prec) +{ EXPR_WRAP(code, zbrent(EXPR_ARG, a,b, prec)); } /* x = solve_start(&D, a, b, prec) * while (x) { @@ -1227,8 +1222,8 @@ } GEN -derivnum0(entree *ep, GEN a, GEN code, long prec) +derivnum0(GEN a, GEN code, long prec) { - EXPR_WRAP(ep,code, derivnum (EXPR_ARG,a,prec)); + EXPR_WRAP(code, derivnum (EXPR_ARG,a,prec)); } Index: src/modules/elldata.c =================================================================== RCS file: /home/cvs/pari/src/modules/elldata.c,v retrieving revision 1.18 diff -u -r1.18 elldata.c --- src/modules/elldata.c 13 Apr 2007 23:42:48 -0000 1.18 +++ src/modules/elldata.c 21 Aug 2007 15:06:11 -0000 @@ -239,12 +239,12 @@ } void -forell(entree *ep, long a, long b, GEN code) +forell(long a, long b, GEN code) { long ca=a/1000, cb=b/1000; long i, j, k; - push_val(ep, NULL); + push_lex(NULL); for(i=ca; i<=cb; i++) { pari_sp ltop=avma; @@ -259,7 +259,7 @@ for(k=2; k<lg(ells); k++) { pari_sp av=avma; - ep->value = (void*)gel(ells, k); + set_lex(-1,gel(ells, k)); closure_evalvoid(code); avma=av; if (loop_break()) goto forell_end; @@ -268,5 +268,5 @@ avma = ltop; } forell_end: - pop_val(ep); + pop_lex(); } Index: src/test/32/program =================================================================== RCS file: /home/cvs/pari/src/test/32/program,v retrieving revision 1.23 diff -u -r1.23 program --- src/test/32/program 28 Mar 2007 22:40:42 -0000 1.23 +++ src/test/32/program 21 Aug 2007 15:06:11 -0000 @@ -134,7 +134,7 @@ 3 ? kill(addii) ? getheap -[24, 3169] +[23, 3164] ? print("Total time spent: ",gettime); -Total time spent: 560 +Total time spent: 36 ? \q Index: src/test/64/program =================================================================== RCS file: /home/cvs/pari/src/test/64/program,v retrieving revision 1.25 diff -u -r1.25 program --- src/test/64/program 28 Mar 2007 22:40:42 -0000 1.25 +++ src/test/64/program 21 Aug 2007 15:06:11 -0000 @@ -131,7 +131,7 @@ 3 ? kill(addii) ? getheap -[24, 1683] +[23, 1678] ? print("Total time spent: ",gettime); -Total time spent: 16 +Total time spent: 8 ? \q --- /dev/null 2007-08-04 13:06:12.080067500 +0200 +++ src/functions/programming/my 2007-05-12 14:00:42.000000000 +0200 @@ -0,0 +1,3 @@ +Function: my +Section: programming/specific +Help: my(x,...,z): declare x,...,z as lexically-scoped local variables