refactor macro use expander
This commit is contained in:
		
							parent
							
								
									113ae32e47
								
							
						
					
					
						commit
						030c7f9034
					
				
							
								
								
									
										150
									
								
								src/macro.c
								
								
								
								
							
							
						
						
									
										150
									
								
								src/macro.c
								
								
								
								
							|  | @ -131,7 +131,7 @@ pic_core_syntactic_env(pic_state *pic) | |||
|   return senv; | ||||
| } | ||||
| 
 | ||||
| struct pic_macro * | ||||
| static struct pic_macro * | ||||
| macro_new(pic_state *pic, struct pic_proc *proc, struct pic_senv *mac_env) | ||||
| { | ||||
|   struct pic_macro *mac; | ||||
|  | @ -142,6 +142,24 @@ macro_new(pic_state *pic, struct pic_proc *proc, struct pic_senv *mac_env) | |||
|   return mac; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| add_macro(pic_state *pic, pic_sym rename, struct pic_macro *mac) | ||||
| { | ||||
|   xh_put(&pic->macros, rename, &mac); | ||||
| } | ||||
| 
 | ||||
| static struct pic_macro * | ||||
| find_macro(pic_state *pic, pic_sym rename) | ||||
| { | ||||
|   xh_entry *e; | ||||
| 
 | ||||
|   if ((e = xh_get(&pic->macros, rename)) == NULL) { | ||||
|     return NULL; | ||||
|   } | ||||
|   return xh_val(e, struct pic_macro *); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static struct pic_sc * | ||||
| sc_new(pic_state *pic, pic_value expr, struct pic_senv *senv) | ||||
| { | ||||
|  | @ -231,7 +249,7 @@ pic_defmacro(pic_state *pic, const char *name, struct pic_proc *macro) | |||
|   /* symbol registration */ | ||||
|   sym = pic_intern_cstr(pic, name); | ||||
|   rename = pic_add_rename(pic, pic->lib->senv, sym); | ||||
|   xh_put(&pic->macros, rename, &mac); | ||||
|   add_macro(pic, rename, mac); | ||||
| 
 | ||||
|   /* auto export! */ | ||||
|   pic_export(pic, sym); | ||||
|  | @ -346,7 +364,6 @@ macroexpand_defsyntax(pic_state *pic, pic_value expr, struct pic_senv *senv, pic | |||
| { | ||||
|   pic_value var, val; | ||||
|   pic_sym sym, rename; | ||||
|   struct pic_macro *mac; | ||||
| 
 | ||||
|   if (pic_length(pic, expr) != 3) { | ||||
|     pic_error(pic, "syntax error"); | ||||
|  | @ -376,8 +393,7 @@ macroexpand_defsyntax(pic_state *pic, pic_value expr, struct pic_senv *senv, pic | |||
|     pic_errorf(pic, "macro definition \"~s\" evaluates to non-procedure object", var); | ||||
|   } | ||||
| 
 | ||||
|   mac = macro_new(pic, pic_proc_ptr(val), senv); | ||||
|   xh_put(&pic->macros, rename, &mac); | ||||
|   add_macro(pic, rename, macro_new(pic, pic_proc_ptr(val), senv)); | ||||
| 
 | ||||
|   return pic_none_value(); | ||||
| } | ||||
|  | @ -387,7 +403,6 @@ macroexpand_defmacro(pic_state *pic, pic_value expr, struct pic_senv *senv) | |||
| { | ||||
|   pic_value var, val; | ||||
|   pic_sym sym, rename; | ||||
|   struct pic_macro *mac; | ||||
| 
 | ||||
|   if (pic_length(pic, expr) < 2) { | ||||
|     pic_error(pic, "syntax error"); | ||||
|  | @ -425,8 +440,7 @@ macroexpand_defmacro(pic_state *pic, pic_value expr, struct pic_senv *senv) | |||
|     pic_errorf(pic, "macro definition \"~s\" evaluates to non-procedure object", var); | ||||
|   } | ||||
| 
 | ||||
|   mac = macro_new(pic, pic_proc_ptr(val), NULL); | ||||
|   xh_put(&pic->macros, rename, &mac); | ||||
|   add_macro(pic, rename, macro_new(pic, pic_proc_ptr(val), NULL)); | ||||
| 
 | ||||
|   return pic_none_value(); | ||||
| } | ||||
|  | @ -492,69 +506,9 @@ macroexpand_lambda(pic_state *pic, pic_value expr, struct pic_senv *senv, pic_va | |||
| } | ||||
| 
 | ||||
| static pic_value | ||||
| macroexpand_node(pic_state *pic, pic_value expr, struct pic_senv *senv, pic_value assoc_box) | ||||
| macroexpand_macro(pic_state *pic, struct pic_macro *mac, pic_value expr, struct pic_senv *senv, pic_value assoc_box) | ||||
| { | ||||
| #if DEBUG | ||||
|   printf("[macroexpand] expanding... "); | ||||
|   pic_debug(pic, expr); | ||||
|   puts(""); | ||||
| #endif | ||||
| 
 | ||||
|   switch (pic_type(expr)) { | ||||
|   case PIC_TT_SC: { | ||||
|     return macroexpand(pic, pic_sc(expr)->expr, pic_sc(expr)->senv, assoc_box); | ||||
|   } | ||||
|   case PIC_TT_SYMBOL: { | ||||
|     return pic_symbol_value(macroexpand_symbol(pic, pic_sym(expr), senv, assoc_box)); | ||||
|   } | ||||
|   case PIC_TT_PAIR: { | ||||
|     pic_value car; | ||||
|     xh_entry *e; | ||||
| 
 | ||||
|     if (! pic_list_p(expr)) { | ||||
|       pic_errorf(pic, "cannot macroexpand improper list: ~s", expr); | ||||
|     } | ||||
| 
 | ||||
|     car = macroexpand(pic, pic_car(pic, expr), senv, assoc_box); | ||||
|     if (pic_sym_p(car)) { | ||||
|       pic_sym tag = pic_sym(car); | ||||
| 
 | ||||
|       if (tag == pic->sDEFINE_LIBRARY) { | ||||
|         return macroexpand_deflibrary(pic, expr); | ||||
|       } | ||||
| 
 | ||||
|       else if (tag == pic->sIMPORT) { | ||||
|         return macroexpand_import(pic, expr); | ||||
|       } | ||||
| 
 | ||||
|       else if (tag == pic->sEXPORT) { | ||||
|         return macroexpand_export(pic, expr); | ||||
|       } | ||||
| 
 | ||||
|       else if (tag == pic->sDEFINE_SYNTAX) { | ||||
|         return macroexpand_defsyntax(pic, expr, senv, assoc_box); | ||||
|       } | ||||
| 
 | ||||
|       else if (tag == pic->sDEFINE_MACRO) { | ||||
|         return macroexpand_defmacro(pic, expr, senv); | ||||
|       } | ||||
| 
 | ||||
|       else if (tag == pic->sLAMBDA) { | ||||
|         return macroexpand_lambda(pic, expr, senv, assoc_box); | ||||
|       } | ||||
| 
 | ||||
|       else if (tag == pic->sDEFINE) { | ||||
|         return macroexpand_define(pic, expr, senv, assoc_box); | ||||
|       } | ||||
| 
 | ||||
|       else if (tag == pic->sQUOTE) { | ||||
| 	return pic_cons(pic, car, pic_cdr(pic, expr)); | ||||
|       } | ||||
| 
 | ||||
|       /* macro */ | ||||
|       if ((e = xh_get(&pic->macros, tag)) != NULL) { | ||||
|   pic_value v, args; | ||||
|         struct pic_macro *mac; | ||||
| 
 | ||||
| #if DEBUG | ||||
|   puts("before expand-1:"); | ||||
|  | @ -562,7 +516,6 @@ macroexpand_node(pic_state *pic, pic_value expr, struct pic_senv *senv, pic_valu | |||
|   puts(""); | ||||
| #endif | ||||
| 
 | ||||
|         mac = xh_val(e, struct pic_macro *); | ||||
|   if (mac->senv == NULL) { /* legacy macro */ | ||||
|     args = pic_cdr(pic, expr); | ||||
|   } | ||||
|  | @ -583,6 +536,63 @@ macroexpand_node(pic_state *pic, pic_value expr, struct pic_senv *senv, pic_valu | |||
| #endif | ||||
| 
 | ||||
|   return macroexpand(pic, v, senv, assoc_box); | ||||
| } | ||||
| 
 | ||||
| static pic_value | ||||
| macroexpand_node(pic_state *pic, pic_value expr, struct pic_senv *senv, pic_value assoc_box) | ||||
| { | ||||
| #if DEBUG | ||||
|   printf("[macroexpand] expanding... "); | ||||
|   pic_debug(pic, expr); | ||||
|   puts(""); | ||||
| #endif | ||||
| 
 | ||||
|   switch (pic_type(expr)) { | ||||
|   case PIC_TT_SC: { | ||||
|     return macroexpand(pic, pic_sc(expr)->expr, pic_sc(expr)->senv, assoc_box); | ||||
|   } | ||||
|   case PIC_TT_SYMBOL: { | ||||
|     return pic_symbol_value(macroexpand_symbol(pic, pic_sym(expr), senv, assoc_box)); | ||||
|   } | ||||
|   case PIC_TT_PAIR: { | ||||
|     pic_value car; | ||||
|     struct pic_macro *mac; | ||||
| 
 | ||||
|     if (! pic_list_p(expr)) { | ||||
|       pic_errorf(pic, "cannot macroexpand improper list: ~s", expr); | ||||
|     } | ||||
| 
 | ||||
|     car = macroexpand(pic, pic_car(pic, expr), senv, assoc_box); | ||||
|     if (pic_sym_p(car)) { | ||||
|       pic_sym tag = pic_sym(car); | ||||
| 
 | ||||
|       if (tag == pic->sDEFINE_LIBRARY) { | ||||
|         return macroexpand_deflibrary(pic, expr); | ||||
|       } | ||||
|       else if (tag == pic->sIMPORT) { | ||||
|         return macroexpand_import(pic, expr); | ||||
|       } | ||||
|       else if (tag == pic->sEXPORT) { | ||||
|         return macroexpand_export(pic, expr); | ||||
|       } | ||||
|       else if (tag == pic->sDEFINE_SYNTAX) { | ||||
|         return macroexpand_defsyntax(pic, expr, senv, assoc_box); | ||||
|       } | ||||
|       else if (tag == pic->sDEFINE_MACRO) { | ||||
|         return macroexpand_defmacro(pic, expr, senv); | ||||
|       } | ||||
|       else if (tag == pic->sLAMBDA) { | ||||
|         return macroexpand_lambda(pic, expr, senv, assoc_box); | ||||
|       } | ||||
|       else if (tag == pic->sDEFINE) { | ||||
|         return macroexpand_define(pic, expr, senv, assoc_box); | ||||
|       } | ||||
|       else if (tag == pic->sQUOTE) { | ||||
| 	return pic_cons(pic, car, pic_cdr(pic, expr)); | ||||
|       } | ||||
| 
 | ||||
|       if ((mac = find_macro(pic, tag)) != NULL) { | ||||
|         return macroexpand_macro(pic, mac, expr, senv, assoc_box); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Yuichi Nishiwaki
						Yuichi Nishiwaki