ndtypes 0.2.0dev4

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 (139) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +50 -0
  3. data/Gemfile +2 -0
  4. data/History.md +0 -0
  5. data/README.md +19 -0
  6. data/Rakefile +125 -0
  7. data/ext/ruby_ndtypes/extconf.rb +55 -0
  8. data/ext/ruby_ndtypes/gc_guard.c +36 -0
  9. data/ext/ruby_ndtypes/gc_guard.h +12 -0
  10. data/ext/ruby_ndtypes/ndtypes/AUTHORS.txt +5 -0
  11. data/ext/ruby_ndtypes/ndtypes/INSTALL.txt +101 -0
  12. data/ext/ruby_ndtypes/ndtypes/LICENSE.txt +29 -0
  13. data/ext/ruby_ndtypes/ndtypes/MANIFEST.in +3 -0
  14. data/ext/ruby_ndtypes/ndtypes/Makefile.in +87 -0
  15. data/ext/ruby_ndtypes/ndtypes/README.rst +47 -0
  16. data/ext/ruby_ndtypes/ndtypes/config.guess +1530 -0
  17. data/ext/ruby_ndtypes/ndtypes/config.h.in +67 -0
  18. data/ext/ruby_ndtypes/ndtypes/config.sub +1782 -0
  19. data/ext/ruby_ndtypes/ndtypes/configure +5260 -0
  20. data/ext/ruby_ndtypes/ndtypes/configure.ac +161 -0
  21. data/ext/ruby_ndtypes/ndtypes/doc/Makefile +14 -0
  22. data/ext/ruby_ndtypes/ndtypes/doc/_static/copybutton.js +66 -0
  23. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +26 -0
  24. data/ext/ruby_ndtypes/ndtypes/doc/grammar/grammar.rst +27 -0
  25. data/ext/ruby_ndtypes/ndtypes/doc/index.rst +56 -0
  26. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/context.rst +131 -0
  27. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/encodings.rst +68 -0
  28. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/fields-values.rst +175 -0
  29. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/functions.rst +72 -0
  30. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/index.rst +43 -0
  31. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/init.rst +48 -0
  32. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/io.rst +100 -0
  33. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/memory.rst +124 -0
  34. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/predicates.rst +110 -0
  35. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/typedef.rst +31 -0
  36. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/types.rst +594 -0
  37. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/util.rst +166 -0
  38. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/buffer-protocol.rst +27 -0
  39. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/index.rst +21 -0
  40. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/pattern-matching.rst +330 -0
  41. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/quickstart.rst +144 -0
  42. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +544 -0
  43. data/ext/ruby_ndtypes/ndtypes/doc/releases/index.rst +35 -0
  44. data/ext/ruby_ndtypes/ndtypes/install-sh +527 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +271 -0
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +269 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +230 -0
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.c +268 -0
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.h +109 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.in +73 -0
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.vc +70 -0
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/README.txt +16 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +2179 -0
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +134 -0
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +428 -0
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +2543 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +735 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +176 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +543 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +110 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.c +228 -0
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +634 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.c +116 -0
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +288 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +3067 -0
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +180 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +417 -0
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +1658 -0
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +2773 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +734 -0
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +222 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +1132 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +2323 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +893 -0
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/overflow.h +161 -0
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +473 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +92 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +246 -0
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +269 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +197 -0
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.in +48 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.vc +46 -0
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +1007 -0
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +442 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/slice.h +42 -0
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +238 -0
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +50 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +371 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +100 -0
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +55 -0
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +45 -0
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.c +82 -0
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.h +49 -0
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +1657 -0
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +85 -0
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +115 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +137 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_indent.c +201 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +2397 -0
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_numba.c +57 -0
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +349 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +27839 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +350 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +231 -0
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +375 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typedef.c +65 -0
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/valgrind.supp +30 -0
  108. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/bench.c +79 -0
  109. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/indent.c +94 -0
  110. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/print_ast.c +96 -0
  111. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +474 -0
  112. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +228 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/bench.py +49 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +409 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +14 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +70 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +1332 -0
  118. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/docstrings.h +319 -0
  119. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +154 -0
  120. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +1977 -0
  121. data/ext/ruby_ndtypes/ndtypes/setup.py +288 -0
  122. data/ext/ruby_ndtypes/ndtypes/vcbuild/INSTALL.txt +41 -0
  123. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest32.bat +15 -0
  124. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest64.bat +13 -0
  125. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild32.bat +38 -0
  126. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild64.bat +38 -0
  127. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcclean.bat +13 -0
  128. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcdistclean.bat +14 -0
  129. data/ext/ruby_ndtypes/ruby_ndtypes.c +1003 -0
  130. data/ext/ruby_ndtypes/ruby_ndtypes.h +37 -0
  131. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +28 -0
  132. data/lib/ndtypes.rb +45 -0
  133. data/lib/ndtypes/errors.rb +2 -0
  134. data/lib/ndtypes/version.rb +6 -0
  135. data/ndtypes.gemspec +47 -0
  136. data/spec/gc_table_spec.rb +10 -0
  137. data/spec/ndtypes_spec.rb +289 -0
  138. data/spec/spec_helper.rb +241 -0
  139. metadata +242 -0
