changeset 29:160e20394f80

macro function (imcomplete)
author kono
date Sat, 08 Feb 2003 04:14:23 +0900
parents c6994794f084
children 20ed2786a276
files Idea mc-parse.c mc.h
diffstat 3 files changed, 176 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/Idea	Sat Feb 08 00:58:04 2003 +0900
+++ b/Idea	Sat Feb 08 04:14:23 2003 +0900
@@ -1364,3 +1364,48 @@
 やっぱりmacro levelを見て、自分と一致したassoc valueまで
 手繰って置換するんでしょう。そうすれば、置き換える必要は無い。
 ということは、local_define にmflagsを格納する必要がある。
+
+   c(a,b) =>  a=>"a", b=>"b"
+        a=>"a" .. mflag == 1
+   g(a,b) =>  (a=>"a+1+1",a=>"a+1"), (b=>"b+1+1",a=>"a+1")
+        a=>"a+1" .. mflag == 2
+        
+macro のもとのnptr が残ってないと、オリジナルを返せない。オ
+リジナルは、sc などが破壊されてしまう。ってことは、local macro
+は、local table を汚してはいけないってことだよね。ってことは、
+macro table は、もとのとは別に用意する必要がある。
+
+#define c(a,b)  g(a+1,b+1)
+#define g(a,b)  printf("%d %d\n",a+2,b+2);
+
+main() {
+   int a,b;                  a ... local
+   a =1; b = 3;
+#ifndef a
+   c(a,                 a = "a".. macro mflag==1
+                        g(a,
+                               a="a+1"  mflag==2
+                                  ^  a = "a" mflag==1
+                        While replacing a in g's body, a should not
+                           be replaced to  (original) "a", should be c's a.
+      b);                
+   /* 3,5 expected */
+#endif
+}
+
+うーむ。ややこしい。
+
+    main() 
+	c(a,b)    mflag++
+                         a=>"a" mflag ==1
+           g(a,b) mflag++;
+                         a=>"a+1" mflag ==2
+                             ^ is replaced by c's "a" not g's a;
+いったん mflag level n で展開したら、それは mflag level n-1 となる。
+
+
+
+
+
+
+
--- a/mc-parse.c	Sat Feb 08 00:58:04 2003 +0900
+++ b/mc-parse.c	Sat Feb 08 04:14:23 2003 +0900
@@ -9,9 +9,10 @@
 static int decl_data(int t, NMTBL *n,int offset);
 static int alpha(char c);
 static int binop(int op, int e1, int e2, int t1, int t2);
-int caddr(int e);
-int cadr(int e);
-int car(int e);
+extern int cadddr(int e);
+extern int caddr(int e);
+extern int cadr(int e);
+extern int car(int e);
 static void compatible(int t1, int t2);
 static void decl(void);
 static void def(NMTBL *n);
@@ -89,7 +90,7 @@
 static void fmacro();
 static void local_define();
 static void local_undef();
-static void replace_macro();
+static int recursive_macro(char *);
 
 extern void display_ntable(NMTBL *n, char *s);
 extern void closing(void);
@@ -208,6 +209,7 @@
 	(n==CHERR) ? "Illegal character" :
 	(n==GSERR) ? "Too many global symbols" :
 	(n==LSERR) ? "Too many local symbols" :
+	(n==MSERR) ? "Too many macro symbols" :
 	(n==STRERR) ? "Too many strings or macros" :
 	(n==LNERR) ? "Line too long" :
 	(n==EOFERR) ? "Unexpected end of file" :
@@ -232,7 +234,11 @@
 
     if(lineno==0) return;
     fprintf(stderr,"%s",linebuf);
-    lim=(mflag?chptrsave:chptr);
+    lim=chptr;
+    while (chptrsave) {
+	lim = (char *)car(chptrsave);
+	chptrsave = cadr(chptrsave);
+    }
     for (p=linebuf; p < lim;)
 	    fprintf(stderr,(*p++ == '\t') ? "\t" : " ");
     fprintf (stderr,"^\n");
@@ -332,7 +338,7 @@
     (nptr = gsearch())->sc = RESERVE;
     if (d==0) {
 	nptr->sc = MACRO;
-	nptr->dsp = (int)"1";
+	nptr->dsp = (int)""; nptr->ty=0;
     } else {
 	nptr->dsp = d;
     }
@@ -1797,7 +1803,6 @@
 	    break;
 	case FMACRO:
 	    fmacro();
-	    ch = *chptr;
 	    getsym();
 	    break;
 	case FLABEL: case BLABEL:
@@ -2184,9 +2189,9 @@
 int
 getsym(void)
 {
-    NMTBL *nptr0,*nptr1;
+    NMTBL *nptr0,*nptr1,*nptrm;
     int i;
-    char c;
+    char c,*macro;
 
     if (alpha(skipspc())) {	
 	i = hash = 0;
@@ -2197,23 +2202,43 @@
 	    getch();
 	}
 	name[i++] = '\0'; 
-	nptr0 = gsearch();
-	if (nptr0->sc == MACRO && !mflag) {	
-	    if (mode==IFDEF) {
+
+	nptrm=msearch(name);
+	if (mode==MDECL) {
+	    nptr = nptrm;
+	    return (sym==MACRO);
+	}
+	if (mode==IFDEF) {
+	    if (nptrm->sc == MACRO||nptrm->sc==FMACRO) {	
 		return (symval=1);
+	    } else {
+		return (symval=0);
 	    }
-	    mflag++;
-	    chsave = ch;
-	    chptrsave = chptr;
-	    chptr = (char *)nptr0->dsp;
+	}
+	if (nptrm->sc!=EMPTY && !recursive_macro((char *)(nptrm->dsp))) {
+	    if (nptrm->sc == FMACRO) {
+		nptr = nptrm;
+		sym = IDENT;
+		return sym;
+	    }
+	    macro = (char *)(car(nptrm->dsp));
+	    i = nptrm->ty;
+	    while (!(cadddr(i)==0||cadddr(i)==mflag)) {
+		macro = (char *)car(cadr(i));
+		i = caddr(i);
+	    }
+	    chptrsave = list4((int)chptr,chptrsave,ch,
+		list2((int)nptrm,(int)macro));
+	    if (cadddr(i)) {
+		mflag--;
+	    }
+	    chptr = macro;
 	    getch();
 	    return getsym();
 	}
-	if (mode==IFDEF) {
-	    return (symval=0);
-	}
+
+	nptr0 = gsearch();
 	if (nptr0->sc == RESERVE) return sym = nptr0->dsp;
-
 	sym = IDENT;
 	gnptr=nptr=nptr0;
 	if (mode==ADECL && nptr0->sc ==TYPE) return sym;
@@ -2224,7 +2249,6 @@
 	nptr1=lsearch(nptr0->nm);
 	if (mode==STAT) {
 	    if (nptr1->sc == EMPTY) return sym;
-	    else { nptr=nptr1; return sym;}
 	}
 	nptr=nptr1;
 	return sym;
@@ -2398,6 +2422,26 @@
     return nptr;
 }
 
+NMTBL *
+msearch(char *name)
+{
+    NMTBL *nptr,*iptr;
+
+    iptr=nptr= &mtable[hash%MSYMS];
+    while(nptr->sc!=0 && neqname(nptr->nm)) {	
+	if (++nptr== &mtable[MSYMS]) 
+	    nptr= &ntable[0];
+	if (nptr==iptr) error(MSERR);
+    }
+    if (nptr->sc == 0) {
+	copy(nptr,name);
+	nptr->sc=EMPTY;
+	nptr->dsp=0;
+	nptr->ty=0;
+    }
+    return nptr;
+}
+
 void
 copy(NMTBL *nptr, char *s)
 {
@@ -2445,9 +2489,24 @@
 int
 getch(void)
 {
+    NMTBL *nptr0;
+    int sargs;
     if(*chptr) return ch= *chptr++;
-    if(mflag) {
-	mflag=0;chptr=chptrsave;return ch=chsave;
+
+    if(chptrsave) {
+	nptr0=(NMTBL *)car(cadddr(chptrsave));
+	if (nptr0->sc==FMACRO) {
+	    sargs = cadr(nptr0->dsp);
+	    while(sargs) {
+		local_undef(car(sargs));
+		sargs = cadr(sargs);
+	    }
+	}
+	mflag--;
+	chptr=(char *)car(chptrsave);
+	ch=caddr(chptrsave);
+	chptrsave=cadr(chptrsave);
+	return ch;
     }
     getline();
     return getch();
@@ -2599,17 +2658,18 @@
     if (macro_if_skip) return;
     if (macroeq("define")) {	
 	i=mode;
-	mode=GDECL;
+	mode=MDECL;
 	ch= *chptr;
-	if (getsym() == IDENT) {	
-	    if (nptr->sc != EMPTY) { error(MCERR);
-	    } else if (ch=='(') {
-		nptr->sc = FMACRO;
-		args = macro_args();
-		nptr->dsp = glist2((int)cheapp,args);
-		while ((*cheapp++ = c = *chptr++)
-		    && c != '\n');
-		*cheapp++ = '\0';
+	getsym();
+	if (nptr->sc != EMPTY) { /* override exisiting macro */
+	}
+	if (ch=='(') {
+	    nptr->sc = FMACRO;
+	    args = macro_args();
+	    nptr->dsp = glist2((int)cheapp,args);
+	    while ((*cheapp++ = c = *chptr++)
+		&& c != '\n');
+	    *cheapp++ = '\0';
 #if 0
 fprintf(stderr,"macro function: %s\n",nptr->nm);
 i = 0;
@@ -2619,16 +2679,15 @@
 }
 fprintf(stderr,"macro body: %s\n",(char *)car(nptr->dsp));
 #endif
-	    } else {
-		nptr->sc = MACRO;
-		nptr->dsp = (int)cheapp;
-		while ((*cheapp++ = c = *chptr++)
-		    && c != '\n');
-		*cheapp++ = '\0';
-	    }
-	    if (cheapp >= cheap+CHEAPSIZE) /* too late? */
-		error(STRERR);
-	} else error(MCERR);
+	} else {
+	    nptr->sc = MACRO;
+	    nptr->dsp = glist2((int)cheapp,0);
+	    while ((*cheapp++ = c = *chptr++)
+		&& c != '\n');
+	    *cheapp++ = '\0';
+	}
+	if (cheapp >= cheap+CHEAPSIZE) /* too late? */
+	    error(STRERR);
 	mode=i;
 	*(chptr = linebuf) = '\0';
     } else if (macroeq("undef")) {	
@@ -2638,8 +2697,9 @@
 	if (getsym() == IDENT) {	
 	    if (nptr->sc == MACRO) {	
 	        nptr->sc = EMPTY;
-	    } else if (nptr->sc == LMACRO) {	
+	    } else if (nptr->sc == FMACRO) {	
 	        nptr->sc = EMPTY;
+		/* we cannot reclaim it's arg */
 	    } else error(MCERR);
 	}
 	mode=i;
@@ -2744,7 +2804,7 @@
 void 
 fmacro()
 {
-    int args,sargs,values;
+    int args,values;
 #if 0
 int i;
 fprintf(stderr,"linebuf: %s\n",linebuf);
@@ -2763,38 +2823,39 @@
 args = cadr(args);
 }
 #endif
-    args = sargs = cadr(nptr->dsp);
+    args = cadr(nptr->dsp);
     values = macro_args();
+    mflag++;
     while(args) {
 	local_define(car(args),car(values));
 	args = cadr(args);
 	values = cadr(values);
     }
-    mflag++;
-    replace_macro();
-    chsave = ch;
-    chptrsave = chptr;
-    chptr = cheapp;
-    while(sargs) {
-	local_undef(car(sargs));
-	sargs = cadr(sargs);
-    }
+    chptrsave = list4((int)chptr,chptrsave,ch,list2((int)nptr,nptr->dsp));
+    chptr = (char *)nptr->dsp;
     getch();
 }
 
-void
-replace_macro()
+int
+recursive_macro(char *macro)
 {
+    int save = chptrsave;
+    while(save) {
+        if (cadr(cadddr(save))==(int)macro) 
+	    return 1;
+	save = cadr(chptrsave);
+    }
+    return 0;
 }
 
 void
 local_define(char *macro,char *value)
 {
     NMTBL *nptr0;
-    nptr0 = lsearch(macro);
-    nptr0->sc=LMACRO; 
-    nptr0->ty=list3(nptr0->sc,nptr0->dsp,nptr0->ty); 
-    nptr0->dsp=(int)value; 
+    nptr0 = msearch(macro);
+    nptr0->ty=list4(nptr0->sc,nptr0->dsp,nptr0->ty,mflag); 
+    nptr0->sc=MACRO; 
+    nptr0->dsp=list2((int)value,0); 
 }
 
 void
@@ -2802,7 +2863,7 @@
 {
     NMTBL *nptr0;
     int save;
-    nptr0 = lsearch(macro);
+    nptr0 = msearch(macro);
     save = nptr0->ty;
     nptr0->sc=car(save); 
     nptr0->dsp=cadr(save); 
--- a/mc.h	Sat Feb 08 00:58:04 2003 +0900
+++ b/mc.h	Sat Feb 08 04:14:23 2003 +0900
@@ -70,6 +70,7 @@
 #define GTDECL	10
 #define LTDECL	11
 #define IFDEF	12
+#define MDECL	13
 
 #define GVAR	1
 #define RGVAR	2
@@ -164,9 +165,11 @@
 #define OPTION	18
 #define REG_ERR	19
 #define CODE_ERR	20
+#define MSERR   21
 
 #define GSYMS	9000
 #define LSYMS	500
+#define MSYMS	500
 
 #define HEAPSIZE	10000
 /* #define CHEAPSIZE	3000 */
@@ -176,7 +179,7 @@
 #define FILES 10
 #define OUTPUT_FILE_NAME "mcout.s"
 
-EXTERN int sym,ch,chsave,type,mode,stmode,gfree,lfree,mflag,lineno,glineno;
+EXTERN int sym,ch,type,mode,stmode,gfree,lfree,mflag,lineno,glineno;
 EXTERN int labelno,gpc,disp,reg_var,debug;
 EXTERN int symval,args,init_vars,heap[HEAPSIZE];
 EXTERN int blabel,clabel,dlabel,cslabel,ilabel,control,ac,ac2,lsrc,chk,asmf;
@@ -184,7 +187,8 @@
 
 EXTERN unsigned hash;
 
-EXTERN char linebuf[LBUFSIZE],namebuf[LBUFSIZE],*chptr,*chptrsave;
+EXTERN int chptrsave;
+EXTERN char linebuf[LBUFSIZE],namebuf[LBUFSIZE],*chptr;
 EXTERN char *name,*cheapp,**av,/*obuf[320],*/*sptr,escape(void);
 EXTERN int arg_offset,stat_no,size_of_int,disp_offset,endian,csvalue,csvalue1;
 EXTERN int code_arg_offset;
@@ -197,9 +201,11 @@
 	int sc,ty,dsp; } NMTBL;
 
 EXTERN NMTBL ntable[GSYMS+LSYMS];
+EXTERN NMTBL mtable[MSYMS];
 EXTERN NMTBL *nptr,*gnptr;
 EXTERN NMTBL *decl0(void),*decl1(void),*lsearch(char *name),*gsearch(void);
 EXTERN NMTBL *fnptr;
+EXTERN NMTBL *msearch(char *name);
 
 EXTERN struct {int fd,ln;char *name0;FILE *fcb;} *filep,filestack[FILES];
 EXTERN char cheap[CHEAPSIZE];