nomen-lang 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/NOMEN_AGENTS.md +235 -0
  2. package/core/System/Ansi.nm +150 -0
  3. package/core/System/Array.nm +358 -0
  4. package/core/System/BigInt.nm +887 -0
  5. package/core/System/Buffer.nm +526 -0
  6. package/core/System/Channel.nm +198 -0
  7. package/core/System/ClassBuffer.nm +229 -0
  8. package/core/System/Console.nm +211 -0
  9. package/core/System/Controls/Button.nm +138 -0
  10. package/core/System/Controls/CheckBox.nm +158 -0
  11. package/core/System/Controls/Container.nm +1562 -0
  12. package/core/System/Controls/Control.nm +28 -0
  13. package/core/System/Controls/Geometry.nm +101 -0
  14. package/core/System/Controls/Layout.nm +228 -0
  15. package/core/System/Controls/LayoutParams.nm +50 -0
  16. package/core/System/Controls/Text.nm +129 -0
  17. package/core/System/Controls/TextBox.nm +157 -0
  18. package/core/System/Controls/Window.nm +280 -0
  19. package/core/System/Disposable.nm +8 -0
  20. package/core/System/Enumerable.nm +10 -0
  21. package/core/System/Equatable.nm +10 -0
  22. package/core/System/Graph.nm +68 -0
  23. package/core/System/Hashable.nm +13 -0
  24. package/core/System/Init.nm +21 -0
  25. package/core/System/LinkedList.nm +64 -0
  26. package/core/System/List.nm +44 -0
  27. package/core/System/Map.nm +153 -0
  28. package/core/System/Math.nm +54 -0
  29. package/core/System/Mutex.nm +78 -0
  30. package/core/System/Nursery.nm +27 -0
  31. package/core/System/Sendable.nm +9 -0
  32. package/core/System/Set.nm +97 -0
  33. package/core/System/Stream/Directory.nm +176 -0
  34. package/core/System/Stream/File.nm +432 -0
  35. package/core/System/Stream/Http.nm +453 -0
  36. package/core/System/String.nm +154 -0
  37. package/core/System/StringBuilder.nm +249 -0
  38. package/core/System/Stringable.nm +8 -0
  39. package/core/System/Task.nm +263 -0
  40. package/core/System/Test.nm +241 -0
  41. package/core/System/Text/Json.nm +377 -0
  42. package/core/System/Text/JsonTree.nm +187 -0
  43. package/core/System/Text/Regex.nm +655 -0
  44. package/core/System/Time.nm +112 -0
  45. package/core/System/Tree.nm +70 -0
  46. package/core/System/Viewable.nm +27 -0
  47. package/core/System/bool.nm +66 -0
  48. package/core/System/char.nm +42 -0
  49. package/core/System/float.nm +43 -0
  50. package/core/System/int.nm +54 -0
  51. package/core/System/int64.nm +42 -0
  52. package/core/System/int8.nm +42 -0
  53. package/core/System/uint.nm +42 -0
  54. package/core/System/uint64.nm +42 -0
  55. package/core/System/uint8.nm +42 -0
  56. package/core/docs/System/Ansi.md +40 -0
  57. package/core/docs/System/Array.md +16 -0
  58. package/core/docs/System/BigInt.md +30 -0
  59. package/core/docs/System/Buffer.md +31 -0
  60. package/core/docs/System/Channel.md +10 -0
  61. package/core/docs/System/ClassBuffer.md +15 -0
  62. package/core/docs/System/Console.md +13 -0
  63. package/core/docs/System/Controls/Button.md +12 -0
  64. package/core/docs/System/Controls/CheckBox.md +15 -0
  65. package/core/docs/System/Controls/Container.md +82 -0
  66. package/core/docs/System/Controls/Control.md +5 -0
  67. package/core/docs/System/Controls/Geometry.md +26 -0
  68. package/core/docs/System/Controls/Layout.md +37 -0
  69. package/core/docs/System/Controls/LayoutParams.md +13 -0
  70. package/core/docs/System/Controls/Text.md +12 -0
  71. package/core/docs/System/Controls/TextBox.md +13 -0
  72. package/core/docs/System/Controls/Window.md +20 -0
  73. package/core/docs/System/Disposable.md +5 -0
  74. package/core/docs/System/Enumerable.md +5 -0
  75. package/core/docs/System/Graph.md +17 -0
  76. package/core/docs/System/Init.md +9 -0
  77. package/core/docs/System/LinkedList.md +16 -0
  78. package/core/docs/System/List.md +13 -0
  79. package/core/docs/System/Map.md +14 -0
  80. package/core/docs/System/Math.md +11 -0
  81. package/core/docs/System/Mutex.md +10 -0
  82. package/core/docs/System/Nursery.md +5 -0
  83. package/core/docs/System/Sendable.md +5 -0
  84. package/core/docs/System/Set.md +14 -0
  85. package/core/docs/System/Stream/Directory.md +12 -0
  86. package/core/docs/System/Stream/File.md +21 -0
  87. package/core/docs/System/String.md +14 -0
  88. package/core/docs/System/StringBuilder.md +12 -0
  89. package/core/docs/System/Stringable.md +5 -0
  90. package/core/docs/System/Task.md +15 -0
  91. package/core/docs/System/Text/Json.md +12 -0
  92. package/core/docs/System/Text/JsonTree.md +21 -0
  93. package/core/docs/System/Text/Regex.md +12 -0
  94. package/core/docs/System/Time.md +11 -0
  95. package/core/docs/System/Tree.md +18 -0
  96. package/core/docs/System/Viewable.md +5 -0
  97. package/core/docs/System/bool.md +9 -0
  98. package/core/docs/System/char.md +9 -0
  99. package/core/docs/System/float.md +9 -0
  100. package/core/docs/System/int.md +10 -0
  101. package/core/docs/System/int64.md +9 -0
  102. package/core/docs/System/int8.md +9 -0
  103. package/core/docs/System/uint.md +9 -0
  104. package/core/docs/System/uint64.md +9 -0
  105. package/core/docs/System/uint8.md +9 -0
  106. package/core/package.jsonc +4 -0
  107. package/dist/index.mjs +417 -5490
  108. package/package.json +33 -30
  109. package/src/args.ts +171 -0
  110. package/src/index.ts +53 -104
  111. package/src/init.ts +128 -0
  112. package/src/test.ts +6 -2
  113. package/test/fixtures/build/calc.test +0 -0
  114. package/test/fixtures/build/calc.test.c +0 -969
  115. package/test/fixtures/build/main.h +0 -170
  116. package/test/fixtures/calc.test.nm +0 -32
  117. package/tsconfig.json +0 -21
  118. package/vite.config.ts +0 -7
