changeset 346:969089695850

name reconfigure.... continue...
author kono
date Tue, 29 Jun 2004 23:11:47 +0900
parents 2b3946ee4fc9
children cef4d8eb9a26
files Changes conv/c.c mc-code-mips.c mc-macro.c mc-parse.c mc-parse.h mc.h
diffstat 7 files changed, 619 insertions(+), 348 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Jun 27 20:31:46 2004 +0900
+++ b/Changes	Tue Jun 29 23:11:47 2004 +0900
@@ -5272,3 +5272,78 @@
       |--------------||---|
 
 みたいな感じだね。
+
+Sun Jun 27 21:06:28 JST 2004
+
+やっぱり、name/namebuf 関連は書き換えるんでしょ?
+
+まず、get_name/get_string  は、cheap 上にコピーする。
+で、new_def でなかった時には cheap を元に戻す。
+name, namebuf は、なくす。
+
+  string hash (oblist) ->  hash table ->
+    nptr -> macro/reserve/local/global/typedef etc
+
+となる。local nptr は、local_scope list に登録し、
+scope を抜けるときに消す。
+
+get_name/string でt既に登録してしまう。gserach/lsearch/msearch
+は、登録されたhash からのlinked list で良い。gsearch も linked
+list にする必要がある。nptr には、next をつける?
+
+あぁ、ARM には fpp はないのね。いや、GBAにはないけど、
+Zaurus にはあるっていうパターン?!
+
+ってことは... MIPS と PowerPC を足して二で割ったような実装
+をしないといけないのか。うーむ。
+
+macrobuf は、cheap で共有できるはず。そうすれば、linebuf 以外は
+一つになる。linebuf も一緒にできるかな? それは、無理なんだけど...
+cheap なんだけど、extendable にするためには...
+
+     struct cheap {
+         char *cheap;
+         char *last;
+	 struct cheap *next;
+     }
+
+として、これへのポインタをcheapとして用いれば良い。cheapp とかが
+あるので、やっかいだが..
+
+Mon Jun 28 20:18:03 JST 2004
+
+あのさ、それをやっちゃうと、chptr も cheap を参照するんだから、
+そっちも、直さないとだめじゃん。
+
+いや、それはない。mappend で、必ず cheap chunk に収まるはず
+だから。結構、無駄が出る可能性もあるけど、別にいいんじゃない?
+巨大に展開した macro の最後の方だけ cheap からはみでるとか。
+だからどうなの? 2M とかに展開されるわけでもないだろ?
+
+mappend で chunk boundary にかかると copy で append を
+壊してしまう。どうせ、cheap rest してから、chptr を
+切替えるんだからいいんだけどさ。
+
+Tue Jun 29 17:36:36 JST 2004
+
+  #define car(a) heap[a]
+だけど...
+       typedef struct tree {
+          int id;
+          int next;
+       } TREE;
+として、
+   #define as_tree(a) (TREE)(heap[a])
+	  TREE t = tree(a);
+	  if (t.id == HOGE) {....
+っていうようにアクセスする手はあるよね。
+   #define tree(a) ((TREE)(heap[a]))
+	  if (tree(a).id == HOGE) {....
+でもいいか。
+
+conservative に変えたいのか、drastic に変えたいのか
+どっちだよ。
+
+
+name space は、tag, macro, その他? typename は重なっていてはいけない。
+field も別だけど。sc で区別するわけだけど...
--- a/conv/c.c	Sun Jun 27 20:31:46 2004 +0900
+++ b/conv/c.c	Tue Jun 29 23:11:47 2004 +0900
@@ -24,14 +24,8 @@
 static void
 open_(char *s)
 {
-    char *p=cheapp;
-    while ((*cheapp++ = *s++)) {
-	if (*s=='.') {
-	    *cheapp++=*s++; *cheapp++='c';
-	    *cheapp++='c'; *cheapp++=0;
-	    break;
-	}
-    }
+    char *p;
+    p = make_filename_with_extension(s,".cc");
 #if 1
     vout = fopen(p,"w");
 #else
--- a/mc-code-mips.c	Sun Jun 27 20:31:46 2004 +0900
+++ b/mc-code-mips.c	Tue Jun 29 23:11:47 2004 +0900
@@ -2718,10 +2718,8 @@
 code_opening(char *filename)
 {
     static int count=0;
+    char *asi_name;
     /* this is called once per file */
-    char *p=cheapp;
-    char *s,*t;
-
     printf("\t.file %d \"%s\"\n",count++,filename);
     printf(".abicalls\n");
     printf(".text\n");
@@ -2730,24 +2728,10 @@
         fclose(asi);
         asi = 0;
     }
-    for (t=0,s=filename;(*cheapp++ = *s++);) {
-        if (*s=='.') {
-	    t=cheapp;
-        }
-    }
-    if (!t) {
-	cheapp--;
-	*cheapp++ = '.';
-	*cheapp++ = 'i';
-	*cheapp++ = 0;
-    } else {
-	t[1]='i'; 
-	t[2]=0; 
-    }
-    asi = fopen(p,"w");
-    cheapp = p;
-    printf(".include \"%s\"\n",p);
+    asi_name = make_filename_with_extension(filename,"i");
+    if ( (asi = fopen(asi_name,"w")) == NULL ) error(FILERR);
     if (!asi) error(-1);
+    printf(".include \"%s\"\n",asi_name);
 }
 
 // should have pcond_const
--- a/mc-macro.c	Sun Jun 27 20:31:46 2004 +0900
+++ b/mc-macro.c	Tue Jun 29 23:11:47 2004 +0900
@@ -11,16 +11,15 @@
 int in_macro_if = 0;
 char *chinput;
 
-static char *macropp,macro_buf[MACROSIZE];
 static int mconcat=0;
 
 static void macro_define0();
-static int macro_args(char **pcheapp,char *maxcheap,char **pchptr);
+static int macro_args(char **pchptr);
 static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history);
 static void local_define(char *macro,char *value);
 static void local_undef(char *macro);
 static int macro_eval(int macrop,char *body0,int history);
-static char * mappend(int lists);
+static char * mappend(int lists,char **result);
 static int macro_processing();
 
 static void
@@ -35,41 +34,41 @@
     int i = mode;
     int macrop = 0;
     int slfree = lfree;
+    char *macropp;
+    struct cheap scheap;
     mode = STAT;
 
-    macropp = macro_buf;
+    save_cheap(&scheap,cheap);
+
     if (nptrm->sc == FMACRO) {
         macrop=macro_function(macrop,&chptr,nptrm,0);
     } else {
         macrop=macro_eval(macrop,(char *)car(nptrm->dsp),0);
     }
-    macropp = macro_buf;
-    mappend(reverse0(macrop));
-    macropp[-1] ='\n';
-    *macropp =0;
+    macropp = cheap->ptr;
+    // we can't reset cheap
+    mappend(reverse0(macrop),&macropp);
+    cheap->ptr[-1] ='\n';
+    cheap->ptr[0] =0;
     while (mconcat) {
         // ## re-eval macro
-        printf("## %s",macro_buf);
+        printf("## %s",macropp);
         mconcat = 0;
         macrop = 0;
-        macropp = macro_buf;
-        macrop=macro_eval(macrop,macro_buf,0);
-        macropp = macro_buf;
-        mappend(reverse0(macrop));
-        macropp[-1] ='\n';
-        *macropp =0;
+        macrop=macro_eval(macrop,macropp,0);
+	macropp = cheap->ptr;
+	// will override evaled list
+        mappend(reverse0(macrop),&macropp);
+	cheap->ptr[-1] ='\n';
+	cheap->ptr[0] =0;
     }
+    cheap = reset_cheap(&scheap);
     mconcat = 0;
     lfree = slfree;
-    if (lsrc && !asmf && nptrm->sc==FMACRO) gen_comment(macro_buf);
-    macropp[-1] =0;
-    if (macro_buf[0]==0) {
-        mode = i;
-        return;
-    }
+    if (lsrc && !asmf && nptrm->sc==FMACRO) gen_comment(macropp);
     chptrsave = glist2((int)chptr,chptrsave);
     chsave = glist2(ch,chsave);
-    chptr = macro_buf;
+    chptr = macropp;
     ch = *chptr++;
     mode = i;
 }
