In order to work with C's namespace limitations, I've designed the following
system, which makes use of a C language extension -fdollars-in-identifiers
that lets you use dollar signs in identifiers. This extension is supported by
GCC, TinyCC, and Clang.
Unique File Suffixes
Each file gets a unique suffix with the format $<filename>_XXXXXXXX, where the
Xs are 8 randomly chosen identifier characters and <filename> includes only
valid identifier characters up to the first period.
For example, in a file called hello-world.tm, a variable like foo would
become foo$helloworld_VEDjfzDs. This helps avoid namespace conflicts between
two files that define the same symbol.
Namespaces
Dollar signs in identifiers provide a way to have compiled C code which segments
its imports into different namespaces. For example Foo$Baz would be the
identifier Baz in the namespace Foo, and would be guaranteed to not collide
with a user-chosen name like FooBaz or Foo_Baz.
# Namespacing
In order to work with C's namespace limitations, I've designed the following
system, which makes use of a C language extension `-fdollars-in-identifiers`
that lets you use dollar signs in identifiers. This extension is supported by
GCC, TinyCC, and Clang.
## Unique File Suffixes
Each file gets a unique suffix with the format `$<filename>_XXXXXXXX`, where the
Xs are 8 randomly chosen identifier characters and `<filename>` includes only
valid identifier characters up to the first period.
For example, in a file called `hello-world.tm`, a variable like `foo` would
become `foo$helloworld_VEDjfzDs`. This helps avoid namespace conflicts between
two files that define the same symbol.
## Namespaces
Dollar signs in identifiers provide a way to have compiled C code which segments
its imports into different namespaces. For example `Foo$Baz` would be the
identifier `Baz` in the namespace `Foo`, and would be guaranteed to not collide
with a user-chosen name like `FooBaz` or `Foo_Baz`.
## Example
For this Tomo code:
```tomo
//File:foo.tmmy_var:=123structBaz(x:Int)member:=5funcfrob(b:Baz->Int)returnb.xfuncmain()pass```
The generated C source code will look like this:
```C
// File: .build/foo.tm.h
...typedefstructBaz$$struct$foo_VEDjfzDsBaz$$type$foo_VEDjfzDs;structBaz$$struct$foo_VEDjfzDs{Int_tx;};DEFINE_OPTIONAL_TYPE(structBaz$$struct$foo_VEDjfzDs,8,$OptionalBaz$$type$foo_VEDjfzDs);externconstTypeInfo_tBaz$$info$foo_VEDjfzDs;externInt_tBaz$member$foo_VEDjfzDs;Int_tBaz$frob$foo_VEDjfzDs(structBaz$$struct$foo_VEDjfzDs_$b);externInt_tmy_var$foo_VEDjfzDs;voidmain$foo_VEDjfzDs();...``````C
// File: .build/foo.tm.c
...publicInt_tmy_var$foo_VEDjfzDs=I_small(123);publicconstTypeInfo_tBaz$$info$foo_VEDjfzDs={...};publicInt_tBaz$member$foo_VEDjfzDs=I_small(5);publicInt_tBaz$frob$foo_VEDjfzDs(structBaz$$struct$foo_VEDjfzDs_$b){return(_$b).x;}publicvoidmain$foo_VEDjfzDs(){}...```