changeset 855:740b026e58b9

macro compatibility
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 22 Nov 2011 05:33:40 +0900
parents f283fc68137f
children d9dd3e6e7c5f
files mc-macro.c
diffstat 1 files changed, 49 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mc-macro.c	Tue Nov 22 01:48:07 2011 +0900
+++ b/mc-macro.c	Tue Nov 22 05:33:40 2011 +0900
@@ -40,7 +40,7 @@
 static void macro_define0();
 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_define(char *macro,char *value, char *name);
 static int macro_eval(int macrop,char *body0,int history);
 static char * mappend0(int lists,char **result);
 static int macro_processing();
@@ -874,14 +874,24 @@
 	getch();
 	// ch = *chptr++;
     }
-    // do not eval argument here
+    // eval all argument list
+    int evalues = 0;
+    int values0 = values;
+    while(values) {
+       evalues = list2(macro_eval(0,scaddr(values),history),evalues);
+       values = cadr(values);
+    }
+    evalues = reverse0(evalues);
+    values = values0;
     // define all arguments locally
     //    #define arg0 arg0_value
     //    #define arg1 arg2_value ....
     enter_scope();
     while(args) {
-	local_define(scaddr(args),scaddr(values));
+        mappend0(reverse0(car(evalues)),&macro);
+        local_define(scaddr(args),macro, scaddr(values));
 	args = cadr(args);
+	evalues = cadr(evalues);
 	values = cadr(values);
     }
     // process body replacement
@@ -898,16 +908,17 @@
  */
 
 static void
-local_define(char *macro,char *value)
+local_define(char *macro,char *value, char *name)
 {
     NMTBL *nptr0,*nlist;
     while(*macro==' '||*macro=='\t') macro++;
     nptr0 = name_space_search(nlist=get_name(macro,0,DEF),MACRO);
     nptr0 = make_local_scope(nlist,nptr0,MACRO);
     nptr0->nm = value;
+    nptr0->u.nm = name;  // shallow value for concatenation
 }
 
-static int
+static void
 string_mark(char **expand)
 {
     mconcat = 1;
@@ -915,6 +926,17 @@
     cheap = increment_cheap(cheap,expand);
 }
 
+static int
+next_concat(int c, char *body)
+{
+    if (c=='#' && body[0]=='#') return 1;
+    while((c=*body++)) {
+	if (c=='#' && body[0]=='#') return 1;
+	if (c!=' ' && c!='\t' && c!='\n') return 0;
+    }
+    return 0;
+}
+
 /*
     Evaluate macro string.
 
@@ -931,6 +953,7 @@
     int in_quote = 0;
     int in_wquote = 0;
     int string_flag = 0;
+    int prev_concat = 0;
     char *macro;
     char *body = body0;
     char **expand;
@@ -955,17 +978,19 @@
 		in_wquote = 0;
 	    }
 	} else if (c=='"') {
-	    in_wquote = 1;
+	    in_wquote = 1; prev_concat = 0;
 	} else if (c=='\'') {
-	    in_quote = 1;
+	    in_quote = 1; prev_concat = 0;
 	} else if (c=='#' && *body=='#') {
 	    mconcat = 1; 
+	    prev_concat = 1;
 	    // name concatenation. flag only. remove and re-evaluate
 	    // in the top level. (and skip space)
 	} else if (!mconcat && c=='#' && alpha(*body)) {
 	    // turn into string next macro literal
 	    string_flag = 1;
 	    string_mark(expand);
+	    prev_concat = 0;
             goto names;
 	} else if (alpha(c)) {
 	    // find a name
@@ -992,6 +1017,7 @@
 	    if (check_recurse(nptrm->nm,history)) {
 		// should return the most original one, but how?
 		// save_cheap/reset_cheap and return here?
+		macro = nptrm->nm;
 		goto skip;
 	    }
 	    switch(nptrm->sc) {
@@ -1000,7 +1026,10 @@
 		    while (c==' '||c=='\t') c=*body++;
 		    body--;
 		}
-		if(c!='(') goto skip; // error(MCERR); this isn't error
+		if(c!='(') {
+		    macro = nptrm->nm;
+		    goto skip; // error(MCERR); this isn't error
+		}
 		*cheap->ptr = 0;
 		cheap = increment_cheap(cheap,expand);
 		body++;
@@ -1009,6 +1038,15 @@
 		macrop = list3s(STRING,macrop,cheap->ptr);
 		expand = (char **)&(scaddr(macrop));
 		break;
+	    default:
+		if (prev_concat) {
+		    prev_concat = 0;
+		    macro = nptrm->u.nm;
+		} else if (next_concat(c,body)) {
+		    prev_concat = 1;
+		    macro = nptrm->u.nm;
+		}  else if (!macro[0]) macro = nptrm->nm;
+		goto skip;
 	    case MACRO:
 		if (neqname(nptrm->nm,macro)) {
 		    if (macro[0]==0)  {
@@ -1020,14 +1058,14 @@
 		    }
 		    *cheap->ptr = 0;
 		    cheap = increment_cheap(cheap,expand);
-		    macrop=macro_eval(macrop,macro,glist3s(STRING,history,nptrm->nm));
+		    history = glist3s(STRING,history,nptrm->nm);
+		    macrop=macro_eval(macrop,macro,history);
 		    macrop = list3s(STRING,macrop,cheap->ptr);
 		    expand = (char **)&(scaddr(macrop));
 		    break;
 		}
-	    default:
+		macro = nptrm->nm;
 skip:
-		macro = nptrm->nm;
 	    case LMACRO:
 		while((*cheap->ptr = *macro++)/* && len-- */)
 		    cheap = increment_cheap(cheap,expand);