## codelabel.pkg
#
# Compiled by:
#
src/lib/compiler/back/low/lib/lowhalf.libpackage codelabel
: Codelabel # Codelabel is from
src/lib/compiler/back/low/code/codelabel.api{
Label_Kind
#
= GLOBAL String
| LOCAL String
| ANONYMOUS
;
Codelabel
=
{ id: Unt,
address: Ref( Int ),
kind: Label_Kind
};
stipulate # Probably 'next_label' should be 'make_label' and 'count' should be 'next_label_id'. XXX SUCKO FIXME.
count = REF 0u0; # XXX BUGGO FIXME More icky thread-hostile mutable global state. :-( :-(
herein # We should initialize to 1 not 0 here -- then clients like
src/lib/compiler/back/low/main/main/translate-nextcode-to-treecode-g.pkg # which currently use f vs -f-1 for private/public labels (because -0==0) could just use f vs -f. I haven't done this yet because
# I don't know how many files are using the f vs -f-1 hack.
# (Odd vs even ids would be another hack, but testing for public vs private would be slower.) -- 2011-08-15 CrT XXX SUCKO FIXME.
fun set_count_to_zero ()
=
count := 0u0;
fun next_label kind
=
{ id = *count;
count := id + 0u1;
{ id, address => REF -1, kind };
};
end;
# Make a global label # This fn is NOWHERE INVOKED.
#
fun make_global_codelabel name
=
next_label (GLOBAL name);
# Make a label generator; note that if the prefix string is "",
# then the standard prefix "L" will be used.
#
fun make_codelabel_generator ""
=>
make_codelabel_generator "L";
make_codelabel_generator prefix
=>
{ kind = LOCAL prefix;
{. next_label kind; };
};
end;
fun make_anonymous_codelabel ()
=
next_label ANONYMOUS;
# Codelabel equality, comparisons, and hashing:
#
fun same_codelabel
(
l1: Codelabel,
l2: Codelabel
)
=
l1.id == l2.id;
fun compare_codelabels # This fn is NOWHERE INVOKED.
(
l1: Codelabel,
l2: Codelabel
)
=
unt::compare (l1.id, l2.id);
fun codelabel_to_hashcode (l: Codelabel)
=
l.id;
# Codelabel addresses:
#
exception GLOBAL_LABEL;
#
fun set_codelabel_address ( { id, address, kind=>GLOBAL _}, _) => raise exception GLOBAL_LABEL;
set_codelabel_address ( { id, address, kind }, a) => address := a;
end;
#
fun get_codelabel_address { id, address, kind=>GLOBAL _} => raise exception GLOBAL_LABEL;
get_codelabel_address { id, address, kind } => *address;
end;
# Return a string representation of the label.
#
# This function is meant for debugging --
# use the fmt function for assembly output.
#
fun codelabel_to_string { id, address, kind => GLOBAL name } => name;
codelabel_to_string { id, address, kind => LOCAL prefix } => prefix + unt::to_string id;
codelabel_to_string { id, address, kind => ANONYMOUS } => ".L" + unt::to_string id;
end;
# Format a label for assembly output.
#
# 'global_symbol_prefix': the target ABI's prefix
# for global symbols
# (e.g., "_" or "")
#
# 'anonymous_label_prefix': the target assembler's prefix
# for anonymous labels.
#
# Local labels are emitted using
# their specified prefix:
#
fun codelabel_format_for_asm { global_symbol_prefix, anonymous_label_prefix }
=
to_string
where
fun to_string { id, address, kind=>GLOBAL name } => global_symbol_prefix + name;
to_string { id, address, kind=>LOCAL prefix } => prefix + unt::to_string id;
to_string { id, address, kind=>ANONYMOUS } => anonymous_label_prefix + unt::to_string id;
end;
end;
};