mt-lang 0.3.4 → 0.3.5
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.
- checksums.yaml +4 -4
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/c_backend/feature_detection.rb +27 -55
- data/lib/milk_tea/core/c_backend/format_helpers.rb +551 -0
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +0 -542
- data/lib/milk_tea/core/c_backend/type_collectors.rb +51 -204
- data/lib/milk_tea/core/c_backend.rb +2 -0
- data/lib/milk_tea/core/compatibility_helpers.rb +1 -1
- data/lib/milk_tea/core/lowering/async/lowering.rb +147 -141
- data/lib/milk_tea/core/lowering/block.rb +759 -725
- data/lib/milk_tea/core/lowering/expressions.rb +94 -0
- data/lib/milk_tea/core/lowering/loops.rb +49 -0
- data/lib/milk_tea/core/lowering/resolve.rb +221 -214
- data/lib/milk_tea/core/lowering/utils.rb +0 -222
- data/lib/milk_tea/core/module_loader.rb +29 -48
- data/lib/milk_tea/core/parser/declarations.rb +2 -2
- data/lib/milk_tea/core/parser/recovery.rb +1 -1
- data/lib/milk_tea/core/parser.rb +1 -1
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +3 -120
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +116 -113
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +346 -343
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +37 -12
- data/lib/milk_tea/core/types/predicates.rb +501 -499
- data/lib/milk_tea/core/types/visitor.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ba5797b3cf3ff504321adf78e281c017a4ca3aa30088f5d472c01fe157f7b4f
|
|
4
|
+
data.tar.gz: f1b7c0dd477f0e0868e6b3da0fa7f640ace5ef9d53703a7aa8ab89b8907999c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9db5f6898f03726a69d907b0a5dec9d19a52ac3141e8cfdda443797476d9fc8f7b0e426812288babdbba3f48d270499e49998224a4509705286992bfd117e810
|
|
7
|
+
data.tar.gz: 5de95e68ce290fa2e3f80e5d595e29dba7d19093f91dcc169c6773a027fe80f3866f38a213713709911aeda767ccd28b30eb3b4765b5d58319997aaec587f414
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -234,7 +234,7 @@ module MilkTea
|
|
|
234
234
|
changed = false
|
|
235
235
|
|
|
236
236
|
helpers.keys.each do |helper|
|
|
237
|
-
|
|
237
|
+
(FORMAT_HELPER_DEPENDENCIES[helper] || []).each do |dependency|
|
|
238
238
|
next if helpers[dependency]
|
|
239
239
|
|
|
240
240
|
helpers[dependency] = true
|
|
@@ -249,60 +249,32 @@ module MilkTea
|
|
|
249
249
|
end
|
|
250
250
|
end
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
when 'mt_format_append_ulong_oct'
|
|
279
|
-
%w[mt_format_check_capacity mt_format_ulong_oct_len]
|
|
280
|
-
when 'mt_format_append_long_oct'
|
|
281
|
-
%w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_oct mt_format_ulong_oct_len]
|
|
282
|
-
when 'mt_format_append_ulong_bin'
|
|
283
|
-
%w[mt_format_check_capacity mt_format_ulong_bin_len]
|
|
284
|
-
when 'mt_format_append_long_bin'
|
|
285
|
-
%w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_bin mt_format_ulong_bin_len]
|
|
286
|
-
when 'mt_format_append_float'
|
|
287
|
-
%w[mt_format_check_capacity mt_format_float_len]
|
|
288
|
-
when 'mt_format_append_double'
|
|
289
|
-
%w[mt_format_check_capacity mt_format_double_len]
|
|
290
|
-
when 'mt_format_append_double_precision'
|
|
291
|
-
%w[mt_format_check_capacity mt_format_double_precision_len]
|
|
292
|
-
when 'mt_format_int_len'
|
|
293
|
-
%w[mt_format_ptr_uint_len]
|
|
294
|
-
when 'mt_format_long_len'
|
|
295
|
-
%w[mt_format_ulong_len]
|
|
296
|
-
when 'mt_format_long_hex_len'
|
|
297
|
-
%w[mt_format_ulong_hex_len]
|
|
298
|
-
when 'mt_format_long_oct_len'
|
|
299
|
-
%w[mt_format_ulong_oct_len]
|
|
300
|
-
when 'mt_format_long_bin_len'
|
|
301
|
-
%w[mt_format_ulong_bin_len]
|
|
302
|
-
else
|
|
303
|
-
[]
|
|
304
|
-
end
|
|
305
|
-
end
|
|
252
|
+
FORMAT_HELPER_DEPENDENCIES = {
|
|
253
|
+
'mt_format_append_str' => %w[mt_format_append_bytes mt_format_check_capacity],
|
|
254
|
+
'mt_format_append_cstr' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_cstr_len],
|
|
255
|
+
'mt_format_append_bool' => %w[mt_format_append_bytes mt_format_check_capacity],
|
|
256
|
+
'mt_format_append_ptr_uint' => %w[mt_format_check_capacity mt_format_ptr_uint_len],
|
|
257
|
+
'mt_format_append_ulong' => %w[mt_format_check_capacity mt_format_ulong_len],
|
|
258
|
+
'mt_format_append_uint' => %w[mt_format_append_ptr_uint mt_format_check_capacity mt_format_ptr_uint_len],
|
|
259
|
+
'mt_format_append_long' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong mt_format_ulong_len],
|
|
260
|
+
'mt_format_append_int' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ptr_uint mt_format_ptr_uint_len],
|
|
261
|
+
'mt_format_append_ulong_hex' => %w[mt_format_check_capacity mt_format_ulong_hex_len],
|
|
262
|
+
'mt_format_append_ulong_hex_upper' => %w[mt_format_check_capacity mt_format_ulong_hex_len],
|
|
263
|
+
'mt_format_append_long_hex' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_hex mt_format_ulong_hex_len],
|
|
264
|
+
'mt_format_append_long_hex_upper' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_hex_upper mt_format_ulong_hex_len],
|
|
265
|
+
'mt_format_append_ulong_oct' => %w[mt_format_check_capacity mt_format_ulong_oct_len],
|
|
266
|
+
'mt_format_append_long_oct' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_oct mt_format_ulong_oct_len],
|
|
267
|
+
'mt_format_append_ulong_bin' => %w[mt_format_check_capacity mt_format_ulong_bin_len],
|
|
268
|
+
'mt_format_append_long_bin' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_bin mt_format_ulong_bin_len],
|
|
269
|
+
'mt_format_append_float' => %w[mt_format_check_capacity mt_format_float_len],
|
|
270
|
+
'mt_format_append_double' => %w[mt_format_check_capacity mt_format_double_len],
|
|
271
|
+
'mt_format_append_double_precision' => %w[mt_format_check_capacity mt_format_double_precision_len],
|
|
272
|
+
'mt_format_int_len' => %w[mt_format_ptr_uint_len],
|
|
273
|
+
'mt_format_long_len' => %w[mt_format_ulong_len],
|
|
274
|
+
'mt_format_long_hex_len' => %w[mt_format_ulong_hex_len],
|
|
275
|
+
'mt_format_long_oct_len' => %w[mt_format_ulong_oct_len],
|
|
276
|
+
'mt_format_long_bin_len' => %w[mt_format_ulong_bin_len],
|
|
277
|
+
}.freeze
|
|
306
278
|
|
|
307
279
|
def uses_format_helpers?
|
|
308
280
|
!used_format_helpers.empty?
|
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MilkTea
|
|
4
|
+
class CBackend
|
|
5
|
+
module FormatHelpers
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def emit_format_helpers
|
|
9
|
+
helpers = used_format_helpers
|
|
10
|
+
lines = []
|
|
11
|
+
|
|
12
|
+
if helpers['mt_format_str_make']
|
|
13
|
+
lines.concat([
|
|
14
|
+
"static mt_str mt_format_str_make(uintptr_t len) {",
|
|
15
|
+
"#{INDENT}char* data = (char*)malloc((size_t)(len + 1));",
|
|
16
|
+
"#{INDENT}if (data == NULL) mt_fatal(\"format string allocation failed\");",
|
|
17
|
+
"#{INDENT}data[len] = '\\0';",
|
|
18
|
+
"#{INDENT}return (mt_str){ .data = data, .len = len };",
|
|
19
|
+
"}",
|
|
20
|
+
])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if helpers['mt_format_str_release']
|
|
24
|
+
lines << "" unless lines.empty?
|
|
25
|
+
lines.concat([
|
|
26
|
+
"static void mt_format_str_release(mt_str value) {",
|
|
27
|
+
"#{INDENT}free(value.data);",
|
|
28
|
+
"}",
|
|
29
|
+
])
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if helpers['mt_format_check_capacity']
|
|
33
|
+
lines << "" unless lines.empty?
|
|
34
|
+
lines.concat([
|
|
35
|
+
"static void mt_format_check_capacity(mt_str target, uintptr_t offset, uintptr_t len) {",
|
|
36
|
+
"#{INDENT}if (offset > target.len || len > target.len - offset) mt_fatal(\"format string append exceeds capacity\");",
|
|
37
|
+
"}",
|
|
38
|
+
])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if helpers['mt_format_append_bytes']
|
|
42
|
+
lines << "" unless lines.empty?
|
|
43
|
+
lines.concat([
|
|
44
|
+
"static uintptr_t mt_format_append_bytes(mt_str target, uintptr_t offset, const char* data, uintptr_t len) {",
|
|
45
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
46
|
+
"#{INDENT}if (len > 0) memcpy(target.data + offset, data, (size_t)len);",
|
|
47
|
+
"#{INDENT}offset += len;",
|
|
48
|
+
"#{INDENT}target.data[offset] = '\\0';",
|
|
49
|
+
"#{INDENT}return offset;",
|
|
50
|
+
"}",
|
|
51
|
+
])
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if helpers['mt_format_cstr_len']
|
|
55
|
+
lines << "" unless lines.empty?
|
|
56
|
+
lines.concat([
|
|
57
|
+
"static uintptr_t mt_format_cstr_len(const char* value) {",
|
|
58
|
+
"#{INDENT}return (uintptr_t)strlen(value);",
|
|
59
|
+
"}",
|
|
60
|
+
])
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if helpers['mt_format_bool_len']
|
|
64
|
+
lines << "" unless lines.empty?
|
|
65
|
+
lines.concat([
|
|
66
|
+
"static uintptr_t mt_format_bool_len(bool value) {",
|
|
67
|
+
"#{INDENT}return value ? 4 : 5;",
|
|
68
|
+
"}",
|
|
69
|
+
])
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if helpers['mt_format_ptr_uint_len']
|
|
73
|
+
lines << "" unless lines.empty?
|
|
74
|
+
lines.concat([
|
|
75
|
+
"static uintptr_t mt_format_ptr_uint_len(uintptr_t value) {",
|
|
76
|
+
"#{INDENT}uintptr_t len = 1;",
|
|
77
|
+
"#{INDENT}while (value >= 10) {",
|
|
78
|
+
"#{INDENT * 2}value /= 10;",
|
|
79
|
+
"#{INDENT * 2}len += 1;",
|
|
80
|
+
"#{INDENT}}",
|
|
81
|
+
"#{INDENT}return len;",
|
|
82
|
+
"}",
|
|
83
|
+
])
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if helpers['mt_format_ulong_len']
|
|
87
|
+
lines << "" unless lines.empty?
|
|
88
|
+
lines.concat([
|
|
89
|
+
"static uintptr_t mt_format_ulong_len(uint64_t value) {",
|
|
90
|
+
"#{INDENT}uintptr_t len = 1;",
|
|
91
|
+
"#{INDENT}while (value >= 10) {",
|
|
92
|
+
"#{INDENT * 2}value /= 10;",
|
|
93
|
+
"#{INDENT * 2}len += 1;",
|
|
94
|
+
"#{INDENT}}",
|
|
95
|
+
"#{INDENT}return len;",
|
|
96
|
+
"}",
|
|
97
|
+
])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if helpers['mt_format_ulong_hex_len']
|
|
101
|
+
lines << "" unless lines.empty?
|
|
102
|
+
lines.concat([
|
|
103
|
+
"static uintptr_t mt_format_ulong_hex_len(uint64_t value) {",
|
|
104
|
+
"#{INDENT}int written = snprintf(NULL, 0, \"%llx\", (unsigned long long)value);",
|
|
105
|
+
"#{INDENT}if (written < 0) mt_fatal(\"format string could not measure unsigned hex\");",
|
|
106
|
+
"#{INDENT}return (uintptr_t)written;",
|
|
107
|
+
"}",
|
|
108
|
+
])
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if helpers['mt_format_uint_len']
|
|
112
|
+
lines << "" unless lines.empty?
|
|
113
|
+
lines.concat([
|
|
114
|
+
"static uintptr_t mt_format_uint_len(uint32_t value) {",
|
|
115
|
+
"#{INDENT}return mt_format_ptr_uint_len((uintptr_t)value);",
|
|
116
|
+
"}",
|
|
117
|
+
])
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
if helpers['mt_format_long_len']
|
|
121
|
+
lines << "" unless lines.empty?
|
|
122
|
+
lines.concat([
|
|
123
|
+
"static uintptr_t mt_format_long_len(int64_t value) {",
|
|
124
|
+
"#{INDENT}if (value < 0) return 1 + mt_format_ulong_len(((uint64_t)(-(value + 1))) + 1);",
|
|
125
|
+
"#{INDENT}return mt_format_ulong_len((uint64_t)value);",
|
|
126
|
+
"}",
|
|
127
|
+
])
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
if helpers['mt_format_long_hex_len']
|
|
131
|
+
lines << "" unless lines.empty?
|
|
132
|
+
lines.concat([
|
|
133
|
+
"static uintptr_t mt_format_long_hex_len(int64_t value) {",
|
|
134
|
+
"#{INDENT}if (value < 0) return 1 + mt_format_ulong_hex_len(((uint64_t)(-(value + 1))) + 1);",
|
|
135
|
+
"#{INDENT}return mt_format_ulong_hex_len((uint64_t)value);",
|
|
136
|
+
"}",
|
|
137
|
+
])
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
if helpers['mt_format_ulong_oct_len']
|
|
141
|
+
lines << "" unless lines.empty?
|
|
142
|
+
lines.concat([
|
|
143
|
+
"static uintptr_t mt_format_ulong_oct_len(uint64_t value) {",
|
|
144
|
+
"#{INDENT}int written = snprintf(NULL, 0, \"%llo\", (unsigned long long)value);",
|
|
145
|
+
"#{INDENT}if (written < 0) mt_fatal(\"format string could not measure unsigned octal\");",
|
|
146
|
+
"#{INDENT}return (uintptr_t)written;",
|
|
147
|
+
"}",
|
|
148
|
+
])
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
if helpers['mt_format_long_oct_len']
|
|
152
|
+
lines << "" unless lines.empty?
|
|
153
|
+
lines.concat([
|
|
154
|
+
"static uintptr_t mt_format_long_oct_len(int64_t value) {",
|
|
155
|
+
"#{INDENT}if (value < 0) return 1 + mt_format_ulong_oct_len(((uint64_t)(-(value + 1))) + 1);",
|
|
156
|
+
"#{INDENT}return mt_format_ulong_oct_len((uint64_t)value);",
|
|
157
|
+
"}",
|
|
158
|
+
])
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
if helpers['mt_format_ulong_bin_len']
|
|
162
|
+
lines << "" unless lines.empty?
|
|
163
|
+
lines.concat([
|
|
164
|
+
"static uintptr_t mt_format_ulong_bin_len(uint64_t value) {",
|
|
165
|
+
"#{INDENT}uintptr_t len = 1;",
|
|
166
|
+
"#{INDENT}while (value >= 2) {",
|
|
167
|
+
"#{INDENT * 2}value >>= 1;",
|
|
168
|
+
"#{INDENT * 2}len += 1;",
|
|
169
|
+
"#{INDENT}}",
|
|
170
|
+
"#{INDENT}return len;",
|
|
171
|
+
"}",
|
|
172
|
+
])
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
if helpers['mt_format_long_bin_len']
|
|
176
|
+
lines << "" unless lines.empty?
|
|
177
|
+
lines.concat([
|
|
178
|
+
"static uintptr_t mt_format_long_bin_len(int64_t value) {",
|
|
179
|
+
"#{INDENT}if (value < 0) return 1 + mt_format_ulong_bin_len(((uint64_t)(-(value + 1))) + 1);",
|
|
180
|
+
"#{INDENT}return mt_format_ulong_bin_len((uint64_t)value);",
|
|
181
|
+
"}",
|
|
182
|
+
])
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
if helpers['mt_format_int_len']
|
|
186
|
+
lines << "" unless lines.empty?
|
|
187
|
+
lines.concat([
|
|
188
|
+
"static uintptr_t mt_format_int_len(int32_t value) {",
|
|
189
|
+
"#{INDENT}if (value < 0) return 1 + mt_format_ptr_uint_len((uintptr_t)(-((int64_t)value)));",
|
|
190
|
+
"#{INDENT}return mt_format_ptr_uint_len((uintptr_t)value);",
|
|
191
|
+
"}",
|
|
192
|
+
])
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
if helpers['mt_format_float_len']
|
|
196
|
+
lines << "" unless lines.empty?
|
|
197
|
+
lines.concat([
|
|
198
|
+
"static uintptr_t mt_format_float_len(float value) {",
|
|
199
|
+
"#{INDENT}int written = snprintf(NULL, 0, \"%g\", (double)value);",
|
|
200
|
+
"#{INDENT}if (written < 0) mt_fatal(\"format string could not measure float\");",
|
|
201
|
+
"#{INDENT}return (uintptr_t)written;",
|
|
202
|
+
"}",
|
|
203
|
+
])
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
if helpers['mt_format_double_len']
|
|
207
|
+
lines << "" unless lines.empty?
|
|
208
|
+
lines.concat([
|
|
209
|
+
"static uintptr_t mt_format_double_len(double value) {",
|
|
210
|
+
"#{INDENT}int written = snprintf(NULL, 0, \"%g\", value);",
|
|
211
|
+
"#{INDENT}if (written < 0) mt_fatal(\"format string could not measure double\");",
|
|
212
|
+
"#{INDENT}return (uintptr_t)written;",
|
|
213
|
+
"}",
|
|
214
|
+
])
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
if helpers['mt_format_double_precision_len']
|
|
218
|
+
lines << "" unless lines.empty?
|
|
219
|
+
lines.concat([
|
|
220
|
+
"static uintptr_t mt_format_double_precision_len(double value, int32_t precision) {",
|
|
221
|
+
"#{INDENT}int written = snprintf(NULL, 0, \"%.*f\", precision, value);",
|
|
222
|
+
"#{INDENT}if (written < 0) mt_fatal(\"format string could not measure double precision\");",
|
|
223
|
+
"#{INDENT}return (uintptr_t)written;",
|
|
224
|
+
"}",
|
|
225
|
+
])
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
if helpers['mt_format_append_str']
|
|
229
|
+
lines << "" unless lines.empty?
|
|
230
|
+
lines.concat([
|
|
231
|
+
"static uintptr_t mt_format_append_str(mt_str target, uintptr_t offset, mt_str value) {",
|
|
232
|
+
"#{INDENT}return mt_format_append_bytes(target, offset, value.data, value.len);",
|
|
233
|
+
"}",
|
|
234
|
+
])
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
if helpers['mt_format_append_cstr']
|
|
238
|
+
lines << "" unless lines.empty?
|
|
239
|
+
lines.concat([
|
|
240
|
+
"static uintptr_t mt_format_append_cstr(mt_str target, uintptr_t offset, const char* value) {",
|
|
241
|
+
"#{INDENT}uintptr_t len = mt_format_cstr_len(value);",
|
|
242
|
+
"#{INDENT}return mt_format_append_bytes(target, offset, value, len);",
|
|
243
|
+
"}",
|
|
244
|
+
])
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
if helpers['mt_format_append_bool']
|
|
248
|
+
lines << "" unless lines.empty?
|
|
249
|
+
lines.concat([
|
|
250
|
+
"static uintptr_t mt_format_append_bool(mt_str target, uintptr_t offset, bool value) {",
|
|
251
|
+
"#{INDENT}return value ? mt_format_append_bytes(target, offset, \"true\", 4) : mt_format_append_bytes(target, offset, \"false\", 5);",
|
|
252
|
+
"}",
|
|
253
|
+
])
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
if helpers['mt_format_append_ptr_uint']
|
|
257
|
+
lines << "" unless lines.empty?
|
|
258
|
+
lines.concat([
|
|
259
|
+
"static uintptr_t mt_format_append_ptr_uint(mt_str target, uintptr_t offset, uintptr_t value) {",
|
|
260
|
+
"#{INDENT}uintptr_t len = mt_format_ptr_uint_len(value);",
|
|
261
|
+
"#{INDENT}uintptr_t index = offset + len;",
|
|
262
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
263
|
+
"#{INDENT}target.data[index] = '\\0';",
|
|
264
|
+
"#{INDENT}do {",
|
|
265
|
+
"#{INDENT * 2}index -= 1;",
|
|
266
|
+
"#{INDENT * 2}target.data[index] = (char)('0' + (value % 10));",
|
|
267
|
+
"#{INDENT * 2}value /= 10;",
|
|
268
|
+
"#{INDENT}} while (index > offset);",
|
|
269
|
+
"#{INDENT}return offset + len;",
|
|
270
|
+
"}",
|
|
271
|
+
])
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
if helpers['mt_format_append_ulong']
|
|
275
|
+
lines << "" unless lines.empty?
|
|
276
|
+
lines.concat([
|
|
277
|
+
"static uintptr_t mt_format_append_ulong(mt_str target, uintptr_t offset, uint64_t value) {",
|
|
278
|
+
"#{INDENT}uintptr_t len = mt_format_ulong_len(value);",
|
|
279
|
+
"#{INDENT}uintptr_t index = offset + len;",
|
|
280
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
281
|
+
"#{INDENT}target.data[index] = '\\0';",
|
|
282
|
+
"#{INDENT}do {",
|
|
283
|
+
"#{INDENT * 2}index -= 1;",
|
|
284
|
+
"#{INDENT * 2}target.data[index] = (char)('0' + (value % 10));",
|
|
285
|
+
"#{INDENT * 2}value /= 10;",
|
|
286
|
+
"#{INDENT}} while (index > offset);",
|
|
287
|
+
"#{INDENT}return offset + len;",
|
|
288
|
+
"}",
|
|
289
|
+
])
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
if helpers['mt_format_append_uint']
|
|
293
|
+
lines << "" unless lines.empty?
|
|
294
|
+
lines.concat([
|
|
295
|
+
"static uintptr_t mt_format_append_uint(mt_str target, uintptr_t offset, uint32_t value) {",
|
|
296
|
+
"#{INDENT}return mt_format_append_ptr_uint(target, offset, (uintptr_t)value);",
|
|
297
|
+
"}",
|
|
298
|
+
])
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
if helpers['mt_format_append_long']
|
|
302
|
+
lines << "" unless lines.empty?
|
|
303
|
+
lines.concat([
|
|
304
|
+
"static uintptr_t mt_format_append_long(mt_str target, uintptr_t offset, int64_t value) {",
|
|
305
|
+
"#{INDENT}if (value < 0) {",
|
|
306
|
+
"#{INDENT * 2}offset = mt_format_append_bytes(target, offset, \"-\", 1);",
|
|
307
|
+
"#{INDENT * 2}return mt_format_append_ulong(target, offset, ((uint64_t)(-(value + 1))) + 1);",
|
|
308
|
+
"#{INDENT}}",
|
|
309
|
+
"#{INDENT}return mt_format_append_ulong(target, offset, (uint64_t)value);",
|
|
310
|
+
"}",
|
|
311
|
+
])
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
if helpers['mt_format_append_ulong_hex']
|
|
315
|
+
lines << "" unless lines.empty?
|
|
316
|
+
lines.concat([
|
|
317
|
+
"static uintptr_t mt_format_append_ulong_hex(mt_str target, uintptr_t offset, uint64_t value) {",
|
|
318
|
+
"#{INDENT}uintptr_t len = mt_format_ulong_hex_len(value);",
|
|
319
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
320
|
+
"#{INDENT}int written = snprintf(target.data + offset, (size_t)(target.len - offset + 1), \"%llx\", (unsigned long long)value);",
|
|
321
|
+
"#{INDENT}if (written < 0 || (uintptr_t)written != len) mt_fatal(\"format string could not format unsigned hex\");",
|
|
322
|
+
"#{INDENT}return offset + len;",
|
|
323
|
+
"}",
|
|
324
|
+
])
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
if helpers['mt_format_append_ulong_hex_upper']
|
|
328
|
+
lines << "" unless lines.empty?
|
|
329
|
+
lines.concat([
|
|
330
|
+
"static uintptr_t mt_format_append_ulong_hex_upper(mt_str target, uintptr_t offset, uint64_t value) {",
|
|
331
|
+
"#{INDENT}uintptr_t len = mt_format_ulong_hex_len(value);",
|
|
332
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
333
|
+
"#{INDENT}int written = snprintf(target.data + offset, (size_t)(target.len - offset + 1), \"%llX\", (unsigned long long)value);",
|
|
334
|
+
"#{INDENT}if (written < 0 || (uintptr_t)written != len) mt_fatal(\"format string could not format unsigned hex\");",
|
|
335
|
+
"#{INDENT}return offset + len;",
|
|
336
|
+
"}",
|
|
337
|
+
])
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
if helpers['mt_format_append_long_hex']
|
|
341
|
+
lines << "" unless lines.empty?
|
|
342
|
+
lines.concat([
|
|
343
|
+
"static uintptr_t mt_format_append_long_hex(mt_str target, uintptr_t offset, int64_t value) {",
|
|
344
|
+
"#{INDENT}if (value < 0) {",
|
|
345
|
+
"#{INDENT * 2}offset = mt_format_append_bytes(target, offset, \"-\", 1);",
|
|
346
|
+
"#{INDENT * 2}return mt_format_append_ulong_hex(target, offset, ((uint64_t)(-(value + 1))) + 1);",
|
|
347
|
+
"#{INDENT}}",
|
|
348
|
+
"#{INDENT}return mt_format_append_ulong_hex(target, offset, (uint64_t)value);",
|
|
349
|
+
"}",
|
|
350
|
+
])
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
if helpers['mt_format_append_long_hex_upper']
|
|
354
|
+
lines << "" unless lines.empty?
|
|
355
|
+
lines.concat([
|
|
356
|
+
"static uintptr_t mt_format_append_long_hex_upper(mt_str target, uintptr_t offset, int64_t value) {",
|
|
357
|
+
"#{INDENT}if (value < 0) {",
|
|
358
|
+
"#{INDENT * 2}offset = mt_format_append_bytes(target, offset, \"-\", 1);",
|
|
359
|
+
"#{INDENT * 2}return mt_format_append_ulong_hex_upper(target, offset, ((uint64_t)(-(value + 1))) + 1);",
|
|
360
|
+
"#{INDENT}}",
|
|
361
|
+
"#{INDENT}return mt_format_append_ulong_hex_upper(target, offset, (uint64_t)value);",
|
|
362
|
+
"}",
|
|
363
|
+
])
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
if helpers['mt_format_append_ulong_oct']
|
|
367
|
+
lines << "" unless lines.empty?
|
|
368
|
+
lines.concat([
|
|
369
|
+
"static uintptr_t mt_format_append_ulong_oct(mt_str target, uintptr_t offset, uint64_t value) {",
|
|
370
|
+
"#{INDENT}uintptr_t len = mt_format_ulong_oct_len(value);",
|
|
371
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
372
|
+
"#{INDENT}int written = snprintf(target.data + offset, (size_t)(target.len - offset + 1), \"%llo\", (unsigned long long)value);",
|
|
373
|
+
"#{INDENT}if (written < 0 || (uintptr_t)written != len) mt_fatal(\"format string could not format unsigned octal\");",
|
|
374
|
+
"#{INDENT}return offset + len;",
|
|
375
|
+
"}",
|
|
376
|
+
])
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
if helpers['mt_format_append_long_oct']
|
|
380
|
+
lines << "" unless lines.empty?
|
|
381
|
+
lines.concat([
|
|
382
|
+
"static uintptr_t mt_format_append_long_oct(mt_str target, uintptr_t offset, int64_t value) {",
|
|
383
|
+
"#{INDENT}if (value < 0) {",
|
|
384
|
+
"#{INDENT * 2}offset = mt_format_append_bytes(target, offset, \"-\", 1);",
|
|
385
|
+
"#{INDENT * 2}return mt_format_append_ulong_oct(target, offset, ((uint64_t)(-(value + 1))) + 1);",
|
|
386
|
+
"#{INDENT}}",
|
|
387
|
+
"#{INDENT}return mt_format_append_ulong_oct(target, offset, (uint64_t)value);",
|
|
388
|
+
"}",
|
|
389
|
+
])
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
if helpers['mt_format_append_ulong_bin']
|
|
393
|
+
lines << "" unless lines.empty?
|
|
394
|
+
lines.concat([
|
|
395
|
+
"static uintptr_t mt_format_append_ulong_bin(mt_str target, uintptr_t offset, uint64_t value) {",
|
|
396
|
+
"#{INDENT}uintptr_t len = mt_format_ulong_bin_len(value);",
|
|
397
|
+
"#{INDENT}uintptr_t index = offset + len;",
|
|
398
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
399
|
+
"#{INDENT}target.data[index] = '\\0';",
|
|
400
|
+
"#{INDENT}do {",
|
|
401
|
+
"#{INDENT * 2}index -= 1;",
|
|
402
|
+
"#{INDENT * 2}target.data[index] = (char)('0' + (value & 1));",
|
|
403
|
+
"#{INDENT * 2}value >>= 1;",
|
|
404
|
+
"#{INDENT}} while (index > offset);",
|
|
405
|
+
"#{INDENT}return offset + len;",
|
|
406
|
+
"}",
|
|
407
|
+
])
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
if helpers['mt_format_append_long_bin']
|
|
411
|
+
lines << "" unless lines.empty?
|
|
412
|
+
lines.concat([
|
|
413
|
+
"static uintptr_t mt_format_append_long_bin(mt_str target, uintptr_t offset, int64_t value) {",
|
|
414
|
+
"#{INDENT}if (value < 0) {",
|
|
415
|
+
"#{INDENT * 2}offset = mt_format_append_bytes(target, offset, \"-\", 1);",
|
|
416
|
+
"#{INDENT * 2}return mt_format_append_ulong_bin(target, offset, ((uint64_t)(-(value + 1))) + 1);",
|
|
417
|
+
"#{INDENT}}",
|
|
418
|
+
"#{INDENT}return mt_format_append_ulong_bin(target, offset, (uint64_t)value);",
|
|
419
|
+
"}",
|
|
420
|
+
])
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
if helpers['mt_format_append_int']
|
|
424
|
+
lines << "" unless lines.empty?
|
|
425
|
+
lines.concat([
|
|
426
|
+
"static uintptr_t mt_format_append_int(mt_str target, uintptr_t offset, int32_t value) {",
|
|
427
|
+
"#{INDENT}if (value < 0) {",
|
|
428
|
+
"#{INDENT * 2}offset = mt_format_append_bytes(target, offset, \"-\", 1);",
|
|
429
|
+
"#{INDENT * 2}return mt_format_append_ptr_uint(target, offset, (uintptr_t)(-((int64_t)value)));",
|
|
430
|
+
"#{INDENT}}",
|
|
431
|
+
"#{INDENT}return mt_format_append_ptr_uint(target, offset, (uintptr_t)value);",
|
|
432
|
+
"}",
|
|
433
|
+
])
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
if helpers['mt_format_append_float']
|
|
437
|
+
lines << "" unless lines.empty?
|
|
438
|
+
lines.concat([
|
|
439
|
+
"static uintptr_t mt_format_append_float(mt_str target, uintptr_t offset, float value) {",
|
|
440
|
+
"#{INDENT}uintptr_t len = mt_format_float_len(value);",
|
|
441
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
442
|
+
"#{INDENT}int written = snprintf(target.data + offset, (size_t)(target.len - offset + 1), \"%g\", (double)value);",
|
|
443
|
+
"#{INDENT}if (written < 0 || (uintptr_t)written != len) mt_fatal(\"format string could not format float\");",
|
|
444
|
+
"#{INDENT}return offset + len;",
|
|
445
|
+
"}",
|
|
446
|
+
])
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
if helpers['mt_format_append_double']
|
|
450
|
+
lines << "" unless lines.empty?
|
|
451
|
+
lines.concat([
|
|
452
|
+
"static uintptr_t mt_format_append_double(mt_str target, uintptr_t offset, double value) {",
|
|
453
|
+
"#{INDENT}uintptr_t len = mt_format_double_len(value);",
|
|
454
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
455
|
+
"#{INDENT}int written = snprintf(target.data + offset, (size_t)(target.len - offset + 1), \"%g\", value);",
|
|
456
|
+
"#{INDENT}if (written < 0 || (uintptr_t)written != len) mt_fatal(\"format string could not format double\");",
|
|
457
|
+
"#{INDENT}return offset + len;",
|
|
458
|
+
"}",
|
|
459
|
+
])
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
if helpers['mt_format_append_double_precision']
|
|
463
|
+
lines << "" unless lines.empty?
|
|
464
|
+
lines.concat([
|
|
465
|
+
"static uintptr_t mt_format_append_double_precision(mt_str target, uintptr_t offset, double value, int32_t precision) {",
|
|
466
|
+
"#{INDENT}uintptr_t len = mt_format_double_precision_len(value, precision);",
|
|
467
|
+
"#{INDENT}mt_format_check_capacity(target, offset, len);",
|
|
468
|
+
"#{INDENT}int written = snprintf(target.data + offset, (size_t)(target.len - offset + 1), \"%.*f\", precision, value);",
|
|
469
|
+
"#{INDENT}if (written < 0 || (uintptr_t)written != len) mt_fatal(\"format string could not format double precision\");",
|
|
470
|
+
"#{INDENT}return offset + len;",
|
|
471
|
+
"}",
|
|
472
|
+
])
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
lines
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
def emit_fmt_builder_helpers
|
|
479
|
+
return [] unless uses_fmt_builder?
|
|
480
|
+
|
|
481
|
+
[
|
|
482
|
+
"typedef struct {",
|
|
483
|
+
"#{INDENT}char* data;",
|
|
484
|
+
"#{INDENT}uintptr_t capacity;",
|
|
485
|
+
"#{INDENT}uintptr_t offset;",
|
|
486
|
+
"} mt_fmt_builder;",
|
|
487
|
+
"",
|
|
488
|
+
"static inline mt_fmt_builder mt_fmt_begin(uintptr_t capacity) {",
|
|
489
|
+
"#{INDENT}mt_fmt_builder b;",
|
|
490
|
+
"#{INDENT}b.data = (char*)malloc((size_t)capacity);",
|
|
491
|
+
"#{INDENT}b.capacity = capacity;",
|
|
492
|
+
"#{INDENT}b.offset = 0;",
|
|
493
|
+
"#{INDENT}return b;",
|
|
494
|
+
"}",
|
|
495
|
+
"",
|
|
496
|
+
"static inline void mt_fmt_cleanup(mt_fmt_builder b) {",
|
|
497
|
+
"#{INDENT}free(b.data);",
|
|
498
|
+
"}",
|
|
499
|
+
"",
|
|
500
|
+
"static inline mt_str mt_fmt_finish(mt_fmt_builder* b) {",
|
|
501
|
+
"#{INDENT}return (mt_str){ .data = b->data, .len = b->offset };",
|
|
502
|
+
"}",
|
|
503
|
+
"",
|
|
504
|
+
"static inline void mt_fmt_write_bytes(mt_fmt_builder* b, const char* data, uintptr_t len) {",
|
|
505
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
506
|
+
"#{INDENT}b->offset = mt_format_append_bytes((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, data, len);",
|
|
507
|
+
"}",
|
|
508
|
+
"",
|
|
509
|
+
"static inline void mt_fmt_write_str(mt_fmt_builder* b, mt_str value) {",
|
|
510
|
+
"#{INDENT}mt_fmt_write_bytes(b, value.data, value.len);",
|
|
511
|
+
"}",
|
|
512
|
+
"",
|
|
513
|
+
"static inline void mt_fmt_write_int(mt_fmt_builder* b, int32_t value) {",
|
|
514
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
515
|
+
"#{INDENT}b->offset = mt_format_append_int((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, value);",
|
|
516
|
+
"}",
|
|
517
|
+
"",
|
|
518
|
+
"static inline void mt_fmt_write_ptr_uint(mt_fmt_builder* b, uintptr_t value) {",
|
|
519
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
520
|
+
"#{INDENT}b->offset = mt_format_append_ptr_uint((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, value);",
|
|
521
|
+
"}",
|
|
522
|
+
"",
|
|
523
|
+
"static inline void mt_fmt_write_long_hex(mt_fmt_builder* b, int64_t value) {",
|
|
524
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
525
|
+
"#{INDENT}b->offset = mt_format_append_long_hex((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, value);",
|
|
526
|
+
"}",
|
|
527
|
+
"",
|
|
528
|
+
"static inline void mt_fmt_write_long_hex_upper(mt_fmt_builder* b, int64_t value) {",
|
|
529
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
530
|
+
"#{INDENT}b->offset = mt_format_append_long_hex_upper((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, value);",
|
|
531
|
+
"}",
|
|
532
|
+
"",
|
|
533
|
+
"static inline void mt_fmt_write_long_oct(mt_fmt_builder* b, int64_t value) {",
|
|
534
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
535
|
+
"#{INDENT}b->offset = mt_format_append_long_oct((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, value);",
|
|
536
|
+
"}",
|
|
537
|
+
"",
|
|
538
|
+
"static inline void mt_fmt_write_long_bin(mt_fmt_builder* b, int64_t value) {",
|
|
539
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
540
|
+
"#{INDENT}b->offset = mt_format_append_long_bin((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, value);",
|
|
541
|
+
"}",
|
|
542
|
+
"",
|
|
543
|
+
"static inline void mt_fmt_write_double_precision(mt_fmt_builder* b, double value, int32_t precision) {",
|
|
544
|
+
"#{INDENT}mt_fmt_builder buf = *b;",
|
|
545
|
+
"#{INDENT}b->offset = mt_format_append_double_precision((mt_str){ .data = buf.data, .len = buf.capacity }, buf.offset, value, precision);",
|
|
546
|
+
"}",
|
|
547
|
+
]
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
end
|