aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-03-18 13:06:38 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-03-18 13:06:38 -0400
commita8e328c015c71f7f835b5b863413d0667fa29327 (patch)
treece79fe0e91f3491bfe318d84b9abfc20c6df80b9
parentf4593bff6c242a9feead2ccefc7412b089ce6e1c (diff)
Add namespacing doc
-rw-r--r--docs/namespacing.md61
1 files changed, 61 insertions, 0 deletions
diff --git a/docs/namespacing.md b/docs/namespacing.md
new file mode 100644
index 00000000..e4d023ec
--- /dev/null
+++ b/docs/namespacing.md
@@ -0,0 +1,61 @@
+# Namespacing
+
+In order to work with C's namespace limitations, I've designed the following
+system:
+
+## 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`.
+
+```
+// File: foo.nl
+struct Baz(x:Int)
+ member := 5
+ func frob(b:Baz)->Int
+ return b.x
+
+qux := "Loaded!"
+say(qux)
+
+// File: foo.nl.h
+...
+typedef struct foo$Baz_s foo$Baz_t;
+#define foo$Baz(...) (foo$Baz_t){__VA_ARGS__}
+struct foo$Baz_s {
+ Int_t x;
+};
+extern Int_t foo$Baz$member;
+Int_t foo$Baz$frob(foo$Baz_t b);
+...
+
+// File: foo.nl.c
+#include "foo.nl.h"
+Int_t foo$Baz$member = 5;
+
+Int_t foo$Baz$frob(foo$Baz_t b) {
+ return b.x;
+}
+
+void use$foo(void) {
+ static enum {UNLOADED, LOADING, LOADED} $state = UNLOADED;
+ if ($state == LOADING)
+ fail("Circular import");
+ else if ($state == LOADED)
+ return;
+
+ $state = LOADING;
+ { // Top-level code:
+ Str qux = "Loaded!";
+ say(qux);
+ }
+ $state = LOADED;
+}
+```
+
+And on the usage site, the code `use ./foo.tm` compiles to `#include
+"./foo.tm.h"` in the header and `use$foo()` in the code that is executed.
+