[RFC] Symbol mangling schema

chris hermansen clhermansen@gmail.com
Sun Nov 9 21:32:42 GMT 2025


José and list,

Another thought or two below...


On Sun, Nov 9, 2025, 10:03 Jose E. Marchesi <jemarch@gnu.org> wrote:

>
> Hello people!
>
> The implementation of modules and separated compilation is progressing
> steadily:
>
>   $ cat module.a68
>   module Foo =
>   def int i;
>       int j = 20;
>       proc ticks = void: to i do puts ("tick'n") od;
>       i := 5
>   postlude
>     ticks
>   fed
>   $ cat foo.c
>   #include <stdio.h>
>
>   void __FOO_prelude (void);
>   void __FOO_postlude (void);
>
>   extern void ticks (void);
>   extern int i;
>   extern int j;
>
>   void
>   __algol68_main ()
>   {
>     __FOO_prelude ();
>     ticks ();
>     i = 3;
>     printf ("j: %d\n", j);
>     __FOO_postlude ();
>   }
>   $ ga68 -c module.a68
>   $ gcc -c foo.c
>   $ ga68 module.o foo.o -lga68
>   $ ./a.out
>   tick
>   tick
>   tick
>   tick
>   tick
>   j: 20
>   tick
>   tick
>   tick
>
> Now it is time to decide on a schema for mangling our symbols.  In my
> opinion the schema shall fullfil the following desirable properties:
>
> - It shall be as simple and orthogonal as possible.  In particular, the
>   meaning of symbols shall not depend on their positions.
>
> - It shall lead to readable (by humans) and predictable symbol names.
>   It shouldn't be necessary for a programmer to use a tool in order to
>   figure out the mangled symbol for some given construct.  For example,
>   it is immediate to figure out that the symbol corresponding to an
>   identifier "accountant" defined in a module "Foo" is FOO_accountant.
>
> - The mangling schema shall be as much as compiler-independent as
>   possible.
>
> So this is my proposal:
>
> 1. Symbols used internally do not follow any fixed mangling rule.
>
> 2. The main program symbol is __algol68_main.
>
> 3. Bold words, i.e. mode indicants, module indicants and operator
>    indicants are mangled to upper-case letters and normal digits.  Note
>    that the underscores following taggles supported by the stropping
>    regimes are not part of the indicants, and therefore are not conveyed
>    to mangled symbols.  For example, a mode "Tree_Node" is mangled to
>    TREENODE.
>
> 4. Tags, i.e. identifiers, are mangled to lower-case and normal digits.
>    Again, underscores following taggles are not part of the tag proper,
>    and are not conveyed to mangled symbols.  Fo example, the identifier
>    "remove_row" is mangled to removerow.
>
> 5. Symbols corresponding to publicized identifiers and indicants always
>    start with the name of the definition module publicizing them,
>    followed by an underscore character.  For example, in the module:
>
>      module Json =
>      def
>          pub mode JSON_Val = union
> (void,bool,int,string.JSON_Arr,JSON_Obj),
>          pub mode JSON_Arr = struct (JSON_Elm elements),
>          ...;
>
>          pub proc json_new_obj = JSON_Val: heap JSON_Obj;
>          ...
>      fed
>
>    The mode JSON_Val will mangle to a symbol JSON_JSONVAL.
>    The identifier json_new_obj will mangle to a symbol JSON_jsonnewobj.
>
> 6. Publicized symbols that are intended to be used by the compiler or
>    runtime are preceded by the mangled name of the module followed by
>    two underscore characters.  For example, the prelude and postlude for
>    the above module will be accessible via the mangled symbols
>    JSON__prelude and JSON__postlude.
>
> 7. Operator symbols, the monads and nomads, are mangled to letter codes
>    symbolizing the symbols:
>
>      %    (p)ercentage
>      ^    (c)aret
>      &    (a)mpersand
>      +    (p)lus
>      -    (m)inus
>      ~    (t)ilde
>      !    (b)ang
>      ?    (q)uestion mark
>      >    bi(g)ger than
>      <    (l)ess than
>      /    (s)lash
>      =    (e)qual
>      :    c(o)lon
>      *    sta(r)
>
>    Each letter code is followed by a single underscore character.  So
>    for example, in the following module:
>
>      module Foo =
>      def
>          int ss;
>          op // = (int a, b) int: a + b;
>          ...
>      fed
>
>    The identifier ss will mangle to a symbol FOO_ss.
>    The operator // will mangle to a symbol FOO_s_s_.
>
> And that's basically it.
> WDYT?
>

After thinking about Jose's response on operator priorities and reading the
conversation about operator name mangling, I wonder if it's worth
considering whether the scheme for dealing with overloaded operators could
be extended to procedures or if there is something missing.

This "just in case" someone decides to add procedure overloading down the
road.

In the same spirit, would it be worthwhile thinking about how this scheme
fits with parametrized types, in case those get added later?

Another question that seems obvious is can we have / do we want to have a
hierarchical name space for modules, something like
org.ga68.collections.list?

And the last thing that comes to mind is the OUTTYPE and INTYPE business we
see in transput (and may want elsewhere, depending on how parametrized
types work out) - given that it's not possible to declare MODE OUTTYPE in
Algol68, how could it be exported from a module?

I'm specifically thinking of the Aleph and longsetys but also the way that
for example print() is able to unpack structures and rows of rows and such.
I realize that I am confused as to how much of that unpacking is handled as
code generation vs by some (unnamed?) procedure that "flattens" complex
structures dynamically.

Of course it may be best to leave these kind of things for the next version
of modules...

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/algol68/attachments/20251109/3087e5ee/attachment-0001.htm>


More information about the Algol68 mailing list