changeset 347:cef4d8eb9a26

name table reconfigure continue...
author kono
date Fri, 02 Jul 2004 03:55:11 +0900
parents 969089695850
children e77b3a7002ad
files Changes conv/null.c conv_func.tbl mc-codegen.c mc-macro.c mc-parse.c mc-parse.h mc.h stdio.h
diffstat 9 files changed, 282 insertions(+), 204 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Tue Jun 29 23:11:47 2004 +0900
+++ b/Changes	Fri Jul 02 03:55:11 2004 +0900
@@ -5271,7 +5271,7 @@
 
       |--------------||---|
 
-みたいな感じだね。
+みたいな感じだね。これは、まだ実装してないんだよね。
 
 Sun Jun 27 21:06:28 JST 2004
 
@@ -5347,3 +5347,41 @@
 
 name space は、tag, macro, その他? typename は重なっていてはいけない。
 field も別だけど。sc で区別するわけだけど...
+
+hash_search が返すのは name spcae assoc だよね。
+
+巨大なname があると、 macro 展開された chptr を上書きする可能性がある。
+             cheap->ptr         chptr
+    |--------|-name1-| |-name2-|pppppppp|
+             cheap->ptr         chptr
+    |--------|xxxxxxx| |-name1-name2-|--|
+先までコピーしてやればいいんだけど...
+                                     chptr
+    |--------|xxxxxxx| |-name1-name2-|pp| |pppppp|
+
+でも、chptr は、boundary にかかることはないんだから、こういうことは
+起きないんじゃないの? chptr はかからなくても、cheap->ptr は、かかる
+可能性があるか。
+
+これのコピーを実装して、mappend ではpage 転送しないようにすれば、
+mappend で reset_cheap しても良い。
+
+Thu Jul  1 20:28:49 JST 2004
+
+    { int hoge;
+        { int hoge; ....} }
+だけど。。。
+
+異なるレベルだってのをどうやって見つけるの?  define case は、
+わかるから大丈夫か。なんかオプションいるの?
+
+   hash -> name_space -> nptr
+           global (typename, global, function)
+           tag
+           field
+           local -> name_space
+		    label
+                    tag
+                    field
+
+であるべきだよね?
--- a/conv/null.c	Tue Jun 29 23:11:47 2004 +0900
+++ b/conv/null.c	Fri Jul 02 03:55:11 2004 +0900
@@ -147,7 +147,7 @@
 { }
 
 static void
-string_(char *s)
+string_(char *s,int len)
 { }
 
 static void
--- a/conv_func.tbl	Tue Jun 29 23:11:47 2004 +0900
+++ b/conv_func.tbl	Fri Jul 02 03:55:11 2004 +0900
@@ -33,7 +33,7 @@
 void goto_();
 void goto_label_();
 void id_(int sy,NMTBL *nptr);
-void string_(char *s);
+void string_(char *s,int len);
 void const_(int symval);
 void return_f_(); 
 void defined_(char *p);
--- a/mc-codegen.c	Tue Jun 29 23:11:47 2004 +0900
+++ b/mc-codegen.c	Fri Jul 02 03:55:11 2004 +0900
@@ -2371,7 +2371,7 @@
 	    nsc = STATIC;
 	n->sc = nsc;
 	if (stmode==LDECL) {
-	    n->nm = new_static_name(n->nm,'.');
+	    n = new_static_name(n->nm,'.');
 	}
 	gpc +=sz;
 	return n;
--- a/mc-macro.c	Tue Jun 29 23:11:47 2004 +0900
+++ b/mc-macro.c	Fri Jul 02 03:55:11 2004 +0900
@@ -45,8 +45,9 @@
     } else {
         macrop=macro_eval(macrop,(char *)car(nptrm->dsp),0);
     }
+    cheap = reset_cheap(&scheap);
     macropp = cheap->ptr;
-    // we can't reset cheap
+    // we can reset cheap, no page wrap in this case
     mappend(reverse0(macrop),&macropp);
     cheap->ptr[-1] ='\n';
     cheap->ptr[0] =0;
