summaryrefslogtreecommitdiff
path: root/chapter29/src/main/c/simple_crt.c
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-11-01 10:33:55 -0800
committerCliff Click <cliffc@acm.org>2026-11-01 10:33:55 -0800
commitf4bd723d929e53475f7990374dca7b7dfcbbdc42 (patch)
tree7bb080119e7b88ad4ac9b30af019fe6a5e4ba9dd /chapter29/src/main/c/simple_crt.c
parent0ac0c9e10287972ac3af5a4ee43d26f0d5b318fe (diff)
downloadSimple-f4bd723d929e53475f7990374dca7b7dfcbbdc42.tar.gz
Simple-f4bd723d929e53475f7990374dca7b7dfcbbdc42.zip
Add Chapter 29 for tech debt cleanup with the parser splitmain
Keep Chapter 28b intact and carry the grammar-oriented parser package, Var move, IterPeeps move, and parser regression tests into Chapter 29. Defer privacy and exclude its experimental tests and fixture changes. Register the chapter in the indexes, IntelliJ modules and run configurations, Maven reactor, roadmap, and linear-history publisher. Windows and Linux each pass 573 tests, release builds, 199 allocation replays, and 29 native checks.
Diffstat (limited to 'chapter29/src/main/c/simple_crt.c')
-rw-r--r--chapter29/src/main/c/simple_crt.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/chapter29/src/main/c/simple_crt.c b/chapter29/src/main/c/simple_crt.c
new file mode 100644
index 00000000..8656a3cc
--- /dev/null
+++ b/chapter29/src/main/c/simple_crt.c
@@ -0,0 +1,61 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+// errno may be thread-local or a macro calling a platform accessor.
+int32_t simple_errno(void) { return errno; }
+
+// Native process arguments converted to ordinary Simple array layouts.
+// The outer array is mutable; every contained byte array is published as
+// immutable and non-null to Simple code.
+typedef struct SimpleBytes {
+ uint32_t len;
+ unsigned char bytes[];
+} SimpleBytes;
+
+typedef struct SimpleArgs {
+ uint32_t len;
+ uint32_t pad;
+ SimpleBytes *args[];
+} SimpleArgs;
+
+__attribute__((CALL_CONV))
+extern int64_t simple_main(SimpleArgs *args);
+
+static SimpleArgs *simple_args(int argc, char **argv) {
+ if (argc < 0 || (uint64_t)argc > UINT32_MAX)
+ return NULL;
+
+ SimpleArgs *args = calloc(1, sizeof(*args) + (size_t)argc * sizeof(args->args[0]));
+ if (args == NULL)
+ return NULL;
+ args->len = (uint32_t)argc;
+
+ for (int i = 0; i < argc; i++) {
+ size_t len = strlen(argv[i]);
+ if (len > UINT32_MAX) {
+ free(args);
+ return NULL;
+ }
+ SimpleBytes *str = malloc(sizeof(*str) + len);
+ if (str == NULL) {
+ for (int j = 0; j < i; j++) free(args->args[j]);
+ free(args);
+ return NULL;
+ }
+ str->len = (uint32_t)len;
+ memcpy(str->bytes, argv[i], len);
+ args->args[i] = str;
+ }
+ return args;
+}
+
+int main(int argc, char **argv) {
+ SimpleArgs *args = simple_args(argc, argv);
+ if (args == NULL)
+ return 1;
+ // The language-level hidden receiver is not part of the emitted ABI for
+ // free functions; source argument zero occupies native argument zero.
+ return (int)simple_main(args);
+}