changeset 721:76761a18703b recursive-macro

Recursive macro
author kono
date Wed, 11 Jun 2008 22:26:42 +0900
parents 6b7372e17970
children c2fb8e2b1dca
files .gdbinit Changes mc-macro.c mc-macro.h mc-parse.c test/basic-code.c test/conv.c test/longcode.c test/tmp2.c
diffstat 9 files changed, 94 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Sat Apr 12 03:53:11 2008 +0900
+++ b/.gdbinit	Wed Jun 11 22:26:42 2008 +0900
@@ -20,7 +20,8 @@
 # r -s test/tmpa.c
 # r -s test/code-gen-all.c
 # r -s mc-code-powerpc.c
-r -s test/strinit.c
+r -s test/macro.c
+# r -s test/strinit.c
 # r -s test/arg.c
 # r -s -DINLINE=inline test/strinit.c
 # r -s test/fact-a.c
--- a/Changes	Sat Apr 12 03:53:11 2008 +0900
+++ b/Changes	Wed Jun 11 22:26:42 2008 +0900
@@ -9806,9 +9806,19 @@
 
 PS3 PPC が動かなくなっているんだよな。
 
-
-
-
-
-
-
+Wed Jun 11 17:49:30 JST 2008
+
+Recursive macro は、一旦、macro_epansion/getsymを出てしまうと、history
+を使った recursive check にはひっかからない。
+
+check_recursive にひっかかっても、もう一度、retry されてしまうので、
+意味がない。
+
+chptr の切替えでmacro_history をclearすると、get_name_from_chhptr()
+で clear されてしまうので、そのあと check_recurse しても無意味。
+
+難しいな....
+
+clear するタイミングを prev_macro_end でおくらせる。
+
+
--- a/mc-macro.c	Sat Apr 12 03:53:11 2008 +0900
+++ b/mc-macro.c	Wed Jun 11 22:26:42 2008 +0900
@@ -32,6 +32,8 @@
 
 int in_macro_if = 0;
 char *chinput;
+int macro_history = 0;
+int macro_history_save = 0;
 
 static int mconcat=0;
 
@@ -78,12 +80,14 @@
     mode = STAT;
 
     save_cheap(&scheap,cheap);
+    // save recursive macro list
+    macro_history_save = glist2(macro_history,macro_history_save);
 
     // call macro evaluation interpreter
     if (nptrm->sc == FMACRO) {
-        macrop=macro_function(macrop,&chptr,nptrm,0);
+        macrop=macro_function(macrop,&chptr,nptrm,macro_history);
     } else {
-        macrop=macro_eval(macrop,scaddr(nptrm->dsp),0);
+        macrop=macro_eval(macrop,scaddr(nptrm->dsp),macro_history);
     }
 
     // copy output from resulted listed string
@@ -124,7 +128,7 @@
 //     printf("### %s\n",macropp);
 //     if (t[-2]!='\n') putchar('\n');
 // }
-        macrop=macro_eval(macrop,macropp,0);
+        macrop=macro_eval(macrop,macropp,macro_history);
 	cheap = reset_cheap(&scheap);
 	macropp = cheap->ptr;
 	// will not override evaled list
@@ -886,7 +890,7 @@
     }
     // process body replacement
     macro = scaddr(nptr->dsp);
-    macrop = macro_eval(macrop,macro,list3s(STRING,history,macro));
+    macrop = macro_eval(macrop,macro,glist3s(STRING,history,nptr->nm));
     args = sargs;
     // unbind arguments
     leave_scope();
@@ -927,6 +931,8 @@
     char *body = body0;
     char **expand;
     NMTBL *nptrm;