@@ -0,0 +1,1658 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #include <stdio.h>
35
+ #include <stdlib.h>
36
+ #include <stdint.h>
37
+ #include <string.h>
38
+ #include <inttypes.h>
39
+ #include <stdarg.h>
40
+ #include <errno.h>
41
+ #include <assert.h>
42
+ #include "ndtypes.h"
43
+
44
+
45
+ /******************************************************************************/
46
+ /* Various string representations */
47
+ /******************************************************************************/
48
+
49
+ /*
50
+ * Return the keyword string if the type is a keyword. Otherwise, return
51
+ * "not a keyword".
52
+ */
53
+ static const char *
54
+ ndt_type_keyword(const ndt_t *t)
55
+ {
56
+ switch (t->tag) {
57
+ case AnyKind: return "Any";
58
+ case FixedDim: return "fixed";
59
+ case VarDim: return "var";
60
+
61
+ case Ref: return "ref";
62
+
63
+ case ScalarKind: return "ScalarKind";
64
+ case Categorical: return "categorical";
65
+
66
+ case FixedStringKind: return "FixedStringKind";
67
+ case FixedString: return "FixedString";
68
+
69
+ case FixedBytesKind: return "FixedBytesKind";
70
+ case FixedBytes: return "FixedBytes";
71
+
72
+ case String: return "string";
73
+ case Bytes: return "bytes";
74
+ case Char: return "char";
75
+
76
+ case Bool: return "bool";
77
+
78
+ case SignedKind: return "SignedKind";
79
+ case Int8: return "int8";
80
+ case Int16: return "int16";
81
+ case Int32: return "int32";
82
+ case Int64: return "int64";
83
+
84
+ case UnsignedKind: return "UnsignedKind";
85
+ case Uint8: return "uint8";
86
+ case Uint16: return "uint16";
87
+ case Uint32: return "uint32";
88
+ case Uint64: return "uint64";
89
+
90
+ case FloatKind: return "FloatKind";
91
+ case Float16: return "float16";
92
+ case Float32: return "float32";
93
+ case Float64: return "float64";
94
+
95
+ case ComplexKind: return "ComplexKind";
96
+ case Complex32: return "complex32";
97
+ case Complex64: return "complex64";
98
+ case Complex128: return "complex128";
99
+
100
+ case Module: case Function:
101
+ case SymbolicDim: case EllipsisDim:
102
+ case Tuple: case Record:
103
+ case Nominal: case Constr:
104
+ case Typevar:
105
+ return "not a keyword";
106
+ }
107
+
108
+ /* NOT REACHED: tags should be exhaustive. */
109
+ ndt_internal_error("invalid tag");
110
+ }
111
+
112
+ /* Return the type name in constructor form for the abstract syntax tree. */
113
+ static const char *
114
+ ndt_type_name(const ndt_t *t)
115
+ {
116
+ switch (t->tag) {
117
+ case Module: return "Module";
118
+ case Function: return "Function";
119
+
120
+ case AnyKind: return "Any";
121
+
122
+ case FixedDim: return "FixedDim";
123
+ case VarDim: return "VarDim";
124
+ case SymbolicDim: return "SymbolicDim";
125
+ case EllipsisDim: return "EllipsisDim";
126
+
127
+ case Tuple: return "Tuple";
128
+ case Record: return "Record";
129
+ case Ref: return "Ref";
130
+ case Constr: return "Constr";
131
+ case Nominal: return "Nominal";
132
+
133
+ case ScalarKind: return "ScalarKind";
134
+ case Categorical: return "Categorical";
135
+
136
+ case FixedStringKind: return "FixedStringKind";
137
+ case FixedString: return "FixedString";
138
+
139
+ case FixedBytesKind: return "FixedBytesKind";
140
+ case FixedBytes: return "FixedBytes";
141
+
142
+ case String: return "String";
143
+ case Bytes: return "Bytes";
144
+ case Char: return "Char";
145
+
146
+ case Bool: return "Bool";
147
+
148
+ case SignedKind: return "SignedKind";
149
+ case Int8: return "Int8";
150
+ case Int16: return "Int16";
151
+ case Int32: return "Int32";
152
+ case Int64: return "Int64";
153
+
154
+ case UnsignedKind: return "UnsignedKind";
155
+ case Uint8: return "Uint8";
156
+ case Uint16: return "Uint16";
157
+ case Uint32: return "Uint32";
158
+ case Uint64: return "Uint64";
159
+
160
+ case FloatKind: return "FloatKind";
161
+ case Float16: return "Float16";
162
+ case Float32: return "Float32";
163
+ case Float64: return "Float64";
164
+
165
+ case ComplexKind: return "ComplexKind";
166
+ case Complex32: return "Complex32";
167
+ case Complex64: return "Complex64";
168
+ case Complex128: return "Complex128";
169
+
170
+ case Typevar: return "Typevar";
171
+ }
172
+
173
+ /* NOT REACHED: tags should be exhaustive. */
174
+ ndt_internal_error("invalid encoding");
175
+ }
176
+
177
+ static const char *
178
+ fixed_tag_as_string(enum ndt_contig tag)
179
+ {
180
+ switch (tag) {
181
+ case RequireNA: return "None";
182
+ case RequireC: return "C";
183
+ case RequireF: return "Fortran";
184
+ }
185
+
186
+ /* NOT REACHED: tags should be exhaustive. */
187
+ ndt_internal_error("invalid contiguity tag");
188
+ }
189
+
190
+
191
+ /******************************************************************************/
192
+ /* String buffer */
193
+ /******************************************************************************/
194
+
195
+ #undef buf_t
196
+ typedef struct {
197
+ size_t count; /* count the required size */
198
+ size_t size; /* buffer size (0 for the count phase) */
199
+ char *cur; /* buffer data (NULL for the count phase) */
200
+ } buf_t;
201
+
202
+ static int indent(ndt_context_t *ctx, buf_t *buf, int n);
203
+
204
+ static int
205
+ _ndt_snprintf(ndt_context_t *ctx, buf_t *buf, const char *fmt, va_list ap)
206
+ {
207
+ int n;
208
+
209
+ errno = 0;
210
+ n = vsnprintf(buf->cur, buf->size, fmt, ap);
211
+ if (buf->cur && n < 0) {
212
+ if (errno == ENOMEM) {
213
+ ndt_err_format(ctx, NDT_MemoryError, "out of memory");
214
+ }
215
+ else {
216
+ ndt_err_format(ctx, NDT_OSError, "output error");
217
+ }
218
+ return -1;
219
+ }
220
+
221
+ if (buf->cur && (size_t)n >= buf->size) {
222
+ ndt_err_format(ctx, NDT_ValueError, "insufficient buffer size");
223
+ return -1;
224
+ }
225
+
226
+ buf->count += n;
227
+
228
+ if (buf->cur) {
229
+ buf->cur += n;
230
+ buf->size -= n;
231
+ }
232
+
233
+ return 0;
234
+ }
235
+
236
+ static int
237
+ ndt_snprintf(ndt_context_t *ctx, buf_t *buf, const char *fmt, ...)
238
+ {
239
+ va_list ap;
240
+ int n;
241
+
242
+ va_start(ap, fmt);
243
+ n = _ndt_snprintf(ctx, buf, fmt, ap);
244
+ va_end(ap);
245
+
246
+ return n;
247
+ }
248
+
249
+ static int
250
+ ndt_snprintf_d(ndt_context_t *ctx, buf_t *buf, int d, const char *fmt, ...)
251
+ {
252
+ va_list ap;
253
+ int n;
254
+
255
+ n = indent(ctx, buf, d);
256
+ if (n < 0) return -1;
257
+
258
+ va_start(ap, fmt);
259
+ n = _ndt_snprintf(ctx, buf, fmt, ap);
260
+ va_end(ap);
261
+
262
+ return n;
263
+ }
264
+
265
+ static int
266
+ indent(ndt_context_t *ctx, buf_t *buf, int n)
267
+ {
268
+ int i;
269
+
270
+ if (n < 0) {
271
+ return 0;
272
+ }
273
+
274
+ for (i = 0; i < n; i++) {
275
+ if (ndt_snprintf(ctx, buf, " ") < 0) {
276
+ return -1;
277
+ }
278
+ }
279
+
280
+ return 0;
281
+ }
282
+
283
+
284
+ /******************************************************************************/
285
+ /* String representation of a type */
286
+ /******************************************************************************/
287
+
288
+ static int datashape(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx);
289
+
290
+ static int
291
+ datashape_list(buf_t *buf, const ndt_t *types[], int64_t start, int64_t stop,
292
+ int d, ndt_context_t *ctx)
293
+ {
294
+ int64_t i;
295
+ int n;
296
+
297
+ if (start == stop) {
298
+ n = ndt_snprintf(ctx, buf, "void");
299
+ if (n < 0) return -1;
300
+ }
301
+ else {
302
+ for (i = start; i < stop; i++) {
303
+ if (i >= start+1) {
304
+ n = ndt_snprintf(ctx, buf, ", ");
305
+ if (n < 0) return -1;
306
+ }
307
+
308
+ n = datashape(buf, types[i], d, ctx);
309
+ if (n < 0) return -1;
310
+ }
311
+ }
312
+
313
+ return 0;
314
+ }
315
+
316
+ static int
317
+ function_types(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
318
+ {
319
+ const ndt_t **types = (const ndt_t **)t->Function.types;
320
+ int n;
321
+
322
+ assert(t->tag == Function);
323
+
324
+ n = datashape_list(buf, types, 0, t->Function.nin, d, ctx);
325
+ if (n < 0) return -1;
326
+
327
+ n = ndt_snprintf(ctx, buf, " -> ");
328
+ if (n < 0) return -1;
329
+
330
+ return datashape_list(buf, types, t->Function.nin, t->Function.nargs,
331
+ d, ctx);
332
+ }
333
+
334
+ static int
335
+ tuple_fields(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
336
+ {
337
+ int64_t i;
338
+ int n;
339
+
340
+ assert(t->tag == Tuple);
341
+
342
+ for (i = 0; i < t->Tuple.shape; i++) {
343
+ if (i >= 1) {
344
+ n = ndt_snprintf(ctx, buf, ", ");
345
+ if (n < 0) return -1;
346
+ }
347
+
348
+ n = datashape(buf, t->Tuple.types[i], d, ctx);
349
+ if (n < 0) return -1;
350
+ }
351
+
352
+ return 0;
353
+ }
354
+
355
+ static int
356
+ record_fields(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
357
+ {
358
+ int64_t i;
359
+ int n;
360
+
361
+ assert(t->tag == Record);
362
+
363
+ for (i = 0; i < t->Tuple.shape; i++) {
364
+ if (i >= 1) {
365
+ if (d >= 0) {
366
+ n = ndt_snprintf(ctx, buf, ",\n");
367
+ if (n < 0) return -1;
368
+
369
+ n = indent(ctx, buf, d);
370
+ if (n < 0) return -1;
371
+ }
372
+ else {
373
+ n = ndt_snprintf(ctx, buf, ", ");
374
+ if (n < 0) return -1;
375
+ }
376
+ }
377
+
378
+ n = ndt_snprintf(ctx, buf, "%s : ", t->Record.names[i]);
379
+ if (n < 0) return -1;
380
+
381
+ n = datashape(buf, t->Record.types[i], d, ctx);
382
+ if (n < 0) return -1;
383
+ }
384
+
385
+ return 0;
386
+ }
387
+
388
+ static int
389
+ variadic_flag(buf_t *buf, enum ndt_variadic flag, ndt_context_t *ctx)
390
+ {
391
+ if (flag == Variadic) {
392
+ return ndt_snprintf(ctx, buf, "...");
393
+ }
394
+
395
+ return 0;
396
+ }
397
+
398
+ static int
399
+ comma_variadic_flag(buf_t *buf, enum ndt_variadic flag, int d, ndt_context_t *ctx)
400
+ {
401
+ int n;
402
+
403
+ if (flag == Variadic) {
404
+ if (d >= 0) {
405
+ n = ndt_snprintf(ctx, buf, ",\n");
406
+ if (n < 0) return -1;
407
+
408
+ n = indent(ctx, buf, d);
409
+ if (n < 0) return -1;
410
+
411
+ return ndt_snprintf(ctx, buf, "...");
412
+ }
413
+ else {
414
+ return ndt_snprintf(ctx, buf, ", ...");
415
+ }
416
+ }
417
+
418
+ return 0;
419
+ }
420
+
421
+ static int
422
+ value(buf_t *buf, const ndt_value_t *mem, ndt_context_t *ctx)
423
+ {
424
+ switch (mem->tag) {
425
+ case ValBool:
426
+ return ndt_snprintf(ctx, buf, mem->ValBool ? "true" : "false");
427
+ case ValInt64:
428
+ return ndt_snprintf(ctx, buf, "%" PRIi64, mem->ValInt64);
429
+ case ValFloat64:
430
+ return ndt_snprintf(ctx, buf, "%g", mem->ValFloat64);
431
+ case ValString:
432
+ return ndt_snprintf(ctx, buf, "'%s'", mem->ValString);
433
+ case ValNA:
434
+ return ndt_snprintf(ctx, buf, "NA");
435
+ }
436
+
437
+ /* NOT REACHED: tags should be exhaustive. */
438
+ ndt_err_format(ctx, NDT_RuntimeError, "invalid value tag");
439
+ return 0;
440
+ }
441
+
442
+ static int
443
+ categorical(buf_t *buf, ndt_value_t *mem, int64_t ntypes, ndt_context_t *ctx)
444
+ {
445
+ int64_t i;
446
+ int n;
447
+
448
+ for (i = 0; i < ntypes; i++) {
449
+ if (i >= 1) {
450
+ n = ndt_snprintf(ctx, buf, ", ");
451
+ if (n < 0) return -1;
452
+ }
453
+
454
+ n = value(buf, &mem[i], ctx);
455
+ if (n < 0) return -1;
456
+ }
457
+
458
+ return 0;
459
+ }
460
+
461
+ static int
462
+ fortran(buf_t *buf, const ndt_t *t, ndt_context_t *ctx)
463
+ {
464
+ if (ndt_really_fortran(t)) {
465
+ return ndt_snprintf(ctx, buf, "!");
466
+ }
467
+
468
+ return 1;
469
+ }
470
+
471
+ static int
472
+ option(buf_t *buf, const ndt_t *t, ndt_context_t *ctx)
473
+ {
474
+ if (ndt_is_optional(t)) {
475
+ return ndt_snprintf(ctx, buf, "?");
476
+ }
477
+
478
+ return 1;
479
+ }
480
+
481
+ static int
482
+ endian(buf_t *buf, const ndt_t *t, ndt_context_t *ctx)
483
+ {
484
+ if (ndt_endian_is_set(t)) {
485
+ if (ndt_is_little_endian(t)) {
486
+ return ndt_snprintf(ctx, buf, "<");
487
+ }
488
+ return ndt_snprintf(ctx, buf, ">");
489
+ }
490
+
491
+ return 1;
492
+ }
493
+
494
+ static int
495
+ datashape(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
496
+ {
497
+ int n;
498
+
499
+ n = fortran(buf, t, ctx);
500
+ if (n < 0) return -1;
501
+
502
+ n = option(buf, t, ctx);
503
+ if (n < 0) return -1;
504
+
505
+ n = endian(buf, t, ctx);
506
+ if (n < 0) return -1;
507
+
508
+ switch (t->tag) {
509
+ case Module: {
510
+ n = ndt_snprintf(ctx, buf, "%s:: ", t->Module.name);
511
+ if (n < 0) return -1;
512
+
513
+ return datashape(buf, t->Module.type, d, ctx);
514
+ }
515
+
516
+ case Function: {
517
+ return function_types(buf, t, d, ctx);
518
+ }
519
+
520
+ case FixedDim: {
521
+ n = ndt_snprintf(ctx, buf, "%s", t->FixedDim.tag==RequireC ? "C[" : "");
522
+ if (n < 0) return -1;
523
+
524
+ n = ndt_snprintf(ctx, buf, "%s", t->FixedDim.tag==RequireF ? "F[" : "");
525
+ if (n < 0) return -1;
526
+
527
+ n = ndt_snprintf(ctx, buf, "%" PRIi64 " * ", t->FixedDim.shape);
528
+ if (n < 0) return -1;
529
+
530
+ n = datashape(buf, t->FixedDim.type, d, ctx);
531
+ if (n < 0) return -1;
532
+
533
+ return ndt_snprintf(ctx, buf, "%s", t->FixedDim.tag==RequireNA ? "" : "]");
534
+ }
535
+
536
+ case VarDim: {
537
+ n = ndt_snprintf(ctx, buf, "var * ");
538
+ if (n < 0) return -1;
539
+
540
+ return datashape(buf, t->VarDim.type, d, ctx);
541
+ }
542
+
543
+ case SymbolicDim: {
544
+ n = ndt_snprintf(ctx, buf, "%s", t->SymbolicDim.tag==RequireC ? "C[" : "");
545
+ if (n < 0) return -1;
546
+
547
+ n = ndt_snprintf(ctx, buf, "%s", t->SymbolicDim.tag==RequireF ? "F[" : "");
548
+ if (n < 0) return -1;
549
+
550
+ n = ndt_snprintf(ctx, buf, "%s * ", t->SymbolicDim.name);
551
+ if (n < 0) return -1;
552
+
553
+ n = datashape(buf, t->SymbolicDim.type, d, ctx);
554
+ if (n < 0) return -1;
555
+
556
+ return ndt_snprintf(ctx, buf, "%s", t->SymbolicDim.tag==RequireNA ? "" : "]");
557
+ }
558
+
559
+ case EllipsisDim: {
560
+ n = ndt_snprintf(ctx, buf, "%s", t->EllipsisDim.tag==RequireC ? "C[" : "");
561
+ if (n < 0) return -1;
562
+
563
+ n = ndt_snprintf(ctx, buf, "%s", t->EllipsisDim.tag==RequireF ? "F[" : "");
564
+ if (n < 0) return -1;
565
+
566
+ n = ndt_snprintf(ctx, buf, "%s... * ",
567
+ t->EllipsisDim.name ? t->EllipsisDim.name : "");
568
+ if (n < 0) return -1;
569
+
570
+ n = datashape(buf, t->EllipsisDim.type, d, ctx);
571
+ if (n < 0) return -1;
572
+
573
+ return ndt_snprintf(ctx, buf, "%s", t->EllipsisDim.tag==RequireNA ? "" : "]");
574
+ }
575
+
576
+ case Tuple: {
577
+ n = ndt_snprintf(ctx, buf, "(");
578
+ if (n < 0) return -1;
579
+
580
+ if (t->Tuple.shape > 0) {
581
+ n = tuple_fields(buf, t, d, ctx);
582
+ if (n < 0) return -1;
583
+
584
+ n = comma_variadic_flag(buf, t->Tuple.flag, INT_MIN, ctx);
585
+ if (n < 0) return -1;
586
+ }
587
+ else {
588
+ n = variadic_flag(buf, t->Tuple.flag, ctx);
589
+ if (n < 0) return -1;
590
+ }
591
+
592
+ return ndt_snprintf(ctx, buf, ")");
593
+ }
594
+
595
+ case Record: {
596
+ n = ndt_snprintf(ctx, buf, "{");
597
+ if (n < 0) return -1;
598
+
599
+ if (d >= 0) {
600
+ n = ndt_snprintf(ctx, buf, "\n");
601
+ if (n < 0) return -1;
602
+ n = indent(ctx, buf, d+2);
603
+ if (n < 0) return -1;
604
+ }
605
+
606
+ if (t->Record.shape > 0) {
607
+ n = record_fields(buf, t, d+2, ctx);
608
+ if (n < 0) return -1;
609
+
610
+ n = comma_variadic_flag(buf, t->Record.flag, d+2, ctx);
611
+ if (n < 0) return -1;
612
+ }
613
+ else {
614
+ n = variadic_flag(buf, t->Record.flag, ctx);
615
+ if (n < 0) return -1;
616
+
617
+ }
618
+
619
+ if (d >= 0) {
620
+ n = ndt_snprintf(ctx, buf, "\n");
621
+ if (n < 0) return -1;
622
+ n = indent(ctx, buf, d);
623
+ if (n < 0) return -1;
624
+ }
625
+
626
+ return ndt_snprintf(ctx, buf, "}");
627
+ }
628
+
629
+ case Ref: {
630
+ n = ndt_snprintf(ctx, buf, "ref(");
631
+ if (n < 0) return -1;
632
+
633
+ n = datashape(buf, t->Ref.type, d, ctx);
634
+ if (n < 0) return -1;
635
+
636
+ return ndt_snprintf(ctx, buf, ")");
637
+ }
638
+
639
+ case Constr: {
640
+ n = ndt_snprintf(ctx, buf, "%s(", t->Constr.name);
641
+ if (n < 0) return -1;
642
+
643
+ n = datashape(buf, t->Constr.type, d, ctx);
644
+ if (n < 0) return -1;
645
+
646
+ return ndt_snprintf(ctx, buf, ")");
647
+ }
648
+
649
+ case Nominal: {
650
+ return ndt_snprintf(ctx, buf, "%s", t->Nominal.name);
651
+ }
652
+
653
+ case Categorical: {
654
+ n = ndt_snprintf(ctx, buf, "categorical(");
655
+ if (n < 0) return -1;
656
+
657
+ n = categorical(buf, t->Categorical.types, t->Categorical.ntypes, ctx);
658
+ if (n < 0) return -1;
659
+
660
+ return ndt_snprintf(ctx, buf, ")");
661
+ }
662
+
663
+ case FixedString: {
664
+ if (t->FixedString.encoding == Utf8) {
665
+ return ndt_snprintf(ctx, buf, "fixed_string(%" PRIi64 ")",
666
+ t->FixedString.size);
667
+ }
668
+ else {
669
+ return ndt_snprintf(ctx, buf, "fixed_string(%" PRIi64 ", %s)",
670
+ t->FixedString.size,
671
+ ndt_encoding_as_string(t->FixedString.encoding));
672
+ }
673
+ }
674
+
675
+ case FixedBytes: {
676
+ if (t->FixedBytes.align == 1) {
677
+ return ndt_snprintf(ctx, buf, "fixed_bytes(size=%" PRIi64 ")",
678
+ t->FixedBytes.size);
679
+ }
680
+ else {
681
+ return ndt_snprintf(ctx, buf, "fixed_bytes(size=%" PRIi64 ", align=%" PRIu8 ")",
682
+ t->FixedBytes.size, t->FixedBytes.align);
683
+ }
684
+ }
685
+
686
+ case Bytes: {
687
+ if (t->Bytes.target_align == 1) {
688
+ return ndt_snprintf(ctx, buf, "bytes");
689
+ }
690
+ else {
691
+ return ndt_snprintf(ctx, buf, "bytes(align=%" PRIu8 ")", t->Bytes.target_align);
692
+ }
693
+ }
694
+
695
+ case Char: {
696
+ return ndt_snprintf(ctx, buf, "char(%s)",
697
+ ndt_encoding_as_string(t->Char.encoding));
698
+ }
699
+
700
+ case Typevar: {
701
+ return ndt_snprintf(ctx, buf, "%s", t->Typevar.name);
702
+ }
703
+
704
+ case AnyKind:
705
+ case ScalarKind:
706
+ case Bool:
707
+ case SignedKind:
708
+ case Int8: case Int16: case Int32: case Int64:
709
+ case UnsignedKind:
710
+ case Uint8: case Uint16: case Uint32: case Uint64:
711
+ case FloatKind:
712
+ case Float16: case Float32: case Float64:
713
+ case ComplexKind:
714
+ case Complex32: case Complex64: case Complex128:
715
+ case FixedStringKind:
716
+ case FixedBytesKind:
717
+ case String:
718
+ return ndt_snprintf(ctx, buf, "%s", ndt_type_keyword(t));
719
+ }
720
+
721
+ /* NOT REACHED: tags should be exhaustive. */
722
+ ndt_internal_error("invalid tag");
723
+ }
724
+
725
+
726
+ /******************************************************************************/
727
+ /* Abstract syntax tree */
728
+ /******************************************************************************/
729
+
730
+ static int ast_datashape(buf_t *buf, const ndt_t *t, int d, int cont, ndt_context_t *ctx);
731
+
732
+ static int
733
+ ast_type_flags(buf_t *buf, const ndt_t *t, ndt_context_t *ctx)
734
+ {
735
+ bool cont = 0;
736
+ int n;
737
+
738
+ if (t->flags & NDT_OPTION) {
739
+ n = ndt_snprintf(ctx, buf, "%sOPTION", cont ? ", " : "");
740
+ if (n > 0) return -1;
741
+ cont = 1;
742
+ }
743
+
744
+ if (t->flags & NDT_SUBTREE_OPTION) {
745
+ n = ndt_snprintf(ctx, buf, "%sSUBTREE_OPTION", cont ? ", " : "");
746
+ if (n > 0) return -1;
747
+ cont = 1;
748
+ }
749
+
750
+ if (t->flags & NDT_LITTLE_ENDIAN) {
751
+ n = ndt_snprintf(ctx, buf, "%sLITTLE_ENDIAN", cont ? ", " : "");
752
+ if (n > 0) return -1;
753
+ cont = 1;
754
+ }
755
+
756
+ if (t->flags & NDT_BIG_ENDIAN) {
757
+ n = ndt_snprintf(ctx, buf, "%sBIG_ENDIAN", cont ? ", " : "");
758
+ if (n > 0) return -1;
759
+ cont = 1;
760
+ }
761
+
762
+ if (t->flags & NDT_ELLIPSIS) {
763
+ n = ndt_snprintf(ctx, buf, "%sELLIPSIS", cont ? ", " : "");
764
+ if (n > 0) return -1;
765
+ }
766
+
767
+ return 0;
768
+ }
769
+
770
+ static int
771
+ ast_common_attributes(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
772
+ {
773
+ int n;
774
+
775
+ if (ndt_is_abstract(t)) {
776
+ n = ndt_snprintf_d(ctx, buf, d, "access=Abstract, ndim=%d, ", t->ndim);
777
+ }
778
+ else {
779
+ n = ndt_snprintf_d(ctx, buf, d,
780
+ "access=Concrete, ndim=%d, datasize=%" PRIi64 ", align=%" PRIu16 ", ",
781
+ t->ndim, t->datasize, t->align);
782
+ }
783
+
784
+ if (n < 0) return -1;
785
+
786
+ n = ndt_snprintf(ctx, buf, "flags=[");
787
+ if (n < 0) return -1;
788
+
789
+ ast_type_flags(buf, t, ctx);
790
+ if (n < 0) return -1;
791
+
792
+ return ndt_snprintf(ctx, buf, "]");
793
+ }
794
+
795
+ static int
796
+ ast_common_attributes_with_newline(buf_t *buf, const ndt_t *t, int d,
797
+ ndt_context_t *ctx)
798
+ {
799
+ int n;
800
+
801
+ n = ast_common_attributes(buf, t, d, ctx);
802
+ if (n < 0) return -1;
803
+
804
+ return ndt_snprintf(ctx, buf, "\n");
805
+ }
806
+
807
+ static int
808
+ ast_function_types(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
809
+ {
810
+ int64_t i;
811
+ int n;
812
+
813
+ assert(t->tag == Function);
814
+
815
+ for (i = 0; i < t->Function.nin; i++) {
816
+ if (i >= 1) {
817
+ n = ndt_snprintf(ctx, buf, ",\n");
818
+ if (n < 0) return -1;
819
+ }
820
+
821
+ n = ndt_snprintf_d(ctx, buf, d, "ParamIn(\n");
822
+ if (n < 0) return -1;
823
+
824
+ n = ndt_snprintf_d(ctx, buf, d+2, "type=");
825
+ if (n < 0) return -1;
826
+
827
+ n = ast_datashape(buf, t->Function.types[i], d+5+2, 1, ctx);
828
+ if (n < 0) return -1;
829
+
830
+ n = ndt_snprintf_d(ctx, buf, d, ")");
831
+ if (n < 0) return -1;
832
+ }
833
+
834
+ for (i = 0; i < t->Function.nargs; i++) {
835
+ if (i >= 1) {
836
+ n = ndt_snprintf(ctx, buf, ",\n");
837
+ if (n < 0) return -1;
838
+ }
839
+
840
+ n = ndt_snprintf_d(ctx, buf, d, "ParamOut(\n");
841
+ if (n < 0) return -1;
842
+
843
+ n = ndt_snprintf_d(ctx, buf, d+2, "type=");
844
+ if (n < 0) return -1;
845
+
846
+ n = ast_datashape(buf, t->Function.types[i], d+5+2, 1, ctx);
847
+ if (n < 0) return -1;
848
+
849
+ n = ndt_snprintf_d(ctx, buf, d, ")");
850
+ if (n < 0) return -1;
851
+ }
852
+
853
+ return 0;
854
+ }
855
+
856
+ static int
857
+ ast_tuple_fields(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
858
+ {
859
+ int64_t i;
860
+ int n;
861
+
862
+ assert(t->tag == Tuple);
863
+
864
+ for (i = 0; i < t->Tuple.shape; i++) {
865
+ if (i >= 1) {
866
+ n = ndt_snprintf(ctx, buf, ",\n");
867
+ if (n < 0) return -1;
868
+ }
869
+
870
+ n = ndt_snprintf_d(ctx, buf, d, "TupleField(\n");
871
+ if (n < 0) return -1;
872
+
873
+ n = ndt_snprintf_d(ctx, buf, d+2, "type=");
874
+ if (n < 0) return -1;
875
+
876
+ n = ast_datashape(buf, t->Tuple.types[i], d+5+2, 1, ctx);
877
+ if (n < 0) return -1;
878
+
879
+ n = ndt_snprintf(ctx, buf, "%s\n", ndt_is_concrete(t) ? "," : "");
880
+ if (n < 0) return -1;
881
+
882
+ if (ndt_is_concrete(t)) {
883
+ n = ndt_snprintf_d(ctx, buf, d+2,
884
+ "offset=%" PRIi64 ", align=%" PRIu16 ", pad=%" PRIu16 "\n",
885
+ t->Concrete.Tuple.offset[i], t->Concrete.Tuple.align[i],
886
+ t->Concrete.Tuple.pad[i]);
887
+ if (n < 0) return -1;
888
+ }
889
+
890
+ n = ndt_snprintf_d(ctx, buf, d, ")");
891
+ if (n < 0) return -1;
892
+ }
893
+
894
+ return 0;
895
+ }
896
+
897
+ static int
898
+ ast_record_fields(buf_t *buf, const ndt_t *t, int d, ndt_context_t *ctx)
899
+ {
900
+ int64_t i;
901
+ int n;
902
+
903
+ assert(t->tag == Record);
904
+
905
+ for (i = 0; i < t->Record.shape; i++) {
906
+ if (i >= 1) {
907
+ n = ndt_snprintf(ctx, buf, ",\n");
908
+ if (n < 0) return -1;
909
+ }
910
+
911
+ n = ndt_snprintf_d(ctx, buf, d, "RecordField(\n");
912
+ if (n < 0) return -1;
913
+
914
+ n = ndt_snprintf_d(ctx, buf, d+2, "name='%s',\n", t->Record.names[i]);
915
+ if (n < 0) return -1;
916
+
917
+ n = ndt_snprintf_d(ctx, buf, d+2, "type=");
918
+ if (n < 0) return -1;
919
+
920
+ n = ast_datashape(buf, t->Record.types[i], d+5+2, 1, ctx);
921
+ if (n < 0) return -1;
922
+
923
+ n = ndt_snprintf(ctx, buf, "%s\n", ndt_is_concrete(t) ? "," : "");
924
+ if (n < 0) return -1;
925
+
926
+ if (ndt_is_concrete(t)) {
927
+ n = ndt_snprintf_d(ctx, buf, d+2,
928
+ "offset=%" PRIi64 ", align=%" PRIu16 ", pad=%" PRIu16 "\n",
929
+ t->Concrete.Record.offset[i], t->Concrete.Record.align[i],
930
+ t->Concrete.Record.pad[i]);
931
+ if (n < 0) return -1;
932
+ }
933
+
934
+ n = ndt_snprintf_d(ctx, buf, d, ")");
935
+ if (n < 0) return -1;
936
+ }
937
+
938
+ return 0;
939
+ }
940
+
941
+ static int
942
+ ast_variadic_flag(buf_t *buf, enum ndt_variadic flag, int d, ndt_context_t *ctx)
943
+ {
944
+ if (flag == Variadic) {
945
+ return ndt_snprintf_d(ctx, buf, d, "variadic=true,\n");
946
+ }
947
+
948
+ return 0;
949
+ }
950
+
951
+ static int
952
+ ast_comma_ast_variadic_flag(buf_t *buf, enum ndt_variadic flag, int d, ndt_context_t *ctx)
953
+ {
954
+ if (flag == Variadic) {
955
+ int n = ndt_snprintf(ctx, buf, ",\n");
956
+ if (n < 0) return -1;
957
+
958
+ return ndt_snprintf_d(ctx, buf, d, "variadic=true");
959
+ }
960
+
961
+ return 0;
962
+ }
963
+
964
+ static int
965
+ ast_value(buf_t *buf, const ndt_value_t *mem, ndt_context_t *ctx)
966
+ {
967
+ switch (mem->tag) {
968
+ case ValBool:
969
+ return ndt_snprintf(ctx, buf, mem->ValBool ? "true" : "false");
970
+ case ValInt64:
971
+ return ndt_snprintf(ctx, buf, "%" PRIi64, mem->ValInt64);
972
+ case ValFloat64:
973
+ return ndt_snprintf(ctx, buf, "%g", mem->ValFloat64);
974
+ case ValString:
975
+ return ndt_snprintf(ctx, buf, "'%s'", mem->ValString);
976
+ case ValNA:
977
+ return ndt_snprintf(ctx, buf, "NA");
978
+ }
979
+
980
+ /* NOT REACHED: tags should be exhaustive. */
981
+ ndt_err_format(ctx, NDT_RuntimeError, "invalid value tag");
982
+ return 0;
983
+ }
984
+
985
+ static int
986
+ ast_categorical(buf_t *buf, ndt_value_t *mem, int64_t ntypes, ndt_context_t *ctx)
987
+ {
988
+ int64_t i;
989
+ int n;
990
+
991
+ for (i = 0; i < ntypes; i++) {
992
+ if (i >= 1) {
993
+ n = ndt_snprintf(ctx, buf, ", ");
994
+ if (n < 0) return -1;
995
+ }
996
+
997
+ n = ast_value(buf, &mem[i], ctx);
998
+ if (n < 0) return -1;
999
+ }
1000
+
1001
+ return 0;
1002
+ }
1003
+
1004
+ static int
1005
+ ast_datashape(buf_t *buf, const ndt_t *t, int d, int cont, ndt_context_t *ctx)
1006
+ {
1007
+ int n;
1008
+
1009
+ switch (t->tag) {
1010
+ case Module: {
1011
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Module(\n");
1012
+ if (n < 0) return -1;
1013
+
1014
+ n = ndt_snprintf_d(ctx, buf, d+2, "name='%s',\n", t->Module.name);
1015
+ if (n < 0) return -1;
1016
+
1017
+ n = ndt_snprintf_d(ctx, buf, d+2, "type=");
1018
+ if (n < 0) return -1;
1019
+
1020
+ n = ast_datashape(buf, t->Module.type, d+5+2, 1, ctx);
1021
+ if (n < 0) return -1;
1022
+
1023
+ n = ndt_snprintf(ctx, buf, "\n");
1024
+ if (n < 0) return -1;
1025
+
1026
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1027
+ if (n < 0) return -1;
1028
+
1029
+ return ndt_snprintf_d(ctx, buf, d, ")");
1030
+ }
1031
+
1032
+ case Function: {
1033
+ return ast_function_types(buf, t, d+2, ctx);
1034
+ }
1035
+
1036
+ case FixedDim: {
1037
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "FixedDim(\n");
1038
+ if (n < 0) return -1;
1039
+
1040
+ n = ast_datashape(buf, t->FixedDim.type, d+2, 0, ctx);
1041
+ if (n < 0) return -1;
1042
+
1043
+ n = ndt_snprintf(ctx, buf, ",\n");
1044
+ if (n < 0) return -1;
1045
+
1046
+ n = ndt_snprintf_d(ctx, buf, d+2, "tag=%s, shape=%" PRIi64,
1047
+ fixed_tag_as_string(t->FixedDim.tag),
1048
+ t->FixedDim.shape);
1049
+ if (n < 0) return -1;
1050
+
1051
+ if (ndt_is_abstract(t)) {
1052
+ n = ndt_snprintf(ctx, buf, ",\n");
1053
+ if (n < 0) return -1;
1054
+ }
1055
+ else {
1056
+ n = ndt_snprintf(ctx, buf,
1057
+ ", itemsize=%" PRIi64 ", step=%" PRIi64 ",\n",
1058
+ t->Concrete.FixedDim.itemsize,
1059
+ t->Concrete.FixedDim.step);
1060
+ }
1061
+ if (n < 0) return -1;
1062
+
1063
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1064
+ if (n < 0) return -1;
1065
+
1066
+ return ndt_snprintf_d(ctx, buf, d, ")");
1067
+ }
1068
+
1069
+ case VarDim: {
1070
+ int i;
1071
+
1072
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "VarDim(\n");
1073
+ if (n < 0) return -1;
1074
+
1075
+ n = ast_datashape(buf, t->VarDim.type, d+2, 0, ctx);
1076
+ if (n < 0) return -1;
1077
+
1078
+ n = ndt_snprintf(ctx, buf, ",\n");
1079
+ if (n < 0) return -1;
1080
+
1081
+ if (ndt_is_concrete(t)) {
1082
+ n = ndt_snprintf_d(ctx, buf, d+2, "offsets=[");
1083
+ if (n < 0) return -1;
1084
+
1085
+ for (i = 0; i < t->Concrete.VarDim.noffsets; i++) {
1086
+ n = ndt_snprintf(ctx, buf, "%" PRIi32 "%s",
1087
+ t->Concrete.VarDim.offsets[i],
1088
+ i==t->Concrete.VarDim.noffsets-1 ? "" : ", ");
1089
+ if (n < 0) return -1;
1090
+ }
1091
+
1092
+ n = ndt_snprintf(ctx, buf, "],\n");
1093
+ if (n < 0) return -1;
1094
+
1095
+ n = ndt_snprintf_d(ctx, buf, d+2, "slices=[");
1096
+ if (n < 0) return -1;
1097
+
1098
+ for (i = 0; i < t->Concrete.VarDim.nslices; i++) {
1099
+ n = ndt_snprintf(ctx, buf, "%" PRIi64 ":%" PRIi64 ":%" PRIi64 "%s",
1100
+ t->Concrete.VarDim.slices[i].start,
1101
+ t->Concrete.VarDim.slices[i].stop,
1102
+ t->Concrete.VarDim.slices[i].step,
1103
+ i==t->Concrete.VarDim.nslices-1 ? "" : ", ");
1104
+ if (n < 0) return -1;
1105
+ }
1106
+
1107
+ n = ndt_snprintf(ctx, buf, "],\n");
1108
+ if (n < 0) return -1;
1109
+
1110
+ n = ndt_snprintf_d(ctx, buf, d+2,
1111
+ "itemsize=%" PRIi64 ",\n", t->Concrete.VarDim.itemsize);
1112
+ if (n < 0) return -1;
1113
+ }
1114
+
1115
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1116
+ if (n < 0) return -1;
1117
+
1118
+ return ndt_snprintf_d(ctx, buf, d, ")");
1119
+ }
1120
+
1121
+ case SymbolicDim: {
1122
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "SymbolicDim(\n");
1123
+ if (n < 0) return -1;
1124
+
1125
+ n = ast_datashape(buf, t->SymbolicDim.type, d+2, 0, ctx);
1126
+ if (n < 0) return -1;
1127
+
1128
+ n = ndt_snprintf(ctx, buf, ",\n");
1129
+ if (n < 0) return -1;
1130
+
1131
+ n = ndt_snprintf_d(ctx, buf, d+2, "tag=%s, name='%s',\n",
1132
+ t->SymbolicDim.tag,
1133
+ t->SymbolicDim.name);
1134
+ if (n < 0) return -1;
1135
+
1136
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1137
+ if (n < 0) return -1;
1138
+
1139
+ return ndt_snprintf_d(ctx, buf, d, ")");
1140
+ }
1141
+
1142
+ case EllipsisDim: {
1143
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "EllipsisDim(\n");
1144
+ if (n < 0) return -1;
1145
+
1146
+ n = ast_datashape(buf, t->EllipsisDim.type, d+2, 0, ctx);
1147
+ if (n < 0) return -1;
1148
+
1149
+ n = ndt_snprintf(ctx, buf, "\n");
1150
+ if (n < 0) return -1;
1151
+
1152
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1153
+ if (n < 0) return -1;
1154
+
1155
+ return ndt_snprintf_d(ctx, buf, d, ")");
1156
+ }
1157
+
1158
+ case Tuple: {
1159
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Tuple(\n");
1160
+ if (n < 0) return -1;
1161
+
1162
+ if (t->Tuple.shape > 0) {
1163
+ n = ast_tuple_fields(buf, t, d+2, ctx);
1164
+ if (n < 0) return -1;
1165
+
1166
+ n = ast_comma_ast_variadic_flag(buf, t->Tuple.flag, d+2, ctx);
1167
+ if (n < 0) return -1;
1168
+
1169
+ n = ndt_snprintf(ctx, buf, ",\n");
1170
+ if (n < 0) return -1;
1171
+ }
1172
+ else {
1173
+ n = ast_variadic_flag(buf, t->Tuple.flag, d+2, ctx);
1174
+ if (n < 0) return -1;
1175
+ }
1176
+
1177
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1178
+ if (n < 0) return -1;
1179
+
1180
+ return ndt_snprintf_d(ctx, buf, d, ")");
1181
+ }
1182
+
1183
+ case Record: {
1184
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Record(\n");
1185
+ if (n < 0) return -1;
1186
+
1187
+ if (t->Record.shape > 0) {
1188
+ n = ast_record_fields(buf, t, d+2, ctx);
1189
+ if (n < 0) return -1;
1190
+
1191
+ n = ast_comma_ast_variadic_flag(buf, t->Record.flag, d+2, ctx);
1192
+ if (n < 0) return -1;
1193
+
1194
+ n = ndt_snprintf(ctx, buf, ",\n");
1195
+ if (n < 0) return -1;
1196
+ }
1197
+ else {
1198
+ n = ast_variadic_flag(buf, t->Record.flag, d+2, ctx);
1199
+ if (n < 0) return -1;
1200
+ }
1201
+
1202
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1203
+ if (n < 0) return -1;
1204
+
1205
+ return ndt_snprintf_d(ctx, buf, d, ")");
1206
+ }
1207
+
1208
+ case Ref: {
1209
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Ref(\n");
1210
+ if (n < 0) return -1;
1211
+
1212
+ n = ast_datashape(buf, t->Ref.type, d+2, 0, ctx);
1213
+ if (n < 0) return -1;
1214
+
1215
+ n = ndt_snprintf(ctx, buf, ",\n");
1216
+ if (n < 0) return -1;
1217
+
1218
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1219
+ if (n < 0) return -1;
1220
+
1221
+ return ndt_snprintf_d(ctx, buf, d, ")");
1222
+ }
1223
+
1224
+ case Constr: {
1225
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Constr(\n");
1226
+ if (n < 0) return -1;
1227
+
1228
+ n = ndt_snprintf_d(ctx, buf, d+2, "name='%s',\n", t->Constr.name);
1229
+ if (n < 0) return -1;
1230
+
1231
+ n = ndt_snprintf_d(ctx, buf, d+2, "type=");
1232
+ if (n < 0) return -1;
1233
+
1234
+ n = ast_datashape(buf, t->Constr.type, d+5+2, 1, ctx);
1235
+ if (n < 0) return -1;
1236
+
1237
+ n = ndt_snprintf(ctx, buf, "\n");
1238
+ if (n < 0) return -1;
1239
+
1240
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1241
+ if (n < 0) return -1;
1242
+
1243
+ return ndt_snprintf_d(ctx, buf, d, ")");
1244
+ }
1245
+
1246
+ case Nominal: {
1247
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Nominal(\n");
1248
+ if (n < 0) return -1;
1249
+
1250
+ n = ndt_snprintf_d(ctx, buf, d+2, "name='%s',\n", t->Nominal.name);
1251
+ if (n < 0) return -1;
1252
+
1253
+ n = ndt_snprintf_d(ctx, buf, d+2, "type=");
1254
+ if (n < 0) return -1;
1255
+
1256
+ n = ast_datashape(buf, t->Nominal.type, d+5+2, 1, ctx);
1257
+ if (n < 0) return -1;
1258
+
1259
+ n = ndt_snprintf(ctx, buf, "\n");
1260
+ if (n < 0) return -1;
1261
+
1262
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1263
+ if (n < 0) return -1;
1264
+
1265
+ return ndt_snprintf_d(ctx, buf, d, ")");
1266
+ }
1267
+
1268
+ case Categorical: {
1269
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Categorical(\n");
1270
+ if (n < 0) return -1;
1271
+
1272
+ n = ndt_snprintf_d(ctx, buf, d+2, "items=[");
1273
+ if (n < 0) return -1;
1274
+
1275
+ n = ast_categorical(buf, t->Categorical.types, t->Categorical.ntypes, ctx);
1276
+ if (n < 0) return -1;
1277
+
1278
+ n = ndt_snprintf(ctx, buf, "],\n");
1279
+ if (n < 0) return -1;
1280
+
1281
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1282
+ if (n < 0) return -1;
1283
+
1284
+ return ndt_snprintf_d(ctx, buf, d, ")");
1285
+ }
1286
+
1287
+ case FixedString: {
1288
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "FixedString(\n");
1289
+ if (n < 0) return -1;
1290
+
1291
+ n = ndt_snprintf_d(ctx, buf, d+2, "size=%" PRIi64 ", encoding=%s,\n",
1292
+ t->FixedString.size,
1293
+ ndt_encoding_as_string(t->FixedString.encoding));
1294
+ if (n < 0) return -1;
1295
+
1296
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1297
+ if (n < 0) return -1;
1298
+
1299
+ return ndt_snprintf_d(ctx, buf, d, ")");
1300
+ }
1301
+
1302
+ case FixedBytes: {
1303
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "FixedBytes(\n");
1304
+ if (n < 0) return -1;
1305
+
1306
+ n = ndt_snprintf_d(ctx, buf, d+2, "size=%" PRIi64 ", align=%" PRIu16 ",\n",
1307
+ t->FixedBytes.size,
1308
+ t->FixedBytes.align);
1309
+ if (n < 0) return -1;
1310
+
1311
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1312
+ if (n < 0) return -1;
1313
+
1314
+ return ndt_snprintf_d(ctx, buf, d, ")");
1315
+ }
1316
+
1317
+ case Bytes: {
1318
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Bytes(\n");
1319
+ if (n < 0) return -1;
1320
+
1321
+ n = ndt_snprintf_d(ctx, buf, d+2, "target_align=%" PRIu16 ",\n",
1322
+ t->Bytes.target_align);
1323
+ if (n < 0) return -1;
1324
+
1325
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1326
+ if (n < 0) return -1;
1327
+
1328
+ return ndt_snprintf_d(ctx, buf, d, ")");
1329
+ }
1330
+
1331
+ case Char: {
1332
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Char(\n");
1333
+ if (n < 0) return -1;
1334
+
1335
+ n = ndt_snprintf_d(ctx, buf, d+2, "encoding=%s,\n",
1336
+ ndt_encoding_as_string(t->Char.encoding));
1337
+ if (n < 0) return -1;
1338
+
1339
+ n = ast_common_attributes_with_newline(buf, t, d+2, ctx);
1340
+ if (n < 0) return -1;
1341
+
1342
+ return ndt_snprintf_d(ctx, buf, d, ")");
1343
+ }
1344
+
1345
+ case Typevar: {
1346
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "Typevar(");
1347
+ if (n < 0) return -1;
1348
+
1349
+ n = ndt_snprintf(ctx, buf, "name='%s', ", t->Typevar.name);
1350
+ if (n < 0) return -1;
1351
+
1352
+ n = ast_common_attributes(buf, t, 0, ctx);
1353
+ if (n < 0) return -1;
1354
+
1355
+ return ndt_snprintf(ctx, buf, ")");
1356
+ }
1357
+
1358
+ case AnyKind: case ScalarKind:
1359
+ case Bool:
1360
+ case SignedKind:
1361
+ case Int8: case Int16: case Int32: case Int64:
1362
+ case UnsignedKind:
1363
+ case Uint8: case Uint16: case Uint32: case Uint64:
1364
+ case FloatKind:
1365
+ case Float16: case Float32: case Float64:
1366
+ case ComplexKind:
1367
+ case Complex32: case Complex64: case Complex128:
1368
+ case FixedStringKind: case FixedBytesKind:
1369
+ case String:
1370
+ n = ndt_snprintf_d(ctx, buf, cont ? 0 : d, "%s(", ndt_type_name(t));
1371
+ if (n < 0) return -1;
1372
+
1373
+ n = ast_common_attributes(buf, t, 0, ctx);
1374
+ if (n < 0) return -1;
1375
+
1376
+ return ndt_snprintf(ctx, buf, ")");
1377
+ }
1378
+
1379
+ /* NOT REACHED: tags should be exhaustive. */
1380
+ ndt_internal_error("invalid tag");
1381
+ }
1382
+
1383
+
1384
+ /******************************************************************************/
1385
+ /* API: string to primitive type conversions */
1386
+ /******************************************************************************/
1387
+
1388
+ bool
1389
+ ndt_strtobool(const char *v, ndt_context_t *ctx)
1390
+ {
1391
+ if (strcmp(v, "true") == 0) {
1392
+ return 1;
1393
+ }
1394
+ else if (strcmp(v, "false") == 0) {
1395
+ return 0;
1396
+ }
1397
+ else {
1398
+ ndt_err_format(ctx, NDT_InvalidArgumentError,
1399
+ "valid values for bool are 'true' or 'false'");
1400
+ return 0;
1401
+ }
1402
+ }
1403
+
1404
+ char
1405
+ ndt_strtochar(const char *v, ndt_context_t *ctx)
1406
+ {
1407
+ if (strlen(v) == 1) {
1408
+ return v[0];
1409
+ }
1410
+ else {
1411
+ ndt_err_format(ctx, NDT_InvalidArgumentError, "invalid char");
1412
+ return 0;
1413
+ }
1414
+ }
1415
+
1416
+ long
1417
+ ndt_strtol(const char *v, long min, long max, ndt_context_t *ctx)
1418
+ {
1419
+ char *endptr;
1420
+ long ld;
1421
+
1422
+ errno = 0;
1423
+ ld = strtol(v, &endptr, 10);
1424
+
1425
+ if (*v == '\0' || *endptr != '\0') {
1426
+ ndt_err_format(ctx, NDT_InvalidArgumentError,
1427
+ "invalid integer: '%s'", v);
1428
+ }
1429
+ if (errno == ERANGE || ld < min || ld > max) {
1430
+ ndt_err_format(ctx, NDT_ValueError,
1431
+ "out of range: '%s'", v);
1432
+ }
1433
+
1434
+ return ld;
1435
+ }
1436
+
1437
+ long long
1438
+ ndt_strtoll(const char *v, long long min, long long max, ndt_context_t *ctx)
1439
+ {
1440
+ char *endptr;
1441
+ long long lld;
1442
+
1443
+ errno = 0;
1444
+ lld = strtoll(v, &endptr, 10);
1445
+ if (*v == '\0' || *endptr != '\0') {
1446
+ ndt_err_format(ctx, NDT_InvalidArgumentError,
1447
+ "invalid integer: '%s'", v);
1448
+ }
1449
+ if (errno == ERANGE || lld < min || lld > max) {
1450
+ ndt_err_format(ctx, NDT_ValueError,
1451
+ "out of range: '%s'", v);
1452
+ }
1453
+
1454
+ return lld;
1455
+ }
1456
+
1457
+ unsigned long
1458
+ ndt_strtoul(const char *v, unsigned long max, ndt_context_t *ctx)
1459
+ {
1460
+ char *endptr;
1461
+ unsigned long lu;
1462
+
1463
+ errno = 0;
1464
+ lu = strtoul(v, &endptr, 10);
1465
+ if (*v == '\0' || *endptr != '\0') {
1466
+ ndt_err_format(ctx, NDT_InvalidArgumentError,
1467
+ "invalid integer: '%s'", v);
1468
+ }
1469
+ if (errno == ERANGE || lu > max) {
1470
+ ndt_err_format(ctx, NDT_ValueError,
1471
+ "out of range: '%s'", v);
1472
+ }
1473
+
1474
+ return lu;
1475
+ }
1476
+
1477
+ unsigned long long
1478
+ ndt_strtoull(const char *v, unsigned long long max, ndt_context_t *ctx)
1479
+ {
1480
+ char *endptr;
1481
+ unsigned long long llu;
1482
+
1483
+ errno = 0;
1484
+ llu = strtoull(v, &endptr, 10);
1485
+ if (*v == '\0' || *endptr != '\0') {
1486
+ ndt_err_format(ctx, NDT_InvalidArgumentError,
1487
+ "invalid integer: '%s'", v);
1488
+ }
1489
+ if (errno == ERANGE || llu > max) {
1490
+ ndt_err_format(ctx, NDT_ValueError,
1491
+ "out of range: '%s'", v);
1492
+ }
1493
+
1494
+ return llu;
1495
+ }
1496
+
1497
+ /* Read a float. Overflow or underflow is an error. */
1498
+ float
1499
+ ndt_strtof(const char *v, ndt_context_t *ctx)
1500
+ {
1501
+ char *endptr;
1502
+ float f;
1503
+
1504
+ errno = 0;
1505
+ f = strtof(v, &endptr);
1506
+ if (*v == '\0' || *endptr != '\0') {
1507
+ ndt_err_format(ctx, NDT_InvalidArgumentError,
1508
+ "invalid float: '%s'", v);
1509
+ }
1510
+ if (errno == ERANGE) {
1511
+ ndt_err_format(ctx, NDT_ValueError,
1512
+ "%s: '%s'", f == 0 ? "underflow" : "overflow", v);
1513
+ }
1514
+
1515
+ return f;
1516
+ }
1517
+
1518
+ /* Read a double. Overflow or underflow is an error. */
1519
+ double
1520
+ ndt_strtod(const char *v, ndt_context_t *ctx)
1521
+ {
1522
+ char *endptr;
1523
+ double d;
1524
+
1525
+ errno = 0;
1526
+ d = strtod(v, &endptr);
1527
+ if (*v == '\0' || *endptr != '\0') {
1528
+ ndt_err_format(ctx, NDT_InvalidArgumentError,
1529
+ "invalid double: '%s'", v);
1530
+ }
1531
+ if (errno == ERANGE) {
1532
+ ndt_err_format(ctx, NDT_ValueError,
1533
+ "%s: '%s'", d == 0 ? "underflow" : "overflow", v);
1534
+ }
1535
+
1536
+ return d;
1537
+ }
1538
+
1539
+
1540
+ /******************************************************************************/
1541
+ /* API: type to string conversions */
1542
+ /******************************************************************************/
1543
+
1544
+ char *
1545
+ ndt_as_string(const ndt_t *t, ndt_context_t *ctx)
1546
+ {
1547
+ buf_t buf = {0, 0, NULL};
1548
+ char *s;
1549
+ size_t count;
1550
+
1551
+ if (datashape(&buf, t, INT_MIN, ctx) < 0) {
1552
+ return NULL;
1553
+ }
1554
+
1555
+ count = buf.count;
1556
+ buf.count = 0;
1557
+ buf.size = count+1;
1558
+
1559
+ buf.cur = s = ndt_alloc(1, count+1);
1560
+ if (buf.cur == NULL) {
1561
+ return ndt_memory_error(ctx);
1562
+ }
1563
+
1564
+ if (datashape(&buf, t, INT_MIN, ctx) < 0) {
1565
+ ndt_free(s);
1566
+ return NULL;
1567
+ }
1568
+ s[count] = '\0';
1569
+
1570
+ return s;
1571
+ }
1572
+
1573
+ char *
1574
+ ndt_list_as_string(const ndt_t *types[], int64_t len, ndt_context_t *ctx)
1575
+ {
1576
+ buf_t buf = {0, 0, NULL};
1577
+ char *s;
1578
+ size_t count;
1579
+
1580
+ if (datashape_list(&buf, types, 0, len, INT_MIN, ctx) < 0) {
1581
+ return NULL;
1582
+ }
1583
+
1584
+ count = buf.count;
1585
+ buf.count = 0;
1586
+ buf.size = count+1;
1587
+
1588
+ buf.cur = s = ndt_alloc(1, count+1);
1589
+ if (buf.cur == NULL) {
1590
+ return ndt_memory_error(ctx);
1591
+ }
1592
+
1593
+ if (datashape_list(&buf, types, 0, len, INT_MIN, ctx) < 0) {
1594
+ ndt_free(s);
1595
+ return NULL;
1596
+ }
1597
+ s[count] = '\0';
1598
+
1599
+ return s;
1600
+ }
1601
+
1602
+ char *
1603
+ ndt_indent(const ndt_t *t, ndt_context_t *ctx)
1604
+ {
1605
+ buf_t buf = {0, 0, NULL};
1606
+ char *s;
1607
+ size_t count;
1608
+
1609
+ if (datashape(&buf, t, 0, ctx) < 0) {
1610
+ return NULL;
1611
+ }
1612
+
1613
+ count = buf.count;
1614
+ buf.count = 0;
1615
+ buf.size = count+1;
1616
+
1617
+ buf.cur = s = ndt_alloc(1, count+1);
1618
+ if (buf.cur == NULL) {
1619
+ return ndt_memory_error(ctx);
1620
+ }
1621
+
1622
+ if (datashape(&buf, t, 0, ctx) < 0) {
1623
+ ndt_free(s);
1624
+ return NULL;
1625
+ }
1626
+ s[count] = '\0';
1627
+
1628
+ return s;
1629
+ }
1630
+
1631
+ char *
1632
+ ndt_ast_repr(const ndt_t *t, ndt_context_t *ctx)
1633
+ {
1634
+ buf_t buf = {0, 0, NULL};
1635
+ char *s;
1636
+ size_t count;
1637
+
1638
+ if (ast_datashape(&buf, t, 0, 0, ctx) < 0) {
1639
+ return NULL;
1640
+ }
1641
+
1642
+ count = buf.count;
1643
+ buf.count = 0;
1644
+ buf.size = count+1;
1645
+
1646
+ buf.cur = s = ndt_alloc(1, count+1);
1647
+ if (buf.cur == NULL) {
1648
+ return ndt_memory_error(ctx);
1649
+ }
1650
+
1651
+ if (ast_datashape(&buf, t, 0, 0, ctx) < 0) {
1652
+ ndt_free(s);
1653
+ return NULL;
1654
+ }
1655
+ s[count] = '\0';
1656
+
1657
+ return s;
1658
+ }