diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-04-30 20:42:31 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-04-30 20:42:31 -0400 |
| commit | dfedf3f2bb434065da3ddbc931e87a4017535f80 (patch) | |
| tree | 6c7d9e5e35fd4fd612d51285dcae7d6c06b8838a /docs/namespacing.md | |
| parent | 46818674d3588dd15ebca5cb7be4afa8cd485cfe (diff) | |
Update compiler to use randomly generated unique-per-file symbol
suffixes instead of needing to rename symbols with objcopy
Diffstat (limited to 'docs/namespacing.md')
| -rw-r--r-- | docs/namespacing.md | 77 |
1 files changed, 43 insertions, 34 deletions
diff --git a/docs/namespacing.md b/docs/namespacing.md index e9dc428d..42bdd984 100644 --- a/docs/namespacing.md +++ b/docs/namespacing.md @@ -1,15 +1,30 @@ # Namespacing In order to work with C's namespace limitations, I've designed the following -system: +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 -In C, there is a GCC extension (also supported by clang and TCC) to allow for -dollar signs in identifiers. This provides 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`. +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.tm @@ -19,46 +34,40 @@ struct Baz(x:Int) member := 5 func frob(b:Baz -> Int) return b.x + +func main() pass ``` +The generated C source code will look like this: + ```C -// File: foo.tm.h +// File: .build/foo.tm.h ... -typedef struct foo$Baz_s foo$Baz_t; -struct foo$Baz_s { - Int_t $x; +typedef struct Baz$$struct$foo_VEDjfzDs Baz$$type$foo_VEDjfzDs; +struct Baz$$struct$foo_VEDjfzDs { + Int_t x; }; - -extern Int_t foo$my_var; -extern const TypeInfo_t foo$Baz; - -extern Int_t foo$Baz$member; -Int_t foo$Baz$frob(struct foo$Baz_s $b); -void foo$main(); +DEFINE_OPTIONAL_TYPE(struct Baz$$struct$foo_VEDjfzDs, 8,$OptionalBaz$$type$foo_VEDjfzDs); +extern const TypeInfo_t Baz$$info$foo_VEDjfzDs; +extern Int_t Baz$member$foo_VEDjfzDs; +Int_t Baz$frob$foo_VEDjfzDs(struct Baz$$struct$foo_VEDjfzDs _$b); +extern Int_t my_var$foo_VEDjfzDs; +void main$foo_VEDjfzDs(); ... ``` ```C -// File: foo.tm.c +// File: .build/foo.tm.c ... -Int_t foo$my_var = I_small(123); -Int_t foo$Baz$member = I_small(5); - -static Text_t foo$Baz$as_text(foo$Baz_t *obj, bool use_color) -{ - if (!obj) - return "Baz"; - return Texts(use_color ? Text("\x1b[0;1mBaz\x1b[m(") : Text("Baz("), - Int$as_text(stack(obj->$x), use_color, &Int$info), Text(")")); +public Int_t my_var$foo_VEDjfzDs = I_small(123); +public const TypeInfo_t Baz$$info$foo_VEDjfzDs = {...}; +public Int_t Baz$member$foo_VEDjfzDs = I_small(5); + +public Int_t Baz$frob$foo_VEDjfzDs(struct Baz$$struct$foo_VEDjfzDs _$b) { + return (_$b).x; } -public Int_t foo$Baz$frob(struct foo$Baz_s $b) -{ - return ($b).x; +public void main$foo_VEDjfzDs() { } ... ``` - -And on the usage site, the code `include ./foo.tm` compiles to `#include -"./foo.tm.h"` in the header and `use$foo()` in the code that is executed. - |
