implementation module cg_name_mangling; import StdEnv; unmangle_name s :== expand_special_chars s; expand_special_chars :: !String -> String; expand_special_chars s #! limit = size s; #! delta = count_length_of_expanded_string 0 limit s 0 | delta == 0 = s; #! expanded_label_name_limit = limit + delta; #! expanded_label_name = createArray expanded_label_name_limit ' '; = expand_name 0 limit s 0 expanded_label_name where { expand_name :: !Int !Int !String !Int !*{#Char} -> *{#Char}; expand_name i limit s j name | i == limit = name; #! (delta,name) = case s.[i] of { '.' -> (2, { name & [j] = '_', [j+1] = 'P' }); '_' -> (2, { name & [j] = '_', [j+1] = '_' }); '*' -> (2, { name & [j] = '_', [j+1] = 'M' }); '-' -> (2, { name & [j] = '_', [j+1] = 'S' }); '+' -> (2, { name & [j] = '_', [j+1] = 'A' }); '=' -> (2, { name & [j] = '_', [j+1] = 'E' }); '~' -> (2, { name & [j] = '_', [j+1] = 'T' }); '<' -> (2, { name & [j] = '_', [j+1] = 'L' }); '>' -> (2, { name & [j] = '_', [j+1] = 'G' }); '/' -> (2, { name & [j] = '_', [j+1] = 'D' }); '?' -> (2, { name & [j] = '_', [j+1] = 'Q' }); '#' -> (2, { name & [j] = '_', [j+1] = 'H' }); ':' -> (2, { name & [j] = '_', [j+1] = 'C' }); '$' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'D' }); '^' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'C' }); '@' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'T' }); '&' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'A' }); '%' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'P' }); '\'' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'S' }); '\"' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'Q' }); '|' -> (2, { name & [j] = '_', [j+1] = 'O' }); '\\' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'B' }); '`' -> (2, { name & [j] = '_', [j+1] = 'B' }); '!' -> (3, { name & [j] = '_', [j+1] = 'N', [j+2] = 'E' }); ';' -> (2, { name & [j] = '_', [j+1] = 'I' }); c -> (1, { name & [j] = c }); } = expand_name (inc i) limit s (j + delta) name; } mangled_name_length unmangled_name :== count_length_of_expanded_string 0 s_unmangled_name unmangled_name s_unmangled_name; where { s_unmangled_name = size unmangled_name; }; count_length_of_expanded_string :: !Int !Int !String !Int -> Int; count_length_of_expanded_string i limit s l | i == limit = l; #! delta = case s.[i] of { '.' -> 1; '_' -> 1; '*' -> 1; '-' -> 1; '+' -> 1; '=' -> 1; '~' -> 1; '<' -> 1; '>' -> 1; '/' -> 1; '?' -> 1; '#' -> 1; ':' -> 1; '$' -> 2; '^' -> 2; '@' -> 2; '&' -> 2; '%' -> 2; '\'' -> 2; '\"' -> 2; '|' -> 1; '\\' -> 2; '`' -> 1; '!' -> 2; ';' -> 1; _ -> 0 } = count_length_of_expanded_string (inc i) limit s (l + delta); // Labels // Layout: // e____ // Constants mangled_module_name_prefix :== "e__"; s_mangled_module_name_prefix :== size mangled_module_name_prefix; mangled_module_name_suffix :== "__"; s_mangled_module_name_suffix :== size mangled_module_name_suffix; class get_label_prefix_from_label s :: !String !Bool !s -> Char; instance get_label_prefix_from_label Int where { get_label_prefix_from_label label True s_unmangled_name # prefix_start = s_mangled_module_name_prefix + s_unmangled_name + s_mangled_module_name_suffix; # prefix_end = inc prefix_start; = (label % (prefix_start,prefix_end)).[0]; };