sbool ctxExpandMacros_debug; static S ctxExpandMacros(S s, SS macros) { while true { S s2 = ctxExpandMacros_step(s, macros); if (eq(s, s2)) ret s; s = s2; } } static S ctxExpandMacros_step(S s, SS macros) { Matcher m = regexp("#([A-Z_0-9]+)#", s); while (m.find()) { if (ctxExpandMacros_debug) print("Replacing " + m.group(1)); S key = m.group(1); S macro = macros.get(key); if (macro == null) macro = "#\\\"\\+\\?@"; s = s.replace(m.group(), macro); } ret s; }