@@ -77,17 +76,16 @@
 /* file inclusion */
 
 static char *
-expand_file_name(char *path,char *name,int pos,int lbufsize)
+expand_file_name(char *path,char *name)
 {
-    char *p = name+pos;
-    int i,j;
-    j = 0;
-    for(i=0;path[i];i++,j++); for(i=0;name[i];i++,j++);
-    if (pos+j+1>lbufsize) { error(FILERR); return ""; }
-    while((name[pos++] = *path++));
-    pos--;
-    if (name[pos]!='/') name[pos]='/';
-    for(i = 0; ((name[pos++] = name[i++])););
+    char *p = cheap->ptr;
+    if (! *path) return name;
+    while(( *cheap->ptr = *path++ )) cheap = increment_cheap(cheap,&p);
+    if (cheap->ptr[-1]!='/') {
+	*cheap->ptr = '/'; cheap = increment_cheap(cheap,&p);
+    }
+    while(( *cheap->ptr = *name++ )) cheap = increment_cheap(cheap,&p);
+    cheap->ptr = 0;
     return p;
 }
 
@@ -95,8 +93,13 @@
 getfname(void)
 {
     int i,end='"',err=0;
-    char *s,*p,**pp,name[LBUFSIZE];
+    char *s,*p,**pp,*name;
     FILE *fp;
+    struct cheap scheap;
+    struct cheap scheap1;
+    save_cheap(&scheap,cheap);
+    name = cheap->ptr;
+    
 
     getch();
     if(skipspc()=='"') { end = '"';
@@ -104,26 +107,34 @@
     } else { error(INCERR); err=1; 
     }
     for(i=0;(getch()!=end && ch!='\n');) {
-	if(i<LBUFSIZE-1) name[i++]=ch;
+	*cheap->ptr = ch;
+	cheap = increment_cheap(cheap,&name);
     }
     if(ch=='\n') error(INCERR);
     if (err) return filep->fcb;
-    name[i]=0;
+    cheap->ptr = 0;
     fp = fopen(name,"r") ;
     if (fp) {
 	p = name; 
     } else {
-	for(pp=(end=='>'||filep->inc=='>')
-		?l_include_path:include_path;*pp;pp++) {
-	    p = expand_file_name(*pp,name,i+1,LBUFSIZE);
+	save_cheap(&scheap1,cheap);
+	for(pp=(end=='>'||filep->inc=='>') ?l_include_path:include_path;
+		*pp;pp++) {
+	    cheap = reset_cheap(&scheap1);
+	    p = expand_file_name(*pp,name);
 	    if ((fp = fopen(p,"r"))) break ;
 	}
     }
     if(!fp) { error(FILERR); return filep->fcb; }
     copy_current_file_dir(s=p);
-    (filep+1)->name0 = cheapp;
+    if (p!=name) {
+	//  File name determined. Dispose extra copies.
+	cheap = reset_cheap(&scheap);
+	name = cheap->ptr;
+	while((*cheap->ptr = *s++)) cheap = increment_cheap(cheap,&name);
+    }
     (filep+1)->inc = end;
-    while((*cheapp++ = *s++));
+    (filep+1)->name0 = name;
     return ( (filep+1)->fcb = fp );
 }
 
@@ -216,6 +227,7 @@
 check_macro_eof()
 {
     int c;
+    // can't be in macro expansion
     for(c=0;c<LBUFSIZE-3&&chptr[c];c++);
     if (c>0&&chptr[c-1]=='\\') {
 	return;
@@ -394,7 +406,7 @@
 macro_define0()
 {
     int i,args,c;
-    char *scheapp;
+    char **body;
 
     i=mode;
     mode=MDECL;
@@ -407,7 +419,7 @@
     args = 0;
     if (ch=='(') {
 	nptr->sc = FMACRO;
-	args = macro_args(&cheapp,cheap+CHEAPSIZE,&chptr);
+	args = macro_args(&chptr);
     } else {
 	nptr->sc = MACRO;
 	nptr->ty = -1;
@@ -415,14 +427,15 @@
     // equal is allowed for -Dhoge=aho option
     if (ch=='=') chptr++;
     while((c=*chptr)==' '||c=='\t') chptr++;
-    nptr->dsp = list2((int)cheapp,args); /* macro body */
-    scheapp = cheapp;
-    while ((*cheapp++ = c = *chptr++)
+    nptr->dsp = list2((int)cheap->ptr,args); /* macro body */
+    body = (char **)&car(nptr->dsp);
+    while ((*cheap->ptr = c = *chptr++)
 	&& c != '\n') {
+	cheap = increment_cheap(cheap,body);
 	if (c=='/'&&chptr[0]=='/') {
-	    cheapp--; while(*chptr++); break;
+	    cheap->ptr--; while(*chptr++); break;
 	} else if (c=='/'&&chptr[0]=='*') {
-	    cheapp--; chptr++;
+	    cheap->ptr--; chptr++;
 	    while((c = *chptr++)) {
 		if (c=='*'&&chptr[0]=='/') {
 		    c = *chptr++; break;
@@ -431,15 +444,15 @@
 	    if (!c) break;
 	} else if (c=='\\' && (*chptr=='\n'||*chptr==0)) {
 	    chptr++;
-	    cheapp--;
+	    cheap->ptr--;
 	    getline();
 	}
     }
-    *cheapp++ = '\0';
-    while(cheapp>scheapp&&(*cheapp=='\n'||*cheapp==0)) cheapp--;
-    *++cheapp = '\0'; cheapp++;
-    if (cheapp >= cheap+CHEAPSIZE) /* too late? */
-	error(STRERR);
+    if (c=='\n') {
+	cheap->ptr--;
+	*cheap->ptr = '\0';
+    }
+    cheap = increment_cheap(cheap,body);
 // fprintf(stderr,"%s\n",(char *)car(nptr->dsp));
     mode=i;
 }
@@ -448,29 +461,30 @@
 //    return  list2((char*)arg,next)
 
 static int
-macro_args(char **pcheapp,char *maxcheap,char **pchptr)
+macro_args(char **pchptr)
 {
     int c;
     int in_quote = 0;
     int in_wquote = 0;
     int plevel = 0;
-    char *cheapp = *pcheapp;
+    char **body;
     char *chptr = *pchptr;
-    int args = list2((int)cheapp,0);
+    int args = list2((int)cheap->ptr,0);
+    body = (char **)&car(args);
     for(;;) {
-        *cheapp++ = c = *chptr++;
-	if (cheapp >= maxcheap) error(MCERR);
+        *cheap->ptr = c = *chptr++;
+	cheap = increment_cheap(cheap,body);
 	if (!c)  {
 	    chptr--;
 	    error(MCERR);
 	    *pchptr = chptr;
-	    *pcheapp = cheapp;
 	    return reverse0(args);
 	}
 	if (in_quote) {
 	    if (c=='\\') {
 		if (*chptr != '\n') {
-		    *cheapp++ = *chptr++;
+		    *cheap->ptr = *chptr++;
+		    cheap = increment_cheap(cheap,body);
 		} else {
 		    getline();
 		}
@@ -480,9 +494,10 @@
 	} else if (in_wquote) {
 	    if (c=='\\') {
 		if (*chptr !='\n') {
-		    *cheapp++ = *chptr++;
+		    *cheap->ptr = *chptr++;
+		    cheap = increment_cheap(cheap,body);
 		} else {
-		    *cheapp = '\n';
+		    *cheap->ptr = '\n';
 		    getline();
 		}
 	    } else if (c=='"') {
@@ -494,22 +509,23 @@
 	    in_quote = 1;
 	} if (plevel==0) {
 	    if (c==',') {
-		cheapp[-1] = 0;
-		args = list2((int)cheapp,args);
+		cheap->ptr[-1] = 0;
+		args = list2((int)cheap->ptr,args);
+		body = (char **)&car(args);
 	    } else if (c==')') {
-		cheapp[-1] = 0;
+		cheap->ptr[-1] = 0;
 		break;
 	    } else if (c=='(') {
 		plevel++;
 	    } else if (c=='\\') {
 		if (*chptr=='\n') {
-		    cheapp--;
+		    cheap->ptr--;
 		    getline();
 		}
 //	    } else if (c==' '||c=='\t') {
-//		cheapp--;
+//		cheap->ptr--;
 	    } else if (c=='\n') {
-		cheapp--;
+		cheap->ptr--;
 		getline();
 		chptr = *pchptr;
 	    }
@@ -518,13 +534,12 @@
 	} else if (c=='(') {
 	    plevel++;
 	} else if (c=='\n') {
-	    cheapp--;
+	    cheap->ptr--;
 	    getline();
 	    chptr = *pchptr;
 	}
     }
     *pchptr = chptr;
-    *pcheapp = cheapp;
     return reverse0(args);
 }
 
@@ -537,7 +552,7 @@
     char *macro;
 
     sargs = args = cadr(nptr->dsp);
-    values = macro_args(&macropp,macro_buf+MACROSIZE,pchptr);
+    values = macro_args(pchptr);
     if (pchptr==&chptr) {
 	ch = *chptr++;
     }
@@ -548,7 +563,8 @@
     }
     evalues = reverse0(evalues);
     while(args) {
-	local_define((char *)car(args),mappend(reverse0(car(evalues))));
+	mappend(reverse0(car(evalues)),&macro);
+	local_define((char *)car(args),macro);
 /* fprintf(stderr,"%s: %s => %s\n",nptr->nm,(char *)car(args),(char *)car(msearch0((char *)car(args))->dsp)); */
 	args = cadr(args);
 	evalues = cadr(evalues);
@@ -597,20 +613,22 @@
     int in_wquote = 0;
     char *macro;
     char *body = body0;
-    int i;
+    char **expand;
     NMTBL *nptrm;
-    macrop = list2((int)macropp,macrop);
+    macrop = list2((int)cheap->ptr,macrop);
+    expand = (char **)&car(macrop);
     for(; (c = *body++) ;) {
-	if (macropp+1>macro_buf+MACROSIZE) error(STRERR);
 	if (in_quote) {
 	    if (c=='\\') {
-		*macropp++ = c; c = *body++;
+		*cheap->ptr = c; c = *body++;
+		cheap = increment_cheap(cheap,expand);
 	    } else if (c=='\'') {
 		in_quote = 0;
 	    }
 	} else if (in_wquote) {
 	    if (c=='\\') {
-		*macropp++ = c; c = *body++;
+		*cheap->ptr = c; c = *body++;
+		cheap = increment_cheap(cheap,expand);
 	    } else if (c=='"') {
 		in_wquote = 0;
 	    }
@@ -622,58 +640,70 @@
 	    // name concatenation. skip ## and re-eval macro line.
 	    mconcat = 1; body++; continue;
 	} else if (alpha(c)) {
-	    i = 0;
-	    do { namebuf[i++] = c; c=*body++;} while (alpha(c)||digit(c));
-	    body--; // ungetc
-	    namebuf[i]=0;
-	    nptrm = msearch0(namebuf);
+	    char *schptr;
+	    schptr = chptr; chptr = body;
+	    get_name();
+	    chptr--; // ungetc
+	    body = chptr; chptr = schptr;
+	    nptrm = msearch0(hptr);
 	    macro = (char *)car(nptrm->dsp);
 	    if (nptrm->sc==LMACRO) {
-		while((*macropp++ = *macro++));
-		macropp--;
-	    } else if (nptrm->sc==MACRO && neqname(namebuf,macro)) {
+		while((*cheap->ptr = *macro++))
+		    cheap = increment_cheap(cheap,expand);
+		cheap->ptr--;
+	    } else if (nptrm->sc==MACRO && neqname(nptrm->nm,macro)) {
 		if (macro[0]==0)  continue;
-		*macropp++=0;
+		*cheap->ptr = 0;
+		cheap = increment_cheap(cheap,expand);
                 macrop=macro_eval(macrop,macro,list2((int)macro,history));
-		macrop = list2((int)macropp,macrop);
+		macrop = list2((int)cheap->ptr,macrop);
+		expand = (char **)&(car(macrop));
 	    } else if (nptrm->sc==FMACRO) {
 		if (c==' '||c=='\t') {
 		    while (c==' '||c=='\t') c=*body++;
 		    body--;
 		}
 		if(c!='(') error(MCERR);
-		*macropp++=0; body++;
+		cheap = increment_cheap(cheap,expand);
+		body++;
 		macrop = macro_function(macrop,&body,nptrm,
 			list2((int)macro,history));
-		macrop = list2((int)macropp,macrop);
+		macrop = list2((int)cheap->ptr,macrop);
+		expand = (char **)&(car(macrop));
 	    } else {
-		macro = namebuf;
-		while((*macropp++ = *macro++));
-		macropp--;
+		macro = nptrm->nm;
+		while((*cheap->ptr = *macro++));
+		    cheap = increment_cheap(cheap,expand);
+		cheap->ptr--;
 	    }
 	    continue;
 	}
-	*macropp++ = c;
+	*cheap->ptr = c;
+	cheap = increment_cheap(cheap,expand);
     }
-    *macropp++=0;
+    *cheap->ptr = 0;
+    cheap = increment_cheap(cheap,expand);
     return macrop;
 }
 
 
 static char *
-mappend(int lists)
+mappend(int lists,char **result)
 {
     char *p;
-    char *result = macropp;
+    *result = cheap->ptr;
     while(lists) {
-        if (macropp>macro_buf+MACROSIZE) error(STRERR);
         p = (char *)car(lists);
-        while((*macropp++=*p++)) if (p[-1]=='\n') macropp[-1]=' ';
-        macropp--;
+        while((*cheap->ptr=*p++)) {
+	    // in_quote + \n case ? should be \n.
+	    if (p[-1]=='\n') cheap->ptr[-1]=' ';
+	    cheap = increment_cheap(cheap,result);
+	}
+        cheap->ptr--;
         lists = cadr(lists);
     }
-    macropp++;
-    return result;
+    cheap = increment_cheap(cheap,result);
+    return *result;
 }
 
 /* end */
--- a/mc-parse.c	Sun Jun 27 20:31:46 2004 +0900
+++ b/mc-parse.c	Tue Jun 29 23:11:47 2004 +0900
@@ -22,14 +22,17 @@
 extern double strtod(const char *nptr, char **endptr);
 #endif
 
+
 NMTBL null_nptr;
 NMTBL *fnptr;
 NMTBL *msearch0(char *name);
 NMTBL *nptr,*gnptr;
 NMTBL ntable[GSYMS+LSYMS];
-char *cheapp;
-char cheap[CHEAPSIZE]; // should be extendable
-char linebuf[LBUFSIZE],namebuf[LBUFSIZE],*chptr;
+static HASH htable0[GSYMS];
+HASH *htable = htable0;
+struct cheap *cheap,*cheap0;
+char linebuf[LBUFSIZE];
+char *chptr;
 int args,init_vars,heap[HEAPSIZE];
 int asmf;
 int bit_field_disp;
@@ -120,6 +123,8 @@
 static int typeid(int s);
 static int typename(void);
 
+static struct cheap * new_cheap();
+
 #if FLOAT_CODE
 static double dsymval;
 #endif
@@ -127,10 +132,7 @@
 static long long  lsymval;
 #endif
 static int symval;
-static char *name;
-static unsigned hash;
 static int gfree;
-static char *sptr;
 
 static int sdecl_f = 1;
 static int stypedecl;
@@ -257,10 +259,12 @@
 	(n==CNERR) ? "Constant required" :
 	(n==CHERR) ? "Illegal character" :
 	(n==GSERR) ? "Too many global symbols" :
+	(n==HSERR) ? "Too many string or 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==NMERR) ? "Name too long" :
 	(n==EOFERR) ? "Unexpected end of file" :
 	(n==MCERR) ? "Macro syntax" :
 	(n==INCERR) ? "Include syntax" :
@@ -324,8 +328,11 @@
 {
     int i;
     NMTBL *nptr;
+    struct cheap *p;
 
-    cheapp=cheap;
+    cheap=cheap0;
+    for(p=cheap;p;p=p->next) p->ptr=p->first;
+
     for(nptr = ntable,i = GSYMS; i--;) (nptr++)->sc = 0;
     for(nptr = mtable,i = MSYMS; i--;) (nptr++)->sc = 0;
 
@@ -391,6 +398,7 @@
 static void
 init(void)
 {
+    cheap0 = new_cheap();
     codegen_init();
     reinit();
     filep=filestack;
@@ -413,11 +421,44 @@
 
 static int first_newfile = 1;
 
+extern char *
+make_filename_with_extension(char *filename,char *ext)
+{
+    char *p=cheap->ptr;
+    char *s,*t;
+    struct cheap scheap,scheap1;
+    save_cheap(&scheap,cheap);
+
+    if (! *filename) filename="mcout";
+    for (t=0,s=filename;(*cheap->ptr = *s++);cheap=increment_cheap(cheap,&p)) {
+        if (*s=='.') {
+            t=cheap->ptr;
+	    save_cheap(&scheap1,cheap);
+        }
+    }
+    if (t) {
+	cheap = reset_cheap(&scheap1);
+        cheap->ptr = t;
+	*cheap->ptr='.';
+    } else {
+	cheap->ptr[-1]='.';
+	cheap = increment_cheap(cheap,&p);
+    }
+    for(s = ext; *s; s++) {
+	*cheap->ptr = *s; cheap = increment_cheap(cheap,&p);
+    }
+    cheap = reset_cheap(&scheap);
+    return p;
+}
+
+
 static void
 newfile(void)
 {
     char *s;
     int flag = 0;
+    struct cheap scheap;
+    FILE *out;
 
     if (!first_newfile) {
 	closing();
@@ -429,24 +470,15 @@
     if ( (filep->fcb = fopen(av[ac2++],"r")) == NULL ) error(FILERR);
     s = av[ac2-1];
     copy_current_file_dir(s);
-    filep->name0 = cheapp;
+    filep->name0 = cheap->ptr;
     filep->inc = 0;
-    while((*cheapp++ = *s++));
+    while((*cheap->ptr = *s++)) cheap = increment_cheap(cheap,&filep->name0);
+    *cheap->ptr = 0;
+    cheap = increment_cheap(cheap,&filep->name0);
     if(!ccout) {
-	ccout=s=cheapp; s= filep->name0;
-	while((*cheapp++ = *s++)) {
-	    if(s[0]=='.'&&s[1]=='c') {
-		*cheapp++=*s++; *cheapp++=*s++;
-		cheapp[-1]='s';
-		flag =1;
-	    }
-	}
-	if (flag) {
-	    if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR);
-	} else {
-	    if ( (freopen("mcout.s","w",stdout)) == NULL ) error(FILERR);
-	}
-	cheapp=ccout;
+	ccout = make_filename_with_extension(filep->name0,"s");
+	if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR);
+	cheap = reset_cheap(&scheap);
 	ccout=0;
     }
     opening(filep->name0);
@@ -478,13 +510,10 @@
 {
     NMTBL *nptr;
     int i;
+    char *schptr = chptr
 
-    hash=0; name=namebuf; i=0;
-    while((name[i++] = *s)) {
-	hash=(((7*hash)&0xfffffff) ^ *s++);
-    }
-    if (cheapp+i >= cheap+CHEAPSIZE) error(STRERR);
-    name[i++] = 0;
+    chptr = s;
+    get_name();
     (nptr = gsearch(0))->sc = RESERVE;
     if (d==0) {
 	nptr->sc = MACRO;
@@ -962,16 +991,18 @@
 new_static_name(char *name,int delimit)
 {
     int ndsp;
-    char *p = cheapp;
+    char *p = cheap->ptr;
 
-    while((*cheapp++ = *name++));
+    while((*cheap->ptr = *name++)) increment_cheap(cheap,&p);
     ndsp = ++stat_no;
-    cheapp[-1] = delimit;
+    cheap->ptr[-1] = delimit;
     while(ndsp>0) {
-	*cheapp++ = ndsp%10+'0';
+	*cheap->ptr = ndsp%10+'0';
+	increment_cheap(cheap,&p);
 	ndsp /= 10;
     }
-    *cheapp++ = 0;
+    *cheap->ptr = 0;
+    increment_cheap(cheap,&p);
     return p;
 }
 
@@ -1935,7 +1966,7 @@
     checksym(LPAR);
     // asm string
     if (sym!=STRING) error(DCERR);
-    asm0=list3(STRING,(int)sptr,symval);
+    asm0=list3(STRING,nptr->nm,nptr->dsp);
     getsym(0);
     if (sym!=COLON) error(DCERR);
     do {
@@ -1943,7 +1974,7 @@
 	getsym(0);
 	if (sym==COLON) break;
 	if (sym!=STRING) error(DCERR);
-	out=list2(list3(STRING,(int)sptr,symval),out);
+	out=list2(list3(STRING,nptr->nm,nptr->dsp),out);
 	getsym(0);
 	e1=list2(e=expr1(),e1);
 	lcheck(e);
@@ -1954,7 +1985,7 @@
 	    getsym(0);
 	    if (sym==COLON) break;
 	    if (sym!=STRING) error(DCERR);
-	    input=list2(list3(STRING,(int)sptr,symval),input);
+	    input=list2(list3(STRING,nptr->nm,nptr->dsp),input);
 	    getsym(0);
 	    e1=list2(expr1(),e1);
 	} while(sym==COMMA);
@@ -1964,7 +1995,7 @@
 	    // option string
 	    getsym(0);
 	    if (sym!=STRING) error(DCERR);
-	    opt=list2(list3(STRING,(int)sptr,symval),opt);
+	    opt=list2(list3(STRING,nptr->nm,nptr->dsp),opt);
 	    getsym(0);
 	} while(sym==COMMA);
     }
@@ -2515,9 +2546,9 @@
 	}
 	break;
     case STRING:
-	conv-> string_(sptr);
-	e1=list3(STRING,(int)sptr,symval);
-	type=list3(ARRAY,CHAR,symval);
+	conv-> string_(nptr->nm,nptr->dsp);
+	e1=list3(STRING,nptr->nm,nptr->dsp);
+	type=list3(ARRAY,CHAR,nptr->dsp);
 	getsym(0);
 	break;
     case CONST:
@@ -2794,20 +2825,133 @@
     }
 }
 
+static struct cheap *
+new_cheap()
+{
+    struct cheap *p = (struct cheap *)malloc(sizeof(struct cheap));
+    if (!p) error(MMERR); // fatal
+    p->ptr = p->first = (char *)malloc(CHEAP_SIZE);
+    if (!p->ptr) error(MMERR); // fatal
+    p->next = 0;
+    return p;
+}
+
+extern struct cheap *
+increment_cheap(struct cheap *cheap,char **save)
+{
+    char *p,*from;
+    int i;
+    if (cheap->ptr == cheap->last) {
+	if (!cheap->next) { 
+	    cheap->next = new_cheap();
+	}
+	if (save) {
+	    cheap->ptr = from = *save;
+	    i = cheap->last - from;
+	    to   = *save = cheap->next->first;
+	    while(i-->0) *to++ = *from++;
+	}
+	cheap = cheap->next;
+    }
+    if (cheap->ptr==chptr)
+	error(-1);
+    cheap->ptr++'
+    return cheap;
+}
+
+extern void
+save_cheap(struct cheap *scheap,struct cheap *cheap)
+{
+    // keep curret cheap pointer
+    scheap->ptr = cheap->ptr;
+    scheap->next = cheap;
+}
+
+extern struct cheap *
+reset_cheap(struct cheap *scheap)
+{
+    // go back to the kept curret cheap pointer
+    if (cheap==scheap) {
+	cheap->ptr = scheap->ptr;
+    } else {
+	cheap->ptr = cheap->first;
+	cheap = scheap->next;
+	cheap->ptr = scheap->ptr;
+    }
+}
+
+
+static int
+neqnamel(char *p,char *q,int len)
+{
+    while(len-->0 && *p++ == *q++);
+    return len!=0;
+}
+
+static HASH *
+hash_search(char *name,int len,int hash)
+{
+    HASH *hptr,*iptr;
+
+    iptr=hptr= &htable[hash % HSYMS];
+    while(hptr->sc!=0 && neqnamel(hptr->nm,name,len)) {
+	if (++hptr== &htable[HSYMS])
+	    hptr=ntable;
+	if (hptr==iptr) error(HSERR);
+    }
+    if (hptr->sc == 0) {
+	hptr->sc=EMPTY;
+    } else {
+	cheap = name;
+    }
+    return hptr;
+}
+
+#define hash_value(hash,ch) (hash = 39*hash^((unsigned char)(ch)))
+
 static void
 get_name()
 {
     int i = 0;
-    hash = 0;
-    name = namebuf;
-    while (alpha(ch) || digit(ch)) {
-	if (i < LBUFSIZE-1)
-	    hash=(((7*hash)&0xfffffff) ^ (name[i++]=ch));
+    int hash = 0;
+    char *name = cheap->ptr;
+    for(i=0;alpha(ch) || digit(ch);i++) {
+	if (i>MAX_NAME) error(NMERR);
+	hash_value(hash,*cheap->ptr = ch);
+	cheap = increment_cheap(cheap,&name);
 	getch();
     }
-    name[i++] = '\0';
+    *cheap->ptr = 0;
+    cheap = increment_cheap(cheap,&name);
+    hptr = hash_search(name,i,hash);
 }
 
+static void
+getstring(void)
+{
+    char *name = cheap->ptr;
+    int i= 0;
+    int hash = 0;
+    while (ch == '"') {
+	in_quote = 1;
+	getch();
+	while (ch != '"') {
+	    if (i>MAX_STRING) error(STRERR);
+	    hash_value(hash, *cheap->ptr = escape());
+	    cheap = increment_cheap(cheap,&name);
+	    i++;
+	}
+	in_quote = 0;
+	getch();
+	skipspc();  // "aaa" "bbb" case
+    }
+    in_quote = 0;
+    *cheap->ptr = 0;
+    cheap = increment_cheap(cheap,&name);
+    i++;
+    nptr = gsearch(hash_search(name,i,hash),STRING);
+    symval = i;
+}
 
 static int
 is_ll()
@@ -2828,11 +2972,15 @@
 get_numerical()
 {
     int d;
-    char *scheapp;
+    struct cheap scheap;
+    char *num;
+
     /* numerical */
 
+    save_cheap(&scheap,cheap);
     symval=0; d=0;
-    scheapp = cheapp;
+    num = cheap->ptr;
+    sym = 0;
     if(ch=='.') {
 	getch();
 	if(ch=='.') {
@@ -2846,12 +2994,14 @@
 	} else if (!digit(ch))
 	    return sym=PERIOD;
 	d=1;
-	*cheapp++ = '.'; /* .0 case */
+	*cheap->ptr = '.'; /* .0 case */
+	cheap = increment_cheap(cheap,&num);
     } else if (ch == '0') {
 	if (getch() == 'x' || ch == 'X') {
 	    /* hexadicimal */
 	    while(1) {
-		getch(); *cheapp++ = ch;
+		getch(); *cheap->ptr = ch;
+		cheap = increment_cheap(cheap,&num);
 		if(digit(ch))
 		    symval=symval*16+ch-'0';
 		else if('a'<=ch&&ch<='f')
@@ -2862,84 +3012,95 @@
 	    }
 	    if (is_ll()) {
 #if LONGLONG_CODE
-		*cheapp++ = 0;
-		lsymval = strtoll(scheapp,0,0);
-		cheapp=scheapp;
-		return sym=LCONST;
+		*cheap->ptr = 0;
+		cheap = increment_cheap(cheap,&num);
+		lsymval = strtoll(num,0,0);
+		// we should keep this value? like string?
+		cheap = reset_cheap(&scheap);
+		sym=LCONST;
 #endif
-	    }
-	    return sym=CONST;
+	    } else
+		sym=CONST;
 	} else if (digit(ch)) {
 	    /* octal */
 	    while(1) {
-		getch(); *cheapp++ = ch;
+		getch(); *cheap->ptr = ch;
+		cheap = increment_cheap(cheap,&num);
 		if(digit(ch))
 		    symval=symval*8+ch-'0';
 		else break;
 	    }
 	    if (is_ll()) {
 #if LONGLONG_CODE
-		*cheapp++ = 0;
-		lsymval = strtoll(scheapp,0,0);
-		cheapp=scheapp;
-		return sym=LCONST;
+		*cheap->ptr = 0;
+		cheap = increment_cheap(cheap,&num);
+		lsymval = strtoll(num,0,0);
+		cheap = reset_cheap(&scheap);
+		sym=LCONST;
 #endif
-	    }
-	    cheapp=scheapp;
-	    return sym=CONST;
+	    } else 
+		sym=CONST;
 	} else if (ch=='L'||ch=='U') {  /* 0L or 0LL case */
 	    if (is_ll()) {
 #if LONGLONG_CODE
 		lsymval = 0;
-		return sym=LCONST;
+		sym=LCONST;
 #endif
 	    }
 	} else if (ch=='.'||ch=='e') {
 	    d=1;
-	    *cheapp++ = '0'; /* 0. case */
+	    *cheap->ptr = '0'; /* 0. case */
+	    cheap = increment_cheap(cheap,&num);
 	} else {
-	    cheapp=scheapp;
+	    cheap = reset_cheap(&scheap);
 	    symval = 0;
-	    return sym=CONST;
+	    sym=CONST;
 	}
     } else {
 	while(digit(ch)) {
-	    *cheapp++ = ch;
+	    *cheap->ptr = ch;
+	    cheap = increment_cheap(cheap,&num);
 	    symval=symval*10+ch-'0';getch();
 	}
 	if (ch=='.'||ch=='e') d=1;
     }
-    if (!d) {
-	if (is_ll()) {
+    if (!sym) {
+	if (!d) {
+	    if (is_ll()) {
 #if LONGLONG_CODE
-	    *cheapp++ = 0;
-	    lsymval = strtoll(scheapp,0,0);
-	    cheapp=scheapp;
-	    return sym=LCONST;
+		*cheap->ptr = '0';
+		cheap = increment_cheap(cheap,&num);
+		lsymval = strtoll(num,0,0);
+		sym=LCONST;
+#endif
+	    } else
+		sym=CONST;
+	} else {
+#if FLOAT_CODE
+	    /* floating point case */
+	    while(digit(ch)|| ch=='.'||ch=='e') {
+		*cheap->ptr = ch;
+		cheap = increment_cheap(cheap,&num);
+		getch();
+		if ((ch=='-' && cheap->ptr[-1]=='e')||
+			(ch=='+' && cheap->ptr[-1]=='e')) {
+		    *cheap->ptr = ch;
+		    cheap = increment_cheap(cheap,&num);
+		    getch();
+		}
+	    }
+	    *cheap->ptr = 0;
+	    cheap = increment_cheap(cheap,&num);
+	    dsymval = strtod(num,0);
+	    sym=DCONST;
+#else
+	    symval = 0;
+	    sym=CONST;
 #endif
 	}
-	cheapp=scheapp;
-	return sym=CONST;
     }
-#if FLOAT_CODE
-    /* floating point case */
-    while(digit(ch)|| ch=='.'||ch=='e') {
-	*cheapp++ = ch;
-	getch();
-	if (ch=='-' && cheapp[-1]=='e') {
-	    *cheapp++ = ch; getch();
-	} else if (ch=='+' && cheapp[-1]=='e') {
-	    *cheapp++ = ch; getch();
-	}
-    }
-    *cheapp++ = 0;
-    dsymval = strtod(scheapp,0);
-    cheapp=scheapp;
-    return sym=DCONST;
-#else
-    symval = 0;
-    return sym=CONST;
-#endif
+    cheap = reset_cheap(&scheap);
+    return;
 }
 
 extern int
@@ -3104,111 +3265,124 @@
     return('0'<=c&&c<='9');
 }
 
+static NMTBL *free_nptr_list;
+static NMTBL *nptr_pool=0;
+static NMTBL *nptr_pool_last=0;
+
+extern int
+free_nptr(NMTBL n*)
+{
+    n->next = free_nptr_list;
+    free_nptr_list = n;
+}
+
+extern int
+get_nptr()
+{
+    NMTBL *ret;
+    if (free_nptr_list) {
+	ret = free_nptr_list;
+	free_nptr_list = free_nptr_list->next;
+	ret->sc = 0;
+	ret->next = 0;
+	return ret;
+    }
+    if (nptr_pool >= nptr_pool_last) {
+	nptr_pool = (NMTBL*)malloc(GSYMS);
+	nptr_pool_last = nptr_pool + GSYMS;
+	if (!nptr_pool) error(GSERR);
+    }
+    ret = nptr_pool++;
+    ret->sc = 0;
+    ret->next = 0;
+    return ret;
+}
+
+extern void
+free_glist3(int e1)
+{
+    if (e1>gfree) return;  /* freeing local heap */
+    if (e1==gfree) {
+	gfree-=3;
+    } else {
+	cadr(e1) = free_glist3_list;
+	free_glist3_list = e1;
+    }
+}
+
+
 int dummy_count = 0;
 
 extern NMTBL *
 anonymous_nptr()
 {
-    NMTBL *nptr,*iptr;
-
-    iptr=nptr= &ntable[hash % GSYMS];
-    while(nptr->sc!=0) {
-	if (++nptr== &ntable[GSYMS])
-	    nptr=ntable;
-	if (nptr==iptr) error(GSERR);
+    NMTBL *nptr;
+    int i,j;
+    nptr= get_nptr();
+    j = dummy_count++;
+    for(i=0;j>0;j/=10);
+    nptr->nm = cheap->ptr;
+    cheap->ptr += i-1+3;
+    increment_cheap(cheap,&nptr->nm);
+    nptr->nm[0]='_';
+    nptr->nm[1]='a';
+    nptr->nm[2]='n';
+    j = dummy_count;
+    for(;i>=0;i--) {
+	nptr->nm[i+3]='0'+j%10;
+	j/=10;
     }
-    copy(nptr,"_00000");
-    dummy_count++;
-    if (dummy_count>999) error(STRERR);
-    nptr->nm[5]='0'+dummy_count%10;
-    nptr->nm[4]='0'+(dummy_count/10)%10;
-    nptr->nm[3]='0'+(dummy_count/100)%10;
     nptr->sc=EMPTY;
-    return nptr;
-}
-
-static NMTBL *
-gsearch(int sc)
-{
-    NMTBL *nptr,*iptr;
-
-    iptr=nptr= &ntable[hash % GSYMS];
-    while(nptr->sc!=0 && (neqname(nptr->nm,name) || 
-	!(sc?(nptr->sc==sc):(nptr->sc!=TAG)))) {
-	if (++nptr== &ntable[GSYMS])
-	    nptr=ntable;
-	if (nptr==iptr) error(GSERR);
-    }
-    if (nptr->sc == 0) {
-	copy(nptr,name);
-	nptr->sc=EMPTY;
-	nptr->dsp=0;
-    }
+    nptr->next=0;
     return nptr;
 }
 
 static NMTBL *
-lsearch(char *name,int sc)
+gsearch(HASH *hp,int sc)
 {
-    NMTBL *nptr,*iptr;
-
-    iptr=nptr= &ntable[hash%LSYMS+GSYMS];
-    while(nptr->sc!=0 && (neqname(nptr->nm,name) || 
-	!(sc?(nptr->sc==sc):(nptr->sc!=TAG)))) {
-	if (++nptr== &ntable[LSYMS+GSYMS])
-	    nptr= &ntable[GSYMS];
-	if (nptr==iptr) error(LSERR);
+    NMTBL *n = hp->nptr;
+   
+    for(n=hp->nptr;n;n=n->next) {
+	if (sc && nptr->sc!=sc) continue;
+	else switch(nptr->sc) {
+	case TAG: case MACRO: case STRING:
+	    contine;
+	}
+	return n;
+    } 
+    if (n==0) {
+	n = get_nptr();
+	n->next = hp->nptr;
+	hp->nptr = n;
     }
-    if (nptr->sc == 0) {
-	nptr->nm=name;  /* already saved in gsearch */
-	nptr->sc=EMPTY;
-	nptr->dsp=0;
-    }
+    n->sc = sc?sc:EMPTY;
+    nptr->dsp = 0;
     return nptr;
 }
 
 static NMTBL *
+lsearch(HASH *hp,int sc)
+{
+    NMTBL *nptr = gsearch(hp,sc);
+    scope = list2((int)nptr,scope);
+    return nptr;
+}
+
+static 
+free_scope(HASH *hp,int sc)
+{
+    NMTBL *nptr = gsearch(hp,sc);
+    scope = list2((int)nptr,scope);
+    return nptr;
+}
+
+
+static NMTBL *
 msearch(char *name)
 {
-    NMTBL *nptr,*iptr;
-
-    iptr=nptr= &mtable[hash%MSYMS];
-    while(nptr->sc!=0 && neqname(nptr->nm,name)) {
-	if (++nptr== &mtable[MSYMS])
-	    nptr= &mtable[0];
-	if (nptr==iptr) error(MSERR);
-    }
-    if (nptr->sc == 0) {
-	copy(nptr,name);
-	nptr->sc=EMPTY;
-	nptr->dsp=0;
-	nptr->ty=0;
-    }
-    return nptr;
-}
-
-extern NMTBL *
-msearch0(char *name)
-{
-    NMTBL *nptr,*iptr;
-    int hash,i;
-
-    i = 0; hash = 0;
-    while((name[i])) {
-	hash=(((7*hash)&0xfffffff) ^ (name[i++]));
-    }
-    iptr=nptr= &mtable[hash%MSYMS];
-    while(nptr->sc!=0 && neqname(nptr->nm,name)) {
-	if (++nptr== &mtable[MSYMS])
-	    nptr= &mtable[0];
-	if (nptr==iptr) error(MSERR);
-    }
-    if (nptr->sc == 0) {
-	copy(nptr,name);
-	nptr->sc=EMPTY;
-	nptr->dsp=0;
-	nptr->ty=0;
-    }
+    NMTBL *nptr;
+    
+    nptr = gsearch(hp,MACRO);
     return nptr;
 }
 
@@ -3216,15 +3390,14 @@
 extern_define(char *s,int d,int type,int use)
 {
     NMTBL *nptr0;
+    HASH *hash;
     int i;
+    char *schptr = chptr;
 
-    hash=0; name=namebuf; i=0;
-    while((name[i++] = *s)) {
-	hash=(((7*hash)&0xfffffff) ^ (*s)); s++;
-    }
-    if (cheapp+i >= cheap+CHEAPSIZE) error(STRERR);
-    name[i++] = 0;
-    (nptr0 = gsearch(0))->sc = EXTRN;
+    chptr = s;
+    hash = get_name();
+    chptr = schptr;
+    (nptr0 = gsearch(hash,0))->sc = EXTRN;
     nptr0->dsp = d; nptr0->ty=type;
     if (use) extrn_use(nptr0);
 }
@@ -3233,8 +3406,9 @@
 static void
 copy(NMTBL *nptr, char *s)
 {
-    nptr->nm = cheapp;
-    while((*cheapp++ = *s++));
+    nptr->nm = cheap->ptr;
+    while((*cheap->ptr = *s++))
+	cheap = increment_cheap(cheap,&nptr->nm);
 }
 
 extern int
@@ -3247,28 +3421,6 @@
     return (*q!=0);
 }
 
-static void
-getstring(void)
-{
-    symval = 0;
-    sptr = cheapp;
-    while (ch == '"') {
-	in_quote = 1;
-	getch();
-	while (ch != '"') {
-	    *cheapp++ = escape();
-	    symval++;
-	    if (cheapp >= cheap+CHEAPSIZE) error(STRERR);
-	}
-	in_quote = 0;
-	getch();
-	skipspc();
-    }
-    in_quote = 0;
-    *cheapp++ = '\0';
-    symval++;
-}
-
 extern int
 skipspc(void)
 {
--- a/mc-parse.h	Sun Jun 27 20:31:46 2004 +0900
+++ b/mc-parse.h	Tue Jun 29 23:11:47 2004 +0900
@@ -18,16 +18,39 @@
 extern int debug; 
 extern int decl_str_init;
 
+typedef struct hash
+{
+    char *nm;
+    int len;
+    NMTBL *nptr;
+} HASH;
+
+/*
+          STRING         nptr
+          MACRO          nptr
+          FMACRO         nptr
+          RESERVE        nptr
+          TAG            nptr
+          FIELD          nptr
+          TYPE           nptr
+ */
+
+typedef struct cheap
+{
+    char *ptr;
+    char *last;
+    char *first;
+    struct cheap *next;
+} CHEAP;
+
 
 /* used in mc-macro.c */
 
 extern int asmf;
 extern int ch;
-extern char cheap[CHEAPSIZE]; // should be extendable
-extern char *cheapp;
 extern int chptrsave; 
 extern int chsave; 
-extern char linebuf[LBUFSIZE],namebuf[LBUFSIZE],*chptr;
+extern char linebuf[LBUFSIZE],*chptr;
 extern int glineno; 
 extern int in_comment; 
 extern int in_quote; 
@@ -41,6 +64,8 @@
 extern  NMTBL null_nptr;
 extern NMTBL ntable[GSYMS+LSYMS];
 
+extern char * make_filename_with_extension(char *filename,char *ext);
+
 /* used in mc-switch */
 
 extern void free_glist3(int e1);
@@ -86,6 +111,8 @@
 
 /* used in mc-macro.c */
 
+extern struct cheap *cheap;
+
 extern int getsym(int sc);
 extern int getch(void);
 extern int skipspc(void);
@@ -96,4 +123,8 @@
 extern int alpha(int c);
 extern int digit(int c);
 
+extern struct cheap * increment_cheap(struct cheap *cheap,char **save);
+extern void save_cheap(struct cheap *scheap,struct cheap *cheap);
+extern struct cheap * reset_cheap(struct cheap *scheap);
+
 /* end */
--- a/mc.h	Sun Jun 27 20:31:46 2004 +0900
+++ b/mc.h	Tue Jun 29 23:11:47 2004 +0900
@@ -405,7 +405,9 @@
 #define CODE_ERR        21
 #define MSERR   22
 #define BTERR   23
-#define INERR   24
+#define HSERR   24
+#define NMERR   25
+#define INERR   26
 
 /* error number end */
 
@@ -423,7 +425,7 @@
 
 typedef struct nametable {
         char *nm;
-        int sc,ty,dsp; } NMTBL;
+        int sc,ty,dsp; struct nametable next; } NMTBL;
 
 extern int heap[HEAPSIZE];
 
@@ -442,6 +444,9 @@
 extern int append4(int p,int a1,int a2,int a3);
 extern int insert_ascend(int p,int e,int eq());
 
+extern int free_nptr(NMTBL n*);
+extern int get_nptr();
+
 #define car(e) (heap[(int)(e)])
 
 #define cadr(e) (heap[((int)(e))+1])