ndtypes 0.2.0dev4

Sign up to get free protection for your applications and to get access to all the features.
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
+ }