+
+    macro_history = history;
     macrop = list3s(STRING,macrop,cheap->ptr);
     expand = (char **)&scaddr(macrop);
     for(; (c = *body++) ;) {
@@ -981,20 +987,20 @@
 		macro = scaddr(nptrm->dsp);
 	    else
 		macro="";
-//	    if (check_recurse(macro,history)) goto skip;
-//		string_flag = 0;
+	    if (check_recurse(nptrm->nm,history)) 
+		goto skip;
 	    switch(nptrm->sc) {
 	    case FMACRO:
 		if (c==' '||c=='\t') {
 		    while (c==' '||c=='\t') c=*body++;
 		    body--;
 		}
-		if(c!='(') error(MCERR);
+		if(c!='(') goto skip; // error(MCERR); this isn't error
 		*cheap->ptr = 0;
 		cheap = increment_cheap(cheap,expand);
 		body++;
 		macrop = macro_function(macrop,&body,nptrm,
-			list3s(STRING,history,macro));
+			glist3s(STRING,history,nptrm->nm));
 		macrop = list3s(STRING,macrop,cheap->ptr);
 		expand = (char **)&(scaddr(macrop));
 		break;
@@ -1010,14 +1016,14 @@
 		    }
 		    *cheap->ptr = 0;
 		    cheap = increment_cheap(cheap,expand);
-		    macrop=macro_eval(macrop,macro,list3s(STRING,history,macro));
+		    macrop=macro_eval(macrop,macro,glist3s(STRING,history,nptrm->nm));
 		    macrop = list3s(STRING,macrop,cheap->ptr);
 		    expand = (char **)&(scaddr(macrop));
 		    break;
 		}
 	    default:
+skip:
 		macro = nptrm->nm;
-// skip:
 	    case LMACRO:
 		while((*cheap->ptr = *macro++)/* && len-- */)
 		    cheap = increment_cheap(cheap,expand);
@@ -1075,4 +1081,18 @@
     return *result;
 }
 
+extern int
+check_recurse(char *macro,int history)
+{
+    for(;history;history = cadr(history)) {
+	if (macro==scaddr(history)) {
+// fprintf(stderr,"check_recurse: %s %s = ",macro,scaddr(history)); 
+// fprintf(stderr,"1\n");
+	    return 1;
+	}
+    }
+// fprintf(stderr,"0\n");
+    return 0;
+}
+
 /* end */
--- a/mc-macro.h	Sat Apr 12 03:53:11 2008 +0900
+++ b/mc-macro.h	Wed Jun 11 22:26:42 2008 +0900
@@ -29,5 +29,8 @@
 extern void macro_define(char *macro);
 extern char *chinput;
 extern char *mappend(int lists,char **result);
+extern int check_recurse(char *macro,int history);
 
 extern int in_macro_if;
+extern int macro_history;
+extern int macro_history_save;
--- a/mc-parse.c	Sat Apr 12 03:53:11 2008 +0900
+++ b/mc-parse.c	Wed Jun 11 22:26:42 2008 +0900
@@ -4945,8 +4945,10 @@
 		symval = 0;
 		return (sym=CONST);
 	    }
-	    macro_expansion(nptrm);
-	    sc=0; goto retry;
+	    if (!check_recurse(nptrm->nm,macro_history)) {
+		macro_expansion(nptrm);
+		sc=0; goto retry;
+	    }
 	}
         /* global variable name table */
 	nptr0 = name_space_search(nlist,sc);
@@ -5328,13 +5330,32 @@
     return ch;
 }
 