@@ -56,8 +57,9 @@
         mconcat = 0;
         macrop = 0;
         macrop=macro_eval(macrop,macropp,0);
+	cheap = reset_cheap(&scheap);
 	macropp = cheap->ptr;
-	// will override evaled list
+	// will not override evaled list
         mappend(reverse0(macrop),&macropp);
 	cheap->ptr[-1] ='\n';
 	cheap->ptr[0] =0;
@@ -586,7 +588,7 @@
     NMTBL *nptr0;
     while(*macro==' '||*macro=='\t') macro++;
     nptr0 = msearch0(macro);
-    /* save nptr previous contents in a list */
+    /* save nptr's previous content in a list */
     nptr0->ty=list3(nptr0->sc,nptr0->ty,nptr0->dsp);
     /* set new value */
     nptr0->sc=LMACRO;
@@ -608,7 +610,7 @@
 static int
 macro_eval(int macrop,char *body0,int history)
 {
-    int c;
+    int c,len;
     int in_quote = 0;
     int in_wquote = 0;
     char *macro;
@@ -640,25 +642,13 @@
 	    // name concatenation. skip ## and re-eval macro line.
 	    mconcat = 1; body++; continue;
 	} else if (alpha(c)) {
-	    char *schptr;
-	    schptr = chptr; chptr = body;
-	    get_name();
-	    chptr--; // ungetc
-	    body = chptr; chptr = schptr;
-	    nptrm = msearch0(hptr);
+	    nptrm = get_name(body,&len);
+	    body += len;
+	    body--; // ungetc
+	    nptrm = name_space_search(nptrm,MACRO);
 	    macro = (char *)car(nptrm->dsp);
-	    if (nptrm->sc==LMACRO) {
-		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;
-		*cheap->ptr = 0;
-		cheap = increment_cheap(cheap,expand);
-                macrop=macro_eval(macrop,macro,list2((int)macro,history));
-		macrop = list2((int)cheap->ptr,macrop);
-		expand = (char **)&(car(macrop));
-	    } else if (nptrm->sc==FMACRO) {
+	    switch(nptrm->sc) {
+	    case FMACRO:
 		if (c==' '||c=='\t') {
 		    while (c==' '||c=='\t') c=*body++;
 		    body--;
@@ -670,8 +660,20 @@
 			list2((int)macro,history));
 		macrop = list2((int)cheap->ptr,macrop);
 		expand = (char **)&(car(macrop));
-	    } else {
+		break;
+	    case MACRO:
+		if (neqname(nptrm->nm,macro)) {
+		    if (macro[0]==0)  continue;
+		    *cheap->ptr = 0;
+		    cheap = increment_cheap(cheap,expand);
+		    macrop=macro_eval(macrop,macro,list2((int)macro,history));
+		    macrop = list2((int)cheap->ptr,macrop);
+		    expand = (char **)&(car(macrop));
+		    break;
+		}
+	    default:
 		macro = nptrm->nm;
+	    case LMACRO:
 		while((*cheap->ptr = *macro++));
 		    cheap = increment_cheap(cheap,expand);
 		cheap->ptr--;
@@ -692,17 +694,14 @@
 {
     char *p;
     *result = cheap->ptr;
-    while(lists) {
+    for(;lists;list= cadr(lists)) {
         p = (char *)car(lists);
-        while((*cheap->ptr=*p++)) {
+        for(;(*cheap->ptr=*p++);cheap = increment_cheap(cheap,0)) {
 	    // in_quote + \n case ? should be \n.
 	    if (p[-1]=='\n') cheap->ptr[-1]=' ';
-	    cheap = increment_cheap(cheap,result);
 	}
-        cheap->ptr--;
-        lists = cadr(lists);
     }
-    cheap = increment_cheap(cheap,result);
+    cheap = increment_cheap(cheap,0);
     return *result;
 }
 
--- a/mc-parse.c	Tue Jun 29 23:11:47 2004 +0900
+++ b/mc-parse.c	Fri Jul 02 03:55:11 2004 +0900
@@ -27,10 +27,16 @@
 NMTBL *fnptr;
 NMTBL *msearch0(char *name);
 NMTBL *nptr,*gnptr;
-NMTBL ntable[GSYMS+LSYMS];
-static HASH htable0[GSYMS];
-HASH *htable = htable0;
+static NMTBL *htable0[GSYMS];
+NMTBL **htable = htable0;
 struct cheap *cheap,*cheap0;
+
+static struct cheap *nptr_pool,*nptr_pool0;
+static NMTBL *free_nptr_list;
+
+static int current_scope;
+static int saved_scope;
+
 char linebuf[LBUFSIZE];
 char *chptr;
 int args,init_vars,heap[HEAPSIZE];
@@ -63,8 +69,6 @@
 struct {int fd,ln;char *name0;int inc;FILE *fcb;} *filep,filestack[FILES];
 
 static NMTBL *decl0(void),*decl1(void),*lsearch(char *name,int sc);
-static NMTBL *gsearch(int sc);
-static NMTBL *msearch(char *name);
 static int append3(int p,int a1,int a2);
 static int expr0(void);
 static int expr1(void);
@@ -91,7 +95,6 @@
 static int edecl();
 static int adecl(NMTBL *n);
 static void code_decl(NMTBL *n);
-static void copy(NMTBL *nptr, char *s);
 static void decl(void);
 static void docase(void);
 static void docomp(int);
@@ -122,6 +125,10 @@
 static int decl_data(int t, NMTBL *n,int offset,int skip);
 static int typeid(int s);
 static int typename(void);
+static NMTBL * get_name_from_chptr();
+static NMTBL * hash_search(char *name,struct cheap *scheap,int len,int hash);
+static void enter_scope();
+static void leave_scope();
 
 static struct cheap * new_cheap();
 
@@ -157,12 +164,9 @@
 static int ilabel;
 static int stat_no;
 
-static NMTBL mtable[MSYMS];
-
 int
 main(int argc, char **argv)
 {
-    NMTBL *nptr;
     int i;
 
     if(argc==1) exit(1);
@@ -205,9 +209,7 @@
 	if ( (freopen(ccout,"w",stdout)) == NULL ) error(FILERR);
     init();
     while(1) {
-	for (nptr = &ntable[GSYMS],i=LSYMS; i--;) {
-	    (nptr++)->sc = 0;
-	}
+	leave_scope();
 	mode=TOP;
 	lfree= HEAPSIZE;
 	codegen_decl_init();
@@ -265,6 +267,7 @@
 	(n==STRERR) ? "Too many strings or macros" :
 	(n==LNERR) ? "Line too long" :
 	(n==NMERR) ? "Name too long" :
+	(n==MMERR) ? "malloc error" :
 	(n==EOFERR) ? "Unexpected end of file" :
 	(n==MCERR) ? "Macro syntax" :
 	(n==INCERR) ? "Include syntax" :
@@ -327,14 +330,15 @@
 reinit(void)
 {
     int i;
-    NMTBL *nptr;
+
     struct cheap *p;
 
     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;
+    nptr_pool = nptr_pool0;
+    for(p=nptr_pool;p;p=p->next) p->ptr=p->first;
+    free_nptr_list = 0;
 
     reserve("int",INT);
     reserve("void",VOID);
@@ -399,6 +403,7 @@
 init(void)
 {
     cheap0 = new_cheap();
+    nptr_pool0 = new_cheap();
     codegen_init();
     reinit();
     filep=filestack;
@@ -456,9 +461,7 @@
 newfile(void)
 {
     char *s;
-    int flag = 0;
     struct cheap scheap;
-    FILE *out;
 
     if (!first_newfile) {
 	closing();
@@ -509,12 +512,9 @@
 reserve(char *s, int d)
 {
     NMTBL *nptr;
-    int i;
-    char *schptr = chptr
+
 
-    chptr = s;
-    get_name();
-    (nptr = gsearch(0))->sc = RESERVE;
+    (nptr = name_space_search(get_name(s,0),d?0:MACRO))->sc = RESERVE;
     if (d==0) {
 	nptr->sc = MACRO;
 	nptr->dsp = (int)""; nptr->ty=0;
@@ -986,24 +986,34 @@
     return 0;
 }
 
+#define hash_value(hash,ch) (hash = (39*hash)^((unsigned char)(ch)))
 
-extern char *
+extern NMTBL *
 new_static_name(char *name,int delimit)
 {
-    int ndsp;
+
+    int ndsp,ch,len=0;
     char *p = cheap->ptr;
+    unsigned int hash = 0;
+    struct cheap scheap;
+    save_cheap(&scheap,cheap);
 
-    while((*cheap->ptr = *name++)) increment_cheap(cheap,&p);
+    while((ch = *name++)) {
+	hash_value(hash,*cheap->ptr = ch);
+	increment_cheap(cheap,&p);len++;
+    }
     ndsp = ++stat_no;
     cheap->ptr[-1] = delimit;
     while(ndsp>0) {
-	*cheap->ptr = ndsp%10+'0';
-	increment_cheap(cheap,&p);
+	ch = ndsp%10+'0';
+	hash_value(hash,*cheap->ptr = ch);
+	increment_cheap(cheap,&p);len++;
 	ndsp /= 10;
     }
     *cheap->ptr = 0;
     increment_cheap(cheap,&p);
-    return p;
+    return name_space_search(
+	name_space_search(hash_search(p,&scheap,len,hash),LDECL),0);
 }
 
 
@@ -1028,7 +1038,7 @@
     if (mode==LDECL && LOCAL_STRUCT_INIT_STATIC) {
 	// uninitialized part should be 0.
 	// local var init cannot postponed because of assign_expr0/type
-	nptr0=lsearch(new_static_name("__lstruct",'_'),0);
+	nptr0=new_static_name("__lstruct",'_');
 	nptr0->sc = GVAR;
 	e = size(type);
 	nptr0->ty = type;
@@ -1376,6 +1386,7 @@
 static void
 local_decl()
 {
+    enter_scope();
     init_vars=0;
     /* local variable declaration */
     stmode=0;
@@ -1436,6 +1447,7 @@
     if(!chk) gen_enter1();
     emit_init_vars();
     while(sym!=RC) statement(0);
+    leave_scope();
 
     conv->function_end_(); conv->rc_();
     if(!chk) gen_leave(control,n->nm);
@@ -1624,7 +1636,7 @@
 static void
 dofor(void)
 {
-    int sbreak,scontinue,l,e,slfree;
+    int sbreak,scontinue,l,e,slfree,dflag=0;
 
     sbreak=blabel;
     scontinue=clabel;
@@ -1633,7 +1645,16 @@
     getsym(0);
     checksym(LPAR);
     slfree=lfree;
-    if(sym!=SM) {
+    if (typeid(sym) || sym==STATIC || sym==EXTRN
+		|| sym==REGISTER || sym==TYPEDEF) {
+	enter_scope(); dflag = 1;
+	mode=LDECL;
+	stmode=0;
+	decl();
+	mode=STAT;
+	checkret();
+	emit_init_vars();
+    } else if(sym!=SM) {
 	checkret();
 	gexpr(expr(0),0);
 	checksym(SM);
@@ -1672,6 +1693,7 @@
 	gexpr(e,0);
 	lfree=slfree;
     }
+    if (dflag) leave_scope();
     conv->for_end_();
     gen_jmp(l);
     fwddef(blabel);
@@ -1687,6 +1709,7 @@
     emit_init_vars();
     while(sym!=RC) statement(use); 
     conv->rc_();
+    leave_scope();
     getsym(0);
 }
 
@@ -1966,7 +1989,7 @@
     checksym(LPAR);
     // asm string
     if (sym!=STRING) error(DCERR);
-    asm0=list3(STRING,nptr->nm,nptr->dsp);
+    asm0=list3(STRING,(int)nptr->nm,nptr->dsp);
     getsym(0);
     if (sym!=COLON) error(DCERR);
     do {
@@ -1974,7 +1997,7 @@
 	getsym(0);
 	if (sym==COLON) break;
 	if (sym!=STRING) error(DCERR);
-	out=list2(list3(STRING,nptr->nm,nptr->dsp),out);
+	out=list2(list3(STRING,(int)nptr->nm,nptr->dsp),out);
 	getsym(0);
 	e1=list2(e=expr1(),e1);
 	lcheck(e);
@@ -1985,7 +2008,7 @@
 	    getsym(0);
 	    if (sym==COLON) break;
 	    if (sym!=STRING) error(DCERR);
-	    input=list2(list3(STRING,nptr->nm,nptr->dsp),input);
+	    input=list2(list3(STRING,(int)nptr->nm,nptr->dsp),input);
 	    getsym(0);
 	    e1=list2(expr1(),e1);
 	} while(sym==COMMA);
@@ -1995,7 +2018,7 @@
 	    // option string
 	    getsym(0);
 	    if (sym!=STRING) error(DCERR);
-	    opt=list2(list3(STRING,nptr->nm,nptr->dsp),opt);
+	    opt=list2(list3(STRING,(int)nptr->nm,nptr->dsp),opt);
 	    getsym(0);
 	} while(sym==COMMA);
     }
@@ -2547,7 +2570,7 @@
 	break;
     case STRING:
 	conv-> string_(nptr->nm,nptr->dsp);
-	e1=list3(STRING,nptr->nm,nptr->dsp);
+	e1=list3(STRING,(int)nptr->nm,nptr->dsp);
 	type=list3(ARRAY,CHAR,nptr->dsp);
 	getsym(0);
 	break;
@@ -2586,7 +2609,7 @@
 	t = mode; mode = IFDEF;
 	getsym(0);
 	if (sym==LPAR) { t1 = 1; getsym(0); } else t1 = 0;
-	conv-> defined_(name);
+	conv-> defined_(nptr->nm);
 	mode = t;
 	type= INT;
 	e1=list2(CONST,symval);
@@ -2613,7 +2636,7 @@
 		//             q->lock = (spinlock_t) { };
 		smode = mode;
 		type = t;
-		nptr0=lsearch(new_static_name("__lstruct",'_'),0);
+		nptr0=new_static_name("__lstruct",'_');
 		nptr0->sc = GVAR;
 		e1 = size(type);
 		nptr0->ty = type;
@@ -2830,7 +2853,7 @@
 {
     struct cheap *p = (struct cheap *)malloc(sizeof(struct cheap));
     if (!p) error(MMERR); // fatal
-    p->ptr = p->first = (char *)malloc(CHEAP_SIZE);
+    p->ptr = p->first = (char *)malloc(CHEAPSIZE);
     if (!p->ptr) error(MMERR); // fatal
     p->next = 0;
     return p;
@@ -2839,7 +2862,7 @@
 extern struct cheap *
 increment_cheap(struct cheap *cheap,char **save)
 {
-    char *p,*from;
+    char *p,*q,*from,*to;
     int i;
     if (cheap->ptr == cheap->last) {
 	if (!cheap->next) { 
@@ -2849,13 +2872,22 @@
 	    cheap->ptr = from = *save;
 	    i = cheap->last - from;
 	    to   = *save = cheap->next->first;
-	    while(i-->0) *to++ = *from++;
+	    if (i>CHEAPSIZE) error(NMERR);
+	    if (to<=chptr && chptr<=to+i) {
+		if (!cheap->next->next) { 
+		    cheap->next->next = new_cheap();
+		}
+		q = chptr;
+		p = chptr = cheap->next->next->ptr;
+		while((*p++ = *q++));
+	    }
+	    while(i-->0) {
+		*to++ = *from++;
+	    }
 	}
 	cheap = cheap->next;
     }
-    if (cheap->ptr==chptr)
-	error(-1);
-    cheap->ptr++'
+    cheap->ptr++;
     return cheap;
 }
 
@@ -2878,6 +2910,7 @@
 	cheap = scheap->next;
 	cheap->ptr = scheap->ptr;
     }
+    return cheap;
 }
 
 
@@ -2888,42 +2921,65 @@
     return len!=0;
 }
 
-static HASH *
-hash_search(char *name,int len,int hash)
+static NMTBL *
+hash_search(char *name,struct cheap *scheap,int len,int hash)
 {
-    HASH *hptr,*iptr;
+    NMTBL *hptr,**iptr,**eptr;
 
-    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);
+    eptr = iptr= &htable[hash % GSYMS];
+    while((hptr=*iptr) && hptr->sc!=0 && neqnamel(hptr->nm,name,len)) {
+	if (++iptr== &htable[GSYMS])
+	    iptr=&htable[0];
+	if (eptr==iptr) error(GSERR);
+    }
+    if (!hptr) {
+	hptr = get_nptr();
+	hptr->nm = name; /* name should be in the safe place (cheap) */
     }
     if (hptr->sc == 0) {
 	hptr->sc=EMPTY;
     } else {
-	cheap = name;
+	cheap = reset_cheap(scheap);
     }
     return hptr;
 }
 
-#define hash_value(hash,ch) (hash = 39*hash^((unsigned char)(ch)))
+extern NMTBL *
+get_name(char *name,int *len)
+{
+    /* no name copy */
+    int ch,i = 0;
+    int hash0 = 0;
+    char *n = name;
+    struct cheap scheap;
 
-static void
-get_name()
+    save_cheap(&scheap,cheap);
+    ch = *n++;
+    for(i=0;alpha(ch) || digit(ch);i++) {
+	hash_value(hash0,ch);
+	ch = *n++;
+    }
+    if (len) *len = i;
+    return hash_search(name,&scheap,i,hash0);
+}
+
+extern NMTBL *
+get_name_from_chptr()
 {
     int i = 0;
-    int hash = 0;
+    int hash0 = 0;
     char *name = cheap->ptr;
+    struct cheap scheap;
+
+    save_cheap(&scheap,cheap);
     for(i=0;alpha(ch) || digit(ch);i++) {
-	if (i>MAX_NAME) error(NMERR);
-	hash_value(hash,*cheap->ptr = ch);
+	hash_value(hash0,*cheap->ptr = ch);
 	cheap = increment_cheap(cheap,&name);
 	getch();
     }
     *cheap->ptr = 0;
     cheap = increment_cheap(cheap,&name);
-    hptr = hash_search(name,i,hash);
+    return hash_search(name,&scheap,i,hash0);
 }
 
 static void
@@ -2932,11 +2988,14 @@
     char *name = cheap->ptr;
     int i= 0;
     int hash = 0;
+    struct cheap scheap;
+
+    save_cheap(&scheap,cheap);
     while (ch == '"') {
 	in_quote = 1;
 	getch();
 	while (ch != '"') {
-	    if (i>MAX_STRING) error(STRERR);
+	    if (i>STRSIZE) error(STRERR);
 	    hash_value(hash, *cheap->ptr = escape());
 	    cheap = increment_cheap(cheap,&name);
 	    i++;
@@ -2949,7 +3008,7 @@
     *cheap->ptr = 0;
     cheap = increment_cheap(cheap,&name);
     i++;
-    nptr = gsearch(hash_search(name,i,hash),STRING);
+    nptr = name_space_search(hash_search(name,&scheap,i,hash),STRING);
     symval = i;
 }
 
@@ -3100,19 +3159,17 @@
 	}
     }
     cheap = reset_cheap(&scheap);
-    return;
+    return sym;
 }
 
 extern int
 getsym(int sc)
 {
-    NMTBL *nptr0,*nptr1,*nptrm;
+    NMTBL *nlist,*nptr0,*nptr1,*nptrm; int ns;
     char c;
 
     if (alpha(skipspc())) {
-	get_name();
-
-	nptrm=msearch(name);
+	nptrm=name_space_search(nlist = get_name_from_chptr(),MACRO);
 	if (mode==MDECL) {
 	    nptr = nptrm;
 	    return (sym==MACRO);
@@ -3125,13 +3182,13 @@
 		return (symval=0);
 	    }
 	}
-	if ((nptrm->sc==MACRO&&neqname((char *)car(nptrm->dsp),name)) ||
+	if ((nptrm->sc==MACRO&&neqname((char *)car(nptrm->dsp),nptrm->nm)) ||
 	    (nptrm->sc==FMACRO&&skipspc()=='(')) {
 	    macro_expansion(nptrm);
 	    return getsym(0);
 	}
         /* global variable name table */
-	nptr0 = gsearch(sc);
+	nptr0 = name_space_search(nlist,sc);
 	if (nptr0->sc == RESERVE) return sym = nptr0->dsp;
 	sym = IDENT;
 	gnptr=nptr=nptr0;
@@ -3142,10 +3199,19 @@
 	}
 
         /* local variable name table */
-	nptr1=lsearch(nptr0->nm,sc);
+	nptr1 = name_space_search(nlist=name_space_search(nlist,LDECL),sc);
 	if (mode==STAT) {
+	    /* can be undeclared global variable */
 	    if (nptr1->sc == EMPTY) return sym;
 	}
+	/* define case */
+	for(ns=nlist->dsp;ns;ns=cadr(ns)) {
+	    if (car(ns)==sc) {
+		current_scope = glist3((int)&(caddr(ns)),current_scope,
+			(int)nptr1);
+		caddr(ns) = (int)(nptr1 = get_nptr());
+	    }
+	} 
 	nptr=nptr1;
 	return sym;
 
@@ -3265,52 +3331,38 @@
     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*)
+extern void
+free_nptr(NMTBL *n)
 {
-    n->next = free_nptr_list;
+    n->dsp = (int)free_nptr_list;
     free_nptr_list = n;
 }
 
-extern int
+extern NMTBL *
 get_nptr()
 {
     NMTBL *ret;
     if (free_nptr_list) {
 	ret = free_nptr_list;
-	free_nptr_list = free_nptr_list->next;
+	free_nptr_list = (NMTBL *)free_nptr_list->dsp;
 	ret->sc = 0;
-	ret->next = 0;
+	ret->dsp = 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);
+    if (nptr_pool->ptr >= nptr_pool->last) {
+	if (nptr_pool->next) {
+	    nptr_pool = nptr_pool->next;
+	} else {
+	    nptr_pool->next = new_cheap();
+	    nptr_pool = nptr_pool->next;
+	}
     }
-    ret = nptr_pool++;
+    ret = ((NMTBL *)nptr_pool->ptr)++;
     ret->sc = 0;
-    ret->next = 0;
+    ret->dsp = 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 *
@@ -3333,84 +3385,76 @@
 	j/=10;
     }
     nptr->sc=EMPTY;
-    nptr->next=0;
+    nptr->dsp=0;
     return nptr;
 }
 
+extern NMTBL *
+msearch0(char *name)
+{
+    return name_space_search(get_name(name,0),MACRO);
+}
+
+extern NMTBL *
+name_space_search(NMTBL *hash,int sc)
+{
+    int ns;
+    NMTBL *n;
+  
+    for(ns=hash->dsp;ns;ns=cadr(ns)) {
+	if (car(ns)==sc) {
+	    return (NMTBL*)caddr(ns);
+	}
+    } 
+    if (ns==0) {
+	n = get_nptr();
+	hash->dsp = glist3(sc,hash->dsp,(int)n);
+    }
+    n->nm = hash->nm;
+    n->sc = EMPTY;
+    n->dsp = 0;
+    return (nptr = n);
+}
+
 static NMTBL *
-gsearch(HASH *hp,int sc)
+lsearch(char *name,int sc)
 {
-    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;
-    }
-    n->sc = sc?sc:EMPTY;
-    nptr->dsp = 0;
-    return nptr;
+    return
+	(nptr = name_space_search(name_space_search(get_name(name,0),LDECL),sc));
+}
+
+static  void
+enter_scope()
+{
+    saved_scope = glist2(current_scope,saved_scope);
+    current_scope = 0;
 }
 
-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)
+static  void
+leave_scope()
 {
-    NMTBL *nptr = gsearch(hp,sc);
-    scope = list2((int)nptr,scope);
-    return nptr;
-}
-
-
-static NMTBL *
-msearch(char *name)
-{
-    NMTBL *nptr;
-    
-    nptr = gsearch(hp,MACRO);
-    return nptr;
+    NMTBL *ns;
+    int next;
+    while(current_scope) {
+	ns = *(NMTBL **)car(current_scope);
+	free_nptr(ns);
+	*(NMTBL **)car(current_scope) = (NMTBL *)caddr(current_scope);
+	next = cadr(current_scope);
+	free_glist2(current_scope); // will destroy cadr
+	current_scope = next;
+    }
 }
 
 extern void
 extern_define(char *s,int d,int type,int use)
 {
     NMTBL *nptr0;
-    HASH *hash;
-    int i;
-    char *schptr = chptr;
 
-    chptr = s;
-    hash = get_name();
-    chptr = schptr;
-    (nptr0 = gsearch(hash,0))->sc = EXTRN;
+    (nptr0 = name_space_search(get_name(s,0),0))->sc = EXTRN;
     nptr0->dsp = d; nptr0->ty=type;
     if (use) extrn_use(nptr0);
 }
 
-
-static void
-copy(NMTBL *nptr, char *s)
-{
-    nptr->nm = cheap->ptr;
-    while((*cheap->ptr = *s++))
-	cheap = increment_cheap(cheap,&nptr->nm);
-}
-
 extern int
 neqname(char *p,char *q)
 {
--- a/mc-parse.h	Tue Jun 29 23:11:47 2004 +0900
+++ b/mc-parse.h	Fri Jul 02 03:55:11 2004 +0900
@@ -18,13 +18,6 @@
 extern int debug; 
 extern int decl_str_init;
 
-typedef struct hash
-{
-    char *nm;
-    int len;
-    NMTBL *nptr;
-} HASH;
-
 /*
           STRING         nptr
           MACRO          nptr
@@ -104,7 +97,7 @@
 extern int llist2(int e1, long long d1);
 #endif
 extern int neqname(char *p,char *q);
-extern char *new_static_name(char *name,int delimit);
+extern NMTBL *new_static_name(char *name,int delimit);
 extern int reverse0(int t1);
 extern int size(int t);
 extern int typespec(void);
@@ -112,6 +105,8 @@
 /* used in mc-macro.c */
 
 extern struct cheap *cheap;
+extern NMTBL *get_name(char *name,int *i);
+extern NMTBL *name_space_search(NMTBL *ns,int sc);
 
 extern int getsym(int sc);
 extern int getch(void);
--- a/mc.h	Tue Jun 29 23:11:47 2004 +0900
+++ b/mc.h	Fri Jul 02 03:55:11 2004 +0900
@@ -407,7 +407,8 @@
 #define BTERR   23
 #define HSERR   24
 #define NMERR   25
-#define INERR   26
+#define MMERR   26
+#define INERR   27
 
 /* error number end */
 
@@ -421,11 +422,11 @@
 #define HEAPSIZE        30000
 #define CHEAPSIZE       356000
 #define LBUFSIZE        4096
-#define MACROSIZE       16000
+#define STRSIZE		4096
 
 typedef struct nametable {
         char *nm;
-        int sc,ty,dsp; struct nametable next; } NMTBL;
+        int sc,ty,dsp; } NMTBL;
 
 extern int heap[HEAPSIZE];
 
@@ -444,8 +445,8 @@
 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();
+extern void free_nptr(NMTBL *n);
+extern NMTBL *get_nptr();
 
 #define car(e) (heap[(int)(e)])
 
--- a/stdio.h	Tue Jun 29 23:11:47 2004 +0900
+++ b/stdio.h	Fri Jul 02 03:55:11 2004 +0900
@@ -1,6 +1,7 @@
 #ifndef __micro_c__aaa
 #include "/usr/include/stdio.h"
 long long strtoll(const char *, char **, int);
+char *malloc(int);
 #else
 
 long long strtoll(const char *, char **, int);