FictionTools/z88dk/src/z80asm/macros.c
// parse #define, #undef and expand macros
parse #define, #undef and expand macros
parse #define #undef and expand macros
static void parse1(str_t *in, str_t *out, str_t *name, str_t *text)
{
	str_set_str(out, in);
	char *p = str_data(in);
	if (*p == '#') {
		p++;
		if (collect_ident(&p, "define")) {
			str_clear(out);
			if (!collect_name(&p, name)) {
				error_syntax();
				return;
			}
			DefMacro *macro = DefMacro_add(str_data(name));
			if (!macro) {
				error_redefined_macro(str_data(name));
				return;
			}
#if 0
			if (!collect_params(&p, macro, text)) {
				error_syntax();
				return;
			}
#endif
			if (!collect_text(&p, macro, text)) {
				error_syntax();
				return;
			}
		}
		else if (collect_ident(&p, "undef")) {
			str_clear(out);
			if (!collect_name(&p, name)) {
				error_syntax();
				return;
			}
			if (!collect_eol(&p)) {
				error_syntax();
				return;
			}
			DefMacro_delete(str_data(name));
		}
		else {
		}
	}
	else {	
		str_clear(out);
		while (*p != '\0') {
			if ((Is_ident_prefix(p[0]) && Is_ident_start(p[1])) ||
				Is_ident_start(p[0])) {
				collect_name(&p, name);
				DefMacro *macro = DefMacro_lookup(str_data(name));
				if (macro)
					macro_expand(macro, &p, out);
				else {
					if (Is_ident_prefix(str_data(name)[0])) {
						str_append_n(out, str_data(name), 1);
						macro = DefMacro_lookup(str_data(name) + 1);
						if (macro)
							macro_expand(macro, &p, out);
						else
							str_append_n(out, str_data(name) + 1, str_len(name) - 1);
					}
					else {
						str_append_n(out, str_data(name), str_len(name));
					}
				}
			}
			else if (*p == '\'' || *p == '"') {
				char q = *p;
				str_append_n(out, p, 1); p++;
				while (*p != q && *p != '\0') {
					if (*p == '\\') {
						str_append_n(out, p, 1); p++;
						if (*p != '\0') {
							str_append_n(out, p, 1); p++;
						}
					}
					else {
						str_append_n(out, p, 1); p++;
					}
				}
				if (*p != '\0') {
					str_append_n(out, p, 1); p++;
				}
			}
			else if (*p == ';') {
				str_append_n(out, "\n", 1); p += strlen(p);		
			}
			else {
				str_append_n(out, p, 1); p++;
			}
		}
		str_set_str(in, out);	
		p = str_data(in);
		if (collect_equ(&p, name)) {
			str_set_f(out, "defc %s = %s", str_data(name), p);
		}
	}
}
static void parse1 ( str_t * in , str_t * out , str_t * name , str_t * text ) { str_set_str ( out , in ) ; char * p = str_data ( in ) ; if ( * p == ' ' ) { p ++ ; if ( collect_ident ( & p , " " ) ) { str_clear ( out ) ; if ( ! collect_name ( & p , name ) ) { error_syntax ( ) ; return ; } DefMacro * macro = DefMacro_add ( str_data ( name ) ) ; if ( ! macro ) { error_redefined_macro ( str_data ( name ) ) ; return ; } #if 0 if ( ! collect_params ( & p , macro , text ) ) { error_syntax ( ) ; return ; } #endif if ( ! collect_text ( & p , macro , text ) ) { error_syntax ( ) ; return ; } } else if ( collect_ident ( & p , " " ) ) { str_clear ( out ) ; if ( ! collect_name ( & p , name ) ) { error_syntax ( ) ; return ; } if ( ! collect_eol ( & p ) ) { error_syntax ( ) ; return ; } DefMacro_delete ( str_data ( name ) ) ; } else { } } else { str_clear ( out ) ; while ( * p != ' \0 ' ) { if ( ( Is_ident_prefix ( p [ 0 ] ) && Is_ident_start ( p [ 1 ] ) ) || Is_ident_start ( p [ 0 ] ) ) { collect_name ( & p , name ) ; DefMacro * macro = DefMacro_lookup ( str_data ( name ) ) ; if ( macro ) macro_expand ( macro , & p , out ) ; else { if ( Is_ident_prefix ( str_data ( name ) [ 0 ] ) ) { str_append_n ( out , str_data ( name ) , 1 ) ; macro = DefMacro_lookup ( str_data ( name ) + 1 ) ; if ( macro ) macro_expand ( macro , & p , out ) ; else str_append_n ( out , str_data ( name ) + 1 , str_len ( name ) - 1 ) ; } else { str_append_n ( out , str_data ( name ) , str_len ( name ) ) ; } } } else if ( * p == ' \' ' || * p == ' ' ) { char q = * p ; str_append_n ( out , p , 1 ) ; p ++ ; while ( * p != q && * p != ' \0 ' ) { if ( * p == ' \\ ' ) { str_append_n ( out , p , 1 ) ; p ++ ; if ( * p != ' \0 ' ) { str_append_n ( out , p , 1 ) ; p ++ ; } } else { str_append_n ( out , p , 1 ) ; p ++ ; } } if ( * p != ' \0 ' ) { str_append_n ( out , p , 1 ) ; p ++ ; } } else if ( * p == ' ' ) { str_append_n ( out , " \n " , 1 ) ; p += strlen ( p ) ; } else { str_append_n ( out , p , 1 ) ; p ++ ; } } str_set_str ( in , out ) ; p = str_data ( in ) ; if ( collect_equ ( & p , name ) ) { str_set_f ( out , " " , str_data ( name ) , p ) ; } } }
parse #define, #undef and expand macros
parse #define #undef and expand macros
// default output = input // get macro name // create macro, error if duplicate // get macro params // get macro text // get macro name // assert end of line // expand macros // maybe at start of macro call // try after prefix // skip comments // check other commands after macro expansion // in = out