@@ -0,0 +1,229 @@
1
+ // ClassBuffer<T>: a flat buffer of owned class pointers of type T. The
2
+ // class-ness is compile-time: #destroy calls the monomorphized element destroy
3
+ // (`T_destroy` -> e.g. Animal_destroy) directly, and store_int/replace_int
4
+ // forbid 0 (you can't overwrite a pointer with null and leak it — use move_int
5
+ // to relinquish a slot). T must be a class. Buffer<T> is the value counterpart.
6
+
7
+ /**
8
+ * A flat buffer of owned class pointers of type T — the backing store for collections of classes
9
+ **/
10
+ pub struct ClassBuffer<T> {
11
+ var uint64 data = 0
12
+ var cap = 0
13
+
14
+ func alloc_int = (ref self, int size, out int: out >= size) {
15
+ ```
16
+ #arch: c
17
+ self->cap = size;
18
+ self->data = (unsigned long long)(long*)calloc(size, sizeof(long));
19
+ return self->cap;
20
+ ```
21
+ ```
22
+ #arch: aarch64
23
+ str x1, [x19, #16]
24
+ mov x0, x1
25
+ mov x1, #8
26
+ bl _calloc
27
+ str x0, [x19, #8]
28
+ ldr x0, [x19, #16]
29
+ ```
30
+ }
31
+
32
+ func grow_int = (ref self, int needed, out int: out >= needed) {
33
+ ```
34
+ #arch: c
35
+ if (self->cap >= needed) return self->cap;
36
+ int new_cap = self->cap;
37
+ if (new_cap == 0) new_cap = 4;
38
+ while (new_cap < needed) new_cap *= 2;
39
+ self->data = (unsigned long long)(long*)realloc((long*)(unsigned long long)self->data, new_cap * sizeof(long));
40
+ memset((long*)(unsigned long long)self->data + self->cap, 0, (new_cap - self->cap) * sizeof(long));
41
+ self->cap = new_cap;
42
+ return self->cap;
43
+ ```
44
+ ```
45
+ #arch: aarch64
46
+ ldr x2, [x19, #16]
47
+ cmp x2, x1
48
+ b.ge .Lcb_grow_end
49
+ mov x3, #4
50
+ cmp x2, #0
51
+ csel x3, x3, x2, eq
52
+ cmp x3, x1
53
+ b.ge .Lcb_grow_got
54
+ .Lcb_grow_loop:
55
+ lsl x3, x3, #1
56
+ cmp x3, x1
57
+ b.lt .Lcb_grow_loop
58
+ .Lcb_grow_got:
59
+ sub sp, sp, #16
60
+ str x2, [sp, #0]
61
+ str x3, [sp, #8]
62
+ ldr x0, [x19, #8]
63
+ lsl x1, x3, #3
64
+ bl _realloc
65
+ str x0, [x19, #8]
66
+ ldr x2, [sp, #0]
67
+ ldr x3, [sp, #8]
68
+ add sp, sp, #16
69
+ str x3, [x19, #16]
70
+ add x0, x0, x2, lsl #3
71
+ mov x1, #0
72
+ sub x2, x3, x2
73
+ lsl x2, x2, #3
74
+ bl _memset
75
+ .Lcb_grow_end:
76
+ ldr x0, [x19, #16]
77
+ ```
78
+ }
79
+
80
+ inline func load_int = (self, int i: i >= 0 && i < self.cap, out int) {
81
+ ```
82
+ #arch: c
83
+ return ((long*)(unsigned long long)self->data)[i];
84
+ ```
85
+ ```
86
+ #arch: aarch64
87
+ ldr x0, [x19, #8]
88
+ lsl x1, x1, #3
89
+ add x0, x0, x1
90
+ ldr x0, [x0]
91
+ ```
92
+ }
93
+
94
+ inline func store_int = (ref self, int i: i >= 0 && i < self.cap, int val: val != 0) {
95
+ ```
96
+ #arch: c
97
+ ((long*)(unsigned long long)self->data)[i] = val;
98
+ ```
99
+ ```
100
+ #arch: aarch64
101
+ ldr x0, [x19, #8]
102
+ lsl x3, x1, #3
103
+ add x0, x0, x3
104
+ str x2, [x0]
105
+ ```
106
+ }
107
+
108
+ inline func move_int = (ref self, int i: i >= 0 && i < self.cap, out int) {
109
+ ```
110
+ #arch: c
111
+ long *slots = (long*)(unsigned long long)self->data;
112
+ long val = slots[i];
113
+ slots[i] = 0;
114
+ return val;
115
+ ```
116
+ ```
117
+ #arch: aarch64
118
+ ldr x0, [x19, #8]
119
+ lsl x3, x1, #3
120
+ add x3, x0, x3
121
+ ldr x0, [x3]
122
+ str xzr, [x3]
123
+ ```
124
+ }
125
+
126
+ // Store into a slot, freeing the previous value (it is an owned class
127
+ // pointer): run its destroy then free it before overwriting.
128
+ func replace_int = (ref self, int i: i >= 0 && i < self.cap, int val: val != 0) {
129
+ ```
130
+ #arch: c
131
+ long *slots = (long*)(unsigned long long)self->data;
132
+ if (slots[i]) {
133
+ T_destroy((void*)slots[i]);
134
+ free((void*)slots[i]);
135
+ }
136
+ slots[i] = val;
137
+ ```
138
+ ```
139
+ #arch: aarch64
140
+ stp x20, x21, [sp, #-16]!
141
+ str x22, [sp, #-16]!
142
+ ldr x0, [x19, #8]
143
+ lsl x3, x1, #3
144
+ add x21, x0, x3
145
+ mov x20, x2
146
+ ldr x0, [x21]
147
+ cbz x0, .Lcb_replace_store
148
+ mov x22, x0
149
+ bl T_destroy
150
+ mov x0, x22
151
+ bl _free
152
+ .Lcb_replace_store:
153
+ str x20, [x21]
154
+ ldr x22, [sp], #16
155
+ ldp x20, x21, [sp], #16
156
+ ```
157
+ }
158
+
159
+ // A non-owning (ptr, len) slice [start, end) over this buffer's class
160
+ // pointers, returned as a `view T` (T is a class, so each element is an
161
+ // 8-byte pointer). Borrows from self — invalidated on reassignment. Mirrors
162
+ // Buffer.slice; ClassBuffer stores 8-byte slots, so the element width is 8.
163
+ func slice = (self, int start: start >= 0, int end: end >= start, out view T) {
164
+ ```
165
+ #arch: c
166
+ nomen_view _r;
167
+ _r.ptr = (void*)((long*)(unsigned long long)self->data + start);
168
+ _r.len = (long)(end - start);
169
+ return _r;
170
+ ```
171
+ ```
172
+ #arch: aarch64
173
+ // x19 = self (ClassBuffer struct ptr), x1 = start, x2 = end.
174
+ // self->data at [x19, #8]. Return (ptr, len) in x0/x1.
175
+ ldr x0, [x19, #8]
176
+ mov x3, #8
177
+ madd x0, x1, x3, x0
178
+ sub x1, x2, x1
179
+ ```
180
+ }
181
+
182
+ func #destroy = () {
183
+ ```
184
+ #arch: c
185
+ if (self->data) {
186
+ long *slots = (long*)(unsigned long long)self->data;
187
+ for (int i = 0; i < self->cap; i++) {
188
+ if (slots[i]) {
189
+ T_destroy((void*)slots[i]);
190
+ free((void*)slots[i]);
191
+ }
192
+ }
193
+ free(slots);
194
+ }
195
+ ```
196
+ ```
197
+ #arch: aarch64
198
+ ldr x0, [x19, #8]
199
+ cbz x0, .Lcb_destroy_end
200
+ stp x20, x21, [sp, #-16]!
201
+ str x22, [sp, #-16]!
202
+ mov x20, x0
203
+ ldr x21, [x19, #16]
204
+ mov x22, #0
205
+ .Lcb_destroy_loop:
206
+ cmp x22, x21
207
+ b.ge .Lcb_destroy_done
208
+ ldr x0, [x20, x22, lsl #3]
209
+ cbz x0, .Lcb_destroy_skip
210
+ str x0, [sp, #-16]!
211
+ bl T_destroy
212
+ ldr x0, [sp], #16
213
+ bl _free
214
+ .Lcb_destroy_skip:
215
+ add x22, x22, #1
216
+ b .Lcb_destroy_loop
217
+ .Lcb_destroy_done:
218
+ ldr x22, [sp], #16
219
+ ldp x20, x21, [sp], #16
220
+ .Lcb_destroy_end:
221
+ ldr x0, [x19, #8]
222
+ cbz x0, .Lcb_destroy_free_done
223
+ bl _free
224
+ .Lcb_destroy_free_done:
225
+ str xzr, [x19, #8]
226
+ str xzr, [x19, #16]
227
+ ```
228
+ }
229
+ }
@@ -0,0 +1,211 @@
1
+ /**
2
+ * The standard console — writing text to, and reading input from, the terminal
3
+ **/
4
+ pub struct Console {
5
+ pub func write = (string line) {
6
+ ```
7
+ #arch: c
8
+ printf("%s", line);
9
+ ```
10
+ ```
11
+ #arch: aarch64
12
+ sub sp, sp, #16
13
+ mov x1, x0
14
+ str x1, [sp]
15
+ adr x0, .Lfmt_console_s
16
+ bl _printf
17
+ add sp, sp, #16
18
+ b .Lend_Console_write
19
+ .Lfmt_console_s: .asciz "%s"
20
+ .p2align 2
21
+ .Lend_Console_write:
22
+ ```
23
+ }
24
+
25
+ pub func write_line = (string line) {
26
+ ```
27
+ #arch: c
28
+ printf("%s\n", line);
29
+ ```
30
+ ```
31
+ #arch: aarch64
32
+ sub sp, sp, #16
33
+ mov x1, x0
34
+ str x1, [sp]
35
+ adr x0, .Lfmt_console_snl
36
+ bl _printf
37
+ add sp, sp, #16
38
+ b .Lend_Console_write_line
39
+ .Lfmt_console_snl: .asciz "%s\n"
40
+ .p2align 2
41
+ .Lend_Console_write_line:
42
+ ```
43
+ }
44
+
45
+ pub func read_line = (out string) {
46
+ ```
47
+ #arch: c
48
+ int cap = 16;
49
+ int len = 0;
50
+ char *buf = (char*)malloc(cap);
51
+ int c = getchar();
52
+ while (c != EOF && c != '\n') {
53
+ if (len + 2 > cap) {
54
+ cap *= 2;
55
+ buf = (char*)realloc(buf, cap);
56
+ }
57
+ buf[len++] = (char)c;
58
+ c = getchar();
59
+ }
60
+ buf[len] = 0;
61
+ return buf;
62
+ ```
63
+ ```
64
+ #arch: aarch64
65
+ sub sp, sp, #32
66
+ mov x0, #16
67
+ bl _malloc
68
+ str x0, [sp, #0]
69
+ mov x1, #16
70
+ str x1, [sp, #8]
71
+ str xzr, [sp, #16]
72
+ bl _getchar
73
+ str w0, [sp, #24]
74
+ .Lconsole_readline_loop:
75
+ ldr w0, [sp, #24]
76
+ cmp w0, #0
77
+ blt .Lconsole_readline_done
78
+ cmp w0, #10
79
+ beq .Lconsole_readline_done
80
+ ldr x0, [sp, #16]
81
+ add x0, x0, #1
82
+ ldr x1, [sp, #8]
83
+ cmp x0, x1
84
+ ble .Lconsole_readline_store
85
+ ldr x1, [sp, #8]
86
+ lsl x1, x1, #1
87
+ str x1, [sp, #8]
88
+ ldr x0, [sp, #0]
89
+ bl _realloc
90
+ str x0, [sp, #0]
91
+ .Lconsole_readline_store:
92
+ ldr x0, [sp, #0]
93
+ ldr x1, [sp, #16]
94
+ ldr w2, [sp, #24]
95
+ strb w2, [x0, x1]
96
+ ldr x0, [sp, #16]
97
+ add x0, x0, #1
98
+ str x0, [sp, #16]
99
+ bl _getchar
100
+ str w0, [sp, #24]
101
+ b .Lconsole_readline_loop
102
+ .Lconsole_readline_done:
103
+ ldr x0, [sp, #0]
104
+ ldr x1, [sp, #16]
105
+ strb wzr, [x0, x1]
106
+ ldr x0, [sp, #0]
107
+ add sp, sp, #32
108
+ b .return_Console_read_line
109
+ ```
110
+ return ""
111
+ }
112
+
113
+ pub func read_char = (out char) {
114
+ ```
115
+ #arch: c
116
+ return (char)getchar();
117
+ ```
118
+ ```
119
+ #arch: aarch64
120
+ bl _getchar
121
+ ```
122
+ }
123
+
124
+ pub func platform = (out string) {
125
+ ```
126
+ #arch: c
127
+ #platform: macos
128
+ return strdup("macos");
129
+ ```
130
+ ```
131
+ #arch: c
132
+ #platform: ios
133
+ return strdup("ios");
134
+ ```
135
+ ```
136
+ #arch: c
137
+ #platform: linux
138
+ return strdup("linux");
139
+ ```
140
+ ```
141
+ #arch: c
142
+ #platform: android
143
+ return strdup("android");
144
+ ```
145
+ ```
146
+ #arch: c
147
+ #platform: windows
148
+ return strdup("windows");
149
+ ```
150
+ ```
151
+ #arch: c
152
+ #platform: web
153
+ return strdup("web");
154
+ ```
155
+ ```
156
+ #arch: aarch64
157
+ #platform: macos
158
+ adr x0, .Lconsole_plat_macos
159
+ bl _strdup
160
+ b .return_Console_platform
161
+ .Lconsole_plat_macos: .asciz "macos"
162
+ .p2align 2
163
+ ```
164
+ ```
165
+ #arch: aarch64
166
+ #platform: ios
167
+ adr x0, .Lconsole_plat_ios
168
+ bl _strdup
169
+ b .return_Console_platform
170
+ .Lconsole_plat_ios: .asciz "ios"
171
+ .p2align 2
172
+ ```
173
+ ```
174
+ #arch: aarch64
175
+ #platform: linux
176
+ adr x0, .Lconsole_plat_linux
177
+ bl _strdup
178
+ b .return_Console_platform
179
+ .Lconsole_plat_linux: .asciz "linux"
180
+ .p2align 2
181
+ ```
182
+ ```
183
+ #arch: aarch64
184
+ #platform: android
185
+ adr x0, .Lconsole_plat_android
186
+ bl _strdup
187
+ b .return_Console_platform
188
+ .Lconsole_plat_android: .asciz "android"
189
+ .p2align 2
190
+ ```
191
+ ```
192
+ #arch: aarch64
193
+ #platform: windows
194
+ adr x0, .Lconsole_plat_windows
195
+ bl _strdup
196
+ b .return_Console_platform
197
+ .Lconsole_plat_windows: .asciz "windows"
198
+ .p2align 2
199
+ ```
200
+ ```
201
+ #arch: aarch64
202
+ #platform: web
203
+ adr x0, .Lconsole_plat_web
204
+ bl _strdup
205
+ b .return_Console_platform
206
+ .Lconsole_plat_web: .asciz "web"
207
+ .p2align 2
208
+ ```
209
+ return ""
210
+ }
211
+ }
@@ -0,0 +1,138 @@
1
+ /**
2
+ * A push-button control that triggers an action when clicked
3
+ **/
4
+ pub class Button : Control {
5
+ var uint64 handle = 0
6
+
7
+ pub func #init = (self, Window window, string title) {
8
+ ```
9
+ #arch: c, aarch64_use_c
10
+ #platform: macos
11
+ id btn = ((id(*)(id, SEL, CGRect))objc_msgSend)(
12
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("NSButton"), sel_registerName("alloc")),
13
+ sel_registerName("initWithFrame:"),
14
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 100, 32));
15
+ ((void(*)(id, SEL, unsigned long))objc_msgSend)(
16
+ btn, sel_registerName("setButtonType:"), 1); // NSPushInButton = 1 (momentary push)
17
+ ((void(*)(id, SEL, id))objc_msgSend)(
18
+ btn, sel_registerName("setTitle:"),
19
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
20
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title));
21
+ id contentView = ((id(*)(id, SEL))objc_msgSend)(
22
+ (id)window->handle, sel_registerName("contentView"));
23
+ ((void(*)(id, SEL, id))objc_msgSend)(
24
+ contentView, sel_registerName("addSubview:"), btn);
25
+ self->handle = (uint64_t)btn;
26
+ ```
27
+ ```
28
+ #arch: c, aarch64_use_c
29
+ #platform: ios
30
+ id btn = ((id(*)(id, SEL, CGRect))objc_msgSend)(
31
+ ((id(*)(id, SEL))objc_msgSend)((id)objc_getClass("UIButton"), sel_registerName("alloc")),
32
+ sel_registerName("initWithFrame:"),
33
+ ((CGRect(*)(double, double, double, double))CGRectMake)(0, 0, 100, 32));
34
+ ((void(*)(id, SEL, unsigned long, id, id))objc_msgSend)(
35
+ btn, sel_registerName("setTitle:forState:"),
36
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
37
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title),
38
+ 0); // UIControlStateNormal = 0
39
+ id parentView = ((id(*)(id, SEL))objc_msgSend)(
40
+ ((id(*)(id, SEL))objc_msgSend)(
41
+ (id)window->handle, sel_registerName("rootViewController")),
42
+ sel_registerName("view"));
43
+ ((void(*)(id, SEL, id))objc_msgSend)(
44
+ parentView, sel_registerName("addSubview:"), btn);
45
+ self->handle = (uint64_t)btn;
46
+ ```
47
+ }
48
+
49
+ pub func set_frame = (ref self, int x, int y, int width, int height) {
50
+ ```
51
+ #arch: c, aarch64_use_c
52
+ #platform: macos
53
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
54
+ (id)self->handle, sel_registerName("setFrame:"),
55
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
56
+ ```
57
+ ```
58
+ #arch: c, aarch64_use_c
59
+ #platform: ios
60
+ ((void(*)(id, SEL, CGRect))objc_msgSend)(
61
+ (id)self->handle, sel_registerName("setFrame:"),
62
+ ((CGRect(*)(double, double, double, double))CGRectMake)((double)x, (double)y, (double)width, (double)height));
63
+ ```
64
+ }
65
+
66
+ pub func set_title = (self, string title) {
67
+ ```
68
+ #arch: c, aarch64_use_c
69
+ #platform: macos
70
+ ((void(*)(id, SEL, id))objc_msgSend)(
71
+ (id)self->handle, sel_registerName("setTitle:"),
72
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
73
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title));
74
+ ```
75
+ ```
76
+ #arch: c, aarch64_use_c
77
+ #platform: ios
78
+ ((void(*)(id, SEL, unsigned long, id, id))objc_msgSend)(
79
+ (id)self->handle, sel_registerName("setTitle:forState:"),
80
+ ((id(*)(id, SEL, const char*))objc_msgSend)(
81
+ (id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), title),
82
+ 0); // UIControlStateNormal = 0
83
+ ```
84
+ }
85
+
86
+ // ── Control trait conformance ──
87
+ // A button sizes to its native intrinsic content size (title + chrome);
88
+ // `measure` clamps that to the box constraints. The native query goes
89
+ // through the shared `native_intrinsic` FFI (see Container.nm), which works
90
+ // on both backends — a per-control raw block couldn't return a `Size` from
91
+ // the aarch64 companion (struct-name mangling) nor mutate a Nomen local.
92
+
93
+ pub func intrinsic_size = (self, out Size) {
94
+ var [w, h] = native_intrinsic(self.handle)
95
+ var Size s = Size()
96
+ s.width = w
97
+ s.height = h
98
+ return s
99
+ }
100
+
101
+ pub func measure = (self, BoxConstraints constraints, out Size) {
102
+ var Size s = self.intrinsic_size()
103
+ if s.width > constraints.max_width {
104
+ s.width = constraints.max_width
105
+ }
106
+ if s.width < constraints.min_width {
107
+ s.width = constraints.min_width
108
+ }
109
+ if s.height > constraints.max_height {
110
+ s.height = constraints.max_height
111
+ }
112
+ if s.height < constraints.min_height {
113
+ s.height = constraints.min_height
114
+ }
115
+ return s
116
+ }
117
+
118
+ func #destroy = () {
119
+ ```
120
+ #arch: c, aarch64_use_c
121
+ #platform: macos
122
+ if (self->handle) {
123
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
124
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
125
+ self->handle = 0;
126
+ }
127
+ ```
128
+ ```
129
+ #arch: c, aarch64_use_c
130
+ #platform: ios
131
+ if (self->handle) {
132
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("removeFromSuperview"));
133
+ ((void(*)(id, SEL))objc_msgSend)((id)self->handle, sel_registerName("release"));
134
+ self->handle = 0;
135
+ }
136
+ ```
137
+ }
138
+ }