+static int prev_macro_end;
+
 extern int
 getch(void)
 {
     int i,j;
+    if (prev_macro_end) {
+	int history = 0;
+	if (macro_history_save) {
+	    history = car(macro_history_save);	
+	    int save = cadr(macro_history_save);	
+	    free_glist2(macro_history_save);
+	    macro_history_save = save;
+	    while(macro_history!=history) {
+		int next = cadr(macro_history);
+		free_glist3(macro_history);
+		macro_history = next;
+	    }
+	} 
+	prev_macro_end = 0;
+    }
     if(*chptr) 
 	return ch = *chptr++;
     else if (chptrsave) {
+	prev_macro_end = 1;
+
 	chptr = scaddr(chptrsave);
 	ch = car(chsave);
 	i = cadr(chptrsave);
--- a/test/basic-code.c	Sat Apr 12 03:53:11 2008 +0900
+++ b/test/basic-code.c	Wed Jun 11 22:26:42 2008 +0900
@@ -19,10 +19,7 @@
     printf("#0018:i50: %d\n",
 a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16+a17+a18+a19+a20+a21+a22+a23+a24+a25+a26+a27+a28+a29+a30+a31+a32+a33+a34+a35+a36+a37+a38+a39+a40+a41+a42+a43+a44+a45+a46+a47+a48+a49
     );
-    printf("#0021:%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 
-%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 
-%d %d \n",
-a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49);
+    printf("#0021:%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n", a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49);
 
    goto f50(
 0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,49.0
@@ -37,9 +34,7 @@
     printf("#0036:f50: %g\n",
 a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16+a17+a18+a19+a20+a21+a22+a23+a24+a25+a26+a27+a28+a29+a30+a31+a32+a33+a34+a35+a36+a37+a38+a39+a40+a41+a42+a43+a44+a45+a46+a47+a48+a49
     );
-    printf("#0039:%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g 
-%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g 
-%g %g \n",
+    printf("#0039:%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g \n",
 a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49);
 
    goto d50(
@@ -55,9 +50,7 @@
     printf("#0054:d50: %g\n",
 a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16+a17+a18+a19+a20+a21+a22+a23+a24+a25+a26+a27+a28+a29+a30+a31+a32+a33+a34+a35+a36+a37+a38+a39+a40+a41+a42+a43+a44+a45+a46+a47+a48+a49
     );
-    printf("#0057:%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g 
-%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g 
-%g %g \n",
+    printf("#0057:%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g \n",
 a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49);
 
     goto exit0();
@@ -77,8 +70,8 @@
 main0()
 {
 
-ret = return;
-env = environment;
+ret = __return;
+env = __environment;
 goto
 i50(
 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49
--- a/test/conv.c	Sat Apr 12 03:53:11 2008 +0900
+++ b/test/conv.c	Wed Jun 11 22:26:42 2008 +0900
@@ -42,7 +42,7 @@
 }
 
 __code f_g1(int j,stack sp) {  // Continuation 
-    struct f_g0_interface *c = sp;
+    struct f_g0_interface *c = (struct f_g0_interface *)sp;
     int k = c->k_;
     sp += sizeof(struct f_g0_interface);
     goto (( (struct cont_interface *)sp)->ret)(k+4+j,sp);
@@ -65,7 +65,7 @@
 }
 
 #define STACK_SIZE 2048
-stack main_stack[STACK_SIZE];
+char main_stack[STACK_SIZE];
 #define stack_last (&main_stack[STACK_SIZE])
 
 main()
@@ -78,8 +78,8 @@
     sp -= sizeof(*cont);
     cont = (struct main_continuation *)sp;
     cont->ret = main_return;
-    cont->main_ret = return;
-    cont->env = environment;
+    cont->main_ret = __return;
+    cont->env = __environment;
     goto f(233,sp);
 }
 
--- a/test/longcode.c	Sat Apr 12 03:53:11 2008 +0900
+++ b/test/longcode.c	Wed Jun 11 22:26:42 2008 +0900
@@ -27,6 +27,16 @@
      int ccount;
 } player;
 
+struct move_interface {
+     int y;
+     int ch;
+     int point;
+     char  bf;
+     int muteki;
+     int zanki;
+     int ccount;
+};
+
 __code
 put_enemy_bung(
      __code(*junction)(int,teki *,player,struct move_interface),
--- a/test/tmp2.c	Sat Apr 12 03:53:11 2008 +0900
+++ b/test/tmp2.c	Wed Jun 11 22:26:42 2008 +0900
@@ -17,7 +17,7 @@
 char *av[];
 {
     fprintf(stdout,"2: %s\n",av[0]);
-    goto code0(av,return,environment);
+    goto code0(av,__return,__environment);
 }
 
 __code code0(av,ret,retenv)