aboutsummaryrefslogtreecommitdiff
path: root/docs/namespacing.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/namespacing.md')
-rw-r--r--docs/namespacing.md77
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.
-