ndtypes 0.2.0dev5 → 0.2.0dev6

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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +12 -0
  3. data/Rakefile +8 -0
  4. data/ext/ruby_ndtypes/GPATH +0 -0
  5. data/ext/ruby_ndtypes/GRTAGS +0 -0
  6. data/ext/ruby_ndtypes/GTAGS +0 -0
  7. data/ext/ruby_ndtypes/extconf.rb +1 -1
  8. data/ext/ruby_ndtypes/include/ndtypes.h +231 -122
  9. data/ext/ruby_ndtypes/include/ruby_ndtypes.h +1 -1
  10. data/ext/ruby_ndtypes/lib/libndtypes.a +0 -0
  11. data/ext/ruby_ndtypes/lib/libndtypes.so.0.2.0dev3 +0 -0
  12. data/ext/ruby_ndtypes/ndtypes/Makefile +87 -0
  13. data/ext/ruby_ndtypes/ndtypes/config.h +68 -0
  14. data/ext/ruby_ndtypes/ndtypes/config.log +477 -0
  15. data/ext/ruby_ndtypes/ndtypes/config.status +1027 -0
  16. data/ext/ruby_ndtypes/ndtypes/doc/_static/style.css +7 -0
  17. data/ext/ruby_ndtypes/ndtypes/doc/_templates/layout.html +2 -0
  18. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +40 -4
  19. data/ext/ruby_ndtypes/ndtypes/doc/images/xndlogo.png +0 -0
  20. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +1 -1
  21. data/ext/ruby_ndtypes/ndtypes/doc/requirements.txt +2 -0
  22. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile +287 -0
  23. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +20 -4
  24. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +22 -3
  25. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +1 -1
  26. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.o +0 -0
  27. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.o +0 -0
  28. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile +73 -0
  29. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +246 -229
  30. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +15 -11
  31. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.o +0 -0
  32. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +38 -28
  33. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +91 -91
  34. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +1 -1
  35. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +4 -3
  36. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.o +0 -0
  37. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +8 -7
  38. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.o +0 -0
  39. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +2 -2
  40. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.o +0 -0
  41. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.o +0 -0
  42. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +263 -182
  43. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.o +0 -0
  44. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.o +0 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +67 -7
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.o +0 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +1112 -1000
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +69 -58
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.o +0 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +150 -99
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +185 -15
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.o +0 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +301 -276
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +1 -1
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +9 -4
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.o +0 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.a +0 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so +1 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0 +1 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0.2.0dev3 +0 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +729 -228
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.o +0 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +768 -403
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h +1002 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +231 -122
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.o +0 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +176 -84
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +26 -14
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.o +0 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +57 -35
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.o +0 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.c +420 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.o +0 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +8 -8
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +1 -1
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.o +0 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile +48 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +200 -116
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.o +0 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +46 -4
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.o +0 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +58 -27
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +1 -1
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.o +0 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +3 -5
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +12 -4
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.o +0 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile +55 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +8 -8
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +5 -5
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +274 -172
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +24 -4
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +2 -2
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +14 -14
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +32 -30
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +37 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +36 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +16 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +5 -5
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +706 -253
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_unify.c +132 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.c +703 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.o +0 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +335 -127
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.o +0 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +2 -2
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.o +0 -0
  108. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +88 -71
  109. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +0 -1
  110. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +10 -13
  111. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +395 -314
  112. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.a +0 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so +1 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0 +1 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0.2.0dev3 +0 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/ndtypes.h +1002 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +15 -33
  118. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +340 -132
  119. data/ext/ruby_ndtypes/ndtypes/setup.py +11 -2
  120. data/ext/ruby_ndtypes/ruby_ndtypes.c +364 -241
  121. data/ext/ruby_ndtypes/ruby_ndtypes.h +1 -1
  122. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +0 -1
  123. data/lib/ndtypes.rb +11 -0
  124. data/lib/ndtypes/version.rb +2 -2
  125. data/lib/ruby_ndtypes.so +0 -0
  126. data/ndtypes.gemspec +3 -0
  127. data/spec/ndtypes_spec.rb +6 -0
  128. metadata +98 -4
  129. data/ext/ruby_ndtypes/gc_guard.c +0 -36
  130. data/ext/ruby_ndtypes/gc_guard.h +0 -12
@@ -727,7 +727,7 @@ extern int yylex \
727
727
  #undef yyTABLES_NAME
728
728
  #endif
729
729
 
730
- #line 176 "bplexer.l"
730
+ #line 177 "bplexer.l"
731
731
 
732
732
 
733
733
  #line 733 "bplexer.h"
@@ -136,9 +136,10 @@ yycolumn = 1;
136
136
  "e" { yylval->uchar = 'e'; return DTYPE; }
137
137
  "f" { yylval->uchar = 'f'; return DTYPE; }
138
138
  "d" { yylval->uchar = 'd'; return DTYPE; }
139
- "E" { yylval->uchar = 'E'; return DTYPE; }
140
- "F" { yylval->uchar = 'F'; return DTYPE; }
141
- "D" { yylval->uchar = 'D'; return DTYPE; }
139
+
140
+ "Ze" { yylval->uchar = 'E'; return DTYPE; }
141
+ "Zf" { yylval->uchar = 'F'; return DTYPE; }
142
+ "Zd" { yylval->uchar = 'D'; return DTYPE; }
142
143
 
143
144
  "x" { return PAD; }
144
145
  "T" { return RECORD; }
@@ -260,23 +260,24 @@ format(buf_t *buf, const ndt_t *t, ndt_context_t *ctx)
260
260
  case Float32: return primitive(buf, t, "f", ctx);
261
261
  case Float64: return primitive(buf, t, "d", ctx);
262
262
 
263
- case Complex32: return primitive(buf, t, "E", ctx);
264
- case Complex64: return primitive(buf, t, "F", ctx);
265
- case Complex128: return primitive(buf, t, "D", ctx);
263
+ case Complex32: return primitive(buf, t, "Ze", ctx);
264
+ case Complex64: return primitive(buf, t, "Zf", ctx);
265
+ case Complex128: return primitive(buf, t, "Zd", ctx);
266
266
 
267
267
  case Char:
268
268
  if (t->Char.encoding == Ascii) return ndt_snprintf(ctx, buf, "c");
269
269
  /* fall through */
270
270
 
271
271
  case Module: case Function:
272
- case VarDim: case SymbolicDim: case EllipsisDim:
273
- case Ref: case Constr: case Nominal:
272
+ case VarDim: case VarDimElem: case SymbolicDim: case EllipsisDim:
273
+ case Union: case Ref: case Constr: case Nominal:
274
274
  case Categorical:
275
- case FixedString: case String: case Bytes:
275
+ case FixedString: case String: case Bytes: case Array:
276
276
  case Typevar:
277
277
  case AnyKind: case ScalarKind:
278
278
  case SignedKind: case UnsignedKind:
279
- case FloatKind: case ComplexKind:
279
+ case FloatKind: case BFloat16:
280
+ case ComplexKind: case BComplex32:
280
281
  case FixedStringKind: case FixedBytesKind:
281
282
  ndt_err_format(ctx, NDT_ValueError,
282
283
  "type is not supported by the buffer protocol");
@@ -49,14 +49,14 @@ int ndt_bpdebug = 1;
49
49
  jmp_buf ndt_bp_lexerror;
50
50
 
51
51
 
52
- ndt_t *
52
+ const ndt_t *
53
53
  ndt_from_bpformat(const char *input, ndt_context_t *ctx)
54
54
  {
55
55
  volatile yyscan_t scanner = NULL;
56
56
  volatile YY_BUFFER_STATE state = NULL;
57
57
  char *buffer;
58
58
  size_t size;
59
- ndt_t *ast = NULL;
59
+ const ndt_t *ast = NULL;
60
60
  int ret;
61
61
 
62
62
  size = strlen(input);
@@ -33,8 +33,11 @@
33
33
 
34
34
  #include <stdio.h>
35
35
  #include <string.h>
36
+ #include <inttypes.h>
37
+ #include <stdint.h>
36
38
  #include <assert.h>
37
39
  #include "ndtypes.h"
40
+ #include "overflow.h"
38
41
 
39
42
 
40
43
  static inline void
@@ -48,22 +51,59 @@ copy_common(ndt_t *u, const ndt_t *t)
48
51
  u->align = t->align;
49
52
  }
50
53
 
51
- static ndt_t *
52
- ndt_copy_var_dim(const ndt_t *t, ndt_context_t *ctx)
54
+ static const ndt_t *
55
+ ndt_copy_var_dim(const ndt_t *t, bool opt, ndt_context_t *ctx)
53
56
  {
54
- ndt_t *type;
55
57
  ndt_slice_t *slices;
56
58
  int nslices;
57
59
 
58
60
  assert(t->tag == VarDim);
59
61
 
60
- type = ndt_copy(t->VarDim.type, ctx);
61
- if (type == NULL) {
62
+ if (ndt_is_abstract(t)) {
63
+ return ndt_abstract_var_dim(t->VarDim.type, opt, ctx);
64
+ }
65
+
66
+ slices = NULL;
67
+ nslices = t->Concrete.VarDim.nslices;
68
+
69
+ if (nslices > 0) {
70
+ slices = ndt_alloc(nslices, sizeof *slices);
71
+ if (slices == NULL) {
72
+ return ndt_memory_error(ctx);
73
+ }
74
+ memcpy(slices, t->Concrete.VarDim.slices,
75
+ nslices * (sizeof *slices));
76
+ }
77
+
78
+ return ndt_var_dim(t->VarDim.type, t->Concrete.VarDim.offsets,
79
+ nslices, slices,
80
+ opt, ctx);
81
+ }
82
+
83
+ const ndt_t *
84
+ ndt_convert_to_var_elem(const ndt_t *t, const ndt_t *type, int64_t index,
85
+ ndt_context_t *ctx)
86
+ {
87
+ ndt_t *u;
88
+ ndt_slice_t *slices;
89
+ int nslices;
90
+
91
+ if (t->tag != VarDim && t->tag != VarDimElem) {
92
+ ndt_err_format(ctx, NDT_ValueError,
93
+ "ndt_convert_to_var_elem: need var dim as input");
62
94
  return NULL;
63
95
  }
64
96
 
65
97
  if (ndt_is_abstract(t)) {
66
- return ndt_abstract_var_dim(type, ctx);
98
+ ndt_err_format(ctx, NDT_ValueError,
99
+ "cannot convert abstract var dim into var elem");
100
+ return NULL;
101
+ }
102
+
103
+ if (ndt_is_optional(t)) {
104
+ ndt_err_format(ctx, NDT_ValueError,
105
+ "cannot convert optional var dim into var elem");
106
+ return NULL;
67
107
  }
68
108
 
69
109
  slices = NULL;
@@ -78,14 +118,19 @@ ndt_copy_var_dim(const ndt_t *t, ndt_context_t *ctx)
78
118
  nslices * (sizeof *slices));
79
119
  }
80
120
 
81
- return ndt_var_dim(type, ExternalOffsets,
82
- t->Concrete.VarDim.noffsets,
83
- t->Concrete.VarDim.offsets,
84
- nslices,
85
- slices, ctx);
121
+ u = (ndt_t *)ndt_var_dim(type, t->Concrete.VarDim.offsets,
122
+ nslices, slices,
123
+ false, ctx);
124
+ if (u == NULL) {
125
+ return NULL;
126
+ }
127
+
128
+ u->tag = VarDimElem;
129
+ u->VarDimElem.index = index;
130
+ return u;
86
131
  }
87
132
 
88
- static ndt_t *
133
+ static const ndt_t *
89
134
  ndt_copy_function(const ndt_t *t, ndt_context_t *ctx)
90
135
  {
91
136
  ndt_t *u;
@@ -103,25 +148,22 @@ ndt_copy_function(const ndt_t *t, ndt_context_t *ctx)
103
148
  copy_common(u, t);
104
149
 
105
150
  for (i = 0; i < t->Function.nargs; i++) {
106
- u->Function.types[i] = ndt_copy(t->Function.types[i], ctx);
107
- if (u->Function.types[i] == NULL) {
108
- ndt_del(u);
109
- return NULL;
110
- }
151
+ ndt_incref(t->Function.types[i]);
152
+ u->Function.types[i] = t->Function.types[i];
111
153
  }
112
154
 
113
155
  return u;
114
156
  }
115
157
 
116
- static ndt_t *
117
- ndt_copy_tuple(const ndt_t *t, ndt_context_t *ctx)
158
+ static const ndt_t *
159
+ ndt_copy_tuple(const ndt_t *t, bool opt, ndt_context_t *ctx)
118
160
  {
119
161
  ndt_t *u;
120
162
  int64_t i;
121
163
 
122
164
  assert(t->tag == Tuple);
123
165
 
124
- u = ndt_tuple_new(t->Tuple.flag, t->Tuple.shape, ctx);
166
+ u = ndt_tuple_new(t->Tuple.flag, t->Tuple.shape, opt, ctx);
125
167
  if (u == NULL) {
126
168
  return NULL;
127
169
  }
@@ -129,11 +171,8 @@ ndt_copy_tuple(const ndt_t *t, ndt_context_t *ctx)
129
171
  copy_common(u, t);
130
172
 
131
173
  for (i = 0; i < t->Tuple.shape; i++) {
132
- u->Tuple.types[i] = ndt_copy(t->Tuple.types[i], ctx);
133
- if (u->Tuple.types[i] == NULL) {
134
- ndt_del(u);
135
- return NULL;
136
- }
174
+ ndt_incref(t->Tuple.types[i]);
175
+ u->Tuple.types[i] = t->Tuple.types[i];
137
176
 
138
177
  u->Concrete.Tuple.offset[i] = t->Concrete.Tuple.offset[i];
139
178
  u->Concrete.Tuple.align[i] = t->Concrete.Tuple.align[i];
@@ -143,15 +182,15 @@ ndt_copy_tuple(const ndt_t *t, ndt_context_t *ctx)
143
182
  return u;
144
183
  }
145
184
 
146
- static ndt_t *
147
- ndt_copy_record(const ndt_t *t, ndt_context_t *ctx)
185
+ static const ndt_t *
186
+ ndt_copy_record(const ndt_t *t, bool opt, ndt_context_t *ctx)
148
187
  {
149
188
  ndt_t *u;
150
189
  int64_t i;
151
190
 
152
191
  assert(t->tag == Record);
153
192
 
154
- u = ndt_record_new(t->Record.flag, t->Record.shape, ctx);
193
+ u = ndt_record_new(t->Record.flag, t->Record.shape, opt, ctx);
155
194
  if (u == NULL) {
156
195
  return NULL;
157
196
  }
@@ -161,15 +200,12 @@ ndt_copy_record(const ndt_t *t, ndt_context_t *ctx)
161
200
  for (i = 0; i < t->Record.shape; i++) {
162
201
  u->Record.names[i] = ndt_strdup(t->Record.names[i], ctx);
163
202
  if (u->Record.names[i] == NULL) {
164
- ndt_del(u);
203
+ ndt_decref(u);
165
204
  return NULL;
166
205
  }
167
206
 
168
- u->Record.types[i] = ndt_copy(t->Record.types[i], ctx);
169
- if (u->Record.types[i] == NULL) {
170
- ndt_del(u);
171
- return NULL;
172
- }
207
+ ndt_incref(t->Record.types[i]);
208
+ u->Record.types[i] = t->Record.types[i];
173
209
 
174
210
  u->Concrete.Record.offset[i] = t->Concrete.Record.offset[i];
175
211
  u->Concrete.Record.align[i] = t->Concrete.Record.align[i];
@@ -179,6 +215,35 @@ ndt_copy_record(const ndt_t *t, ndt_context_t *ctx)
179
215
  return u;
180
216
  }
181
217
 
218
+ static const ndt_t *
219
+ ndt_copy_union(const ndt_t *t, bool opt, ndt_context_t *ctx)
220
+ {
221
+ ndt_t *u;
222
+ int64_t i;
223
+
224
+ assert(t->tag == Union);
225
+
226
+ u = ndt_new(t->Union.ntags, opt, ctx);
227
+ if (u == NULL) {
228
+ return NULL;
229
+ }
230
+
231
+ copy_common(u, t);
232
+
233
+ for (i = 0; i < t->Union.ntags; i++) {
234
+ u->Union.tags[i] = ndt_strdup(t->Union.tags[i], ctx);
235
+ if (u->Union.tags[i] == NULL) {
236
+ ndt_decref(u);
237
+ return NULL;
238
+ }
239
+
240
+ ndt_incref(t->Union.types[i]);
241
+ u->Union.types[i] = t->Union.types[i];
242
+ }
243
+
244
+ return u;
245
+ }
246
+
182
247
  static int
183
248
  ndt_copy_value(ndt_value_t *v, const ndt_value_t *u, ndt_context_t *ctx)
184
249
  {
@@ -200,8 +265,8 @@ ndt_copy_value(ndt_value_t *v, const ndt_value_t *u, ndt_context_t *ctx)
200
265
  return -1;
201
266
  }
202
267
 
203
- static ndt_t *
204
- ndt_copy_categorical(const ndt_t *t, ndt_context_t *ctx)
268
+ static const ndt_t *
269
+ ndt_copy_categorical(const ndt_t *t, bool opt, ndt_context_t *ctx)
205
270
  {
206
271
  int64_t ntypes = t->Categorical.ntypes;
207
272
  ndt_value_t *types;
@@ -225,85 +290,79 @@ ndt_copy_categorical(const ndt_t *t, ndt_context_t *ctx)
225
290
  }
226
291
  }
227
292
 
228
- return ndt_categorical(types, ntypes, ctx);
293
+ return ndt_categorical(types, ntypes, opt, ctx);
229
294
  }
230
295
 
231
- ndt_t *
296
+ /* shallow copy */
297
+ const ndt_t *
232
298
  ndt_copy(const ndt_t *t, ndt_context_t *ctx)
233
299
  {
300
+ bool opt = ndt_is_optional(t);
234
301
  ndt_t *u = NULL;
235
- ndt_t *type;
236
302
 
237
303
  switch (t->tag) {
238
304
  case FixedDim: {
239
- type = ndt_copy(t->FixedDim.type, ctx);
240
- if (type == NULL) {
241
- return NULL;
242
- }
243
-
244
- u = ndt_fixed_dim_tag(type, t->FixedDim.tag, t->FixedDim.shape,
245
- t->Concrete.FixedDim.step, ctx);
305
+ u = (ndt_t *)ndt_fixed_dim_tag(t->FixedDim.type, t->FixedDim.tag, t->FixedDim.shape,
306
+ t->Concrete.FixedDim.step, ctx);
246
307
  goto copy_common_fields;
247
308
  }
248
309
 
249
310
  case VarDim: {
250
- u = ndt_copy_var_dim(t, ctx);
311
+ u = (ndt_t *)ndt_copy_var_dim(t, opt, ctx);
312
+ goto copy_common_fields;
313
+ }
314
+
315
+ case VarDimElem: {
316
+ u = (ndt_t *)ndt_copy_var_dim(t, opt, ctx);
317
+ u->VarDimElem.index = t->VarDimElem.index;
251
318
  goto copy_common_fields;
252
319
  }
253
320
 
254
321
  case SymbolicDim: {
255
322
  char *name;
256
323
 
257
- type = ndt_copy(t->SymbolicDim.type, ctx);
258
- if (type == NULL) {
259
- return NULL;
260
- }
261
-
262
324
  name = ndt_strdup(t->SymbolicDim.name, ctx);
263
325
  if (name == NULL) {
264
- ndt_del(type);
265
326
  return NULL;
266
327
  }
267
328
 
268
- u = ndt_symbolic_dim_tag(name, type, t->SymbolicDim.tag, ctx);
329
+ u = (ndt_t *)ndt_symbolic_dim_tag(name, t->SymbolicDim.type, t->SymbolicDim.tag, ctx);
269
330
  goto copy_common_fields;
270
331
  }
271
332
 
272
333
  case EllipsisDim: {
273
334
  char *name = NULL;
274
335
 
275
- type = ndt_copy(t->EllipsisDim.type, ctx);
276
- if (type == NULL) {
277
- return NULL;
278
- }
279
-
280
336
  if (t->EllipsisDim.name != NULL) {
281
337
  name = ndt_strdup(t->SymbolicDim.name, ctx);
282
338
  if (name == NULL) {
283
- ndt_del(type);
284
339
  return NULL;
285
340
  }
286
341
  }
287
342
 
288
- u = ndt_ellipsis_dim_tag(name, type, t->EllipsisDim.tag, ctx);
343
+ u = (ndt_t *)ndt_ellipsis_dim_tag(name, t->EllipsisDim.type, t->EllipsisDim.tag, ctx);
344
+ goto copy_common_fields;
345
+ }
346
+
347
+ case Array: {
348
+ u = (ndt_t *)ndt_array(t->Array.type, opt, ctx);
289
349
  goto copy_common_fields;
290
350
  }
291
351
 
292
352
  case Tuple: {
293
- return ndt_copy_tuple(t, ctx);
353
+ return ndt_copy_tuple(t, opt, ctx);
294
354
  }
295
355
 
296
356
  case Record: {
297
- return ndt_copy_record(t, ctx);
357
+ return ndt_copy_record(t, opt, ctx);
298
358
  }
299
359
 
300
- case Ref: {
301
- type = ndt_copy(t->Ref.type, ctx);
302
- if (type == NULL) {
303
- return NULL;
304
- }
360
+ case Union: {
361
+ return ndt_copy_union(t, opt, ctx);
362
+ }
305
363
 
306
- u = ndt_ref(type, ctx);
364
+ case Ref: {
365
+ u = (ndt_t *)ndt_ref(t->Ref.type, opt, ctx);
307
366
  goto copy_common_fields;
308
367
  }
309
368
 
@@ -313,13 +372,7 @@ ndt_copy(const ndt_t *t, ndt_context_t *ctx)
313
372
  return NULL;
314
373
  }
315
374
 
316
- type = ndt_copy(t->Constr.type, ctx);
317
- if (type == NULL) {
318
- ndt_free(name);
319
- return NULL;
320
- }
321
-
322
- u = ndt_constr(name, type, ctx);
375
+ u = (ndt_t *)ndt_constr(name, t->Constr.type, opt, ctx);
323
376
  goto copy_common_fields;
324
377
  }
325
378
 
@@ -329,18 +382,12 @@ ndt_copy(const ndt_t *t, ndt_context_t *ctx)
329
382
  return NULL;
330
383
  }
331
384
 
332
- type = ndt_copy(t->Nominal.type, ctx);
333
- if (type == NULL) {
334
- ndt_free(name);
335
- return NULL;
336
- }
337
-
338
- u = ndt_nominal(name, type, ctx);
385
+ u = (ndt_t *)ndt_nominal(name, t->Nominal.type, opt, ctx);
339
386
  goto copy_common_fields;
340
387
  }
341
388
 
342
389
  case Categorical: {
343
- u = ndt_copy_categorical(t, ctx);
390
+ u = (ndt_t *)ndt_copy_categorical(t, opt, ctx);
344
391
  goto copy_common_fields;
345
392
  }
346
393
 
@@ -352,7 +399,7 @@ ndt_copy(const ndt_t *t, ndt_context_t *ctx)
352
399
  return NULL;
353
400
  }
354
401
 
355
- u = ndt_typevar(name, ctx);
402
+ u = (ndt_t *)ndt_typevar(name, ctx);
356
403
  goto copy_common_fields;
357
404
  }
358
405
 
@@ -363,18 +410,12 @@ ndt_copy(const ndt_t *t, ndt_context_t *ctx)
363
410
  case Module: {
364
411
  char *name;
365
412
 
366
- type = ndt_copy(t->Module.type, ctx);
367
- if (type == NULL) {
368
- return NULL;
369
- }
370
-
371
413
  name = ndt_strdup(t->Module.name, ctx);
372
414
  if (name == NULL) {
373
- ndt_del(type);
374
415
  return NULL;
375
416
  }
376
417
 
377
- u = ndt_module(name, type, ctx);
418
+ u = (ndt_t *)ndt_module(name, t->Module.type, ctx);
378
419
  goto copy_common_fields;
379
420
  }
380
421
 
@@ -383,21 +424,25 @@ ndt_copy(const ndt_t *t, ndt_context_t *ctx)
383
424
  case SignedKind: case UnsignedKind:
384
425
  case FloatKind: case ComplexKind:
385
426
  case FixedStringKind: case FixedBytesKind:
386
- case Bool:
387
- case Int8: case Int16: case Int32: case Int64:
388
- case Uint8: case Uint16: case Uint32: case Uint64:
389
- case Float16: case Float32: case Float64:
390
- case Complex32: case Complex64: case Complex128:
391
427
  case FixedString: case FixedBytes:
392
- case String: case Bytes:
428
+ case Bytes:
393
429
  case Char: {
394
- u = ndt_new(t->tag, ctx);
430
+ u = ndt_new(t->tag, opt, ctx);
395
431
  if (u == NULL) {
396
432
  return NULL;
397
433
  }
398
434
  *u = *t;
435
+ u->refcnt = 1;
399
436
  return u;
400
- }
437
+ }
438
+
439
+ case String:
440
+ case Bool:
441
+ case Int8: case Int16: case Int32: case Int64:
442
+ case Uint8: case Uint16: case Uint32: case Uint64:
443
+ case BFloat16: case Float16: case Float32: case Float64:
444
+ case BComplex32: case Complex32: case Complex64: case Complex128:
445
+ return t;
401
446
  }
402
447
 
403
448
  goto invalid_tag;
@@ -417,29 +462,34 @@ invalid_tag:
417
462
  return NULL;
418
463
  }
419
464
 
420
- static ndt_t *
421
- fixed_copy_contiguous(const ndt_t *t, ndt_t *type, ndt_context_t *ctx)
465
+ static const ndt_t *
466
+ fixed_copy_contiguous(const ndt_t *t, const ndt_t *type, ndt_context_t *ctx)
422
467
  {
468
+ const ndt_t *u, *v;
469
+
423
470
  if (t->ndim == 0) {
471
+ ndt_incref(type);
424
472
  return type;
425
473
  }
426
474
 
427
475
  assert(t->tag == FixedDim);
428
476
  assert(ndt_is_concrete(t));
429
- type = fixed_copy_contiguous(t->FixedDim.type, type, ctx);
430
- if (type == NULL) {
431
- ndt_del(type);
477
+
478
+ u = fixed_copy_contiguous(t->FixedDim.type, type, ctx);
479
+ if (u == NULL) {
432
480
  return NULL;
433
481
  }
434
482
 
435
- return ndt_fixed_dim_tag(type, t->FixedDim.tag, t->FixedDim.shape,
436
- INT64_MAX, ctx);
483
+ v = ndt_fixed_dim_tag(u, t->FixedDim.tag, t->FixedDim.shape,
484
+ INT64_MAX, ctx);
485
+ ndt_decref(u);
486
+ return v;
437
487
  }
438
488
 
439
489
  typedef struct {
440
490
  int maxdim;
491
+ bool active[NDT_MAX_DIM+1];
441
492
  int32_t index[NDT_MAX_DIM+1];
442
- int32_t noffsets[NDT_MAX_DIM+1];
443
493
  int32_t *offsets[NDT_MAX_DIM+1];
444
494
  } offsets_t;
445
495
 
@@ -452,60 +502,80 @@ clear_offsets(offsets_t *m)
452
502
  }
453
503
 
454
504
  static int
455
- var_init_offsets(offsets_t *m, const ndt_t *t, int32_t noffsets, ndt_context_t *ctx)
505
+ var_init_offsets(offsets_t *m, ndt_context_t *ctx)
456
506
  {
457
507
  int32_t *offsets;
458
- int64_t shape, start, step;
459
- int64_t sum;
460
- int32_t i;
461
-
462
- assert(t->ndim >= 1);
463
508
 
464
- offsets = ndt_alloc(noffsets, sizeof *offsets);
465
- if (offsets == NULL) {
466
- clear_offsets(m);
467
- (void)ndt_memory_error(ctx);
468
- return -1;
509
+ for (int i = 1; i <= m->maxdim; i++) {
510
+ offsets = ndt_calloc(m->index[i]+1, sizeof *offsets);
511
+ if (offsets == NULL) {
512
+ clear_offsets(m);
513
+ (void)ndt_memory_error(ctx);
514
+ return -1;
515
+ }
516
+ m->offsets[i] = offsets;
469
517
  }
470
- m->noffsets[t->ndim] = noffsets;
471
- m->offsets[t->ndim] = offsets;
472
518
 
473
- if (t->ndim == 1) {
474
- return 0;
519
+ return 0;
520
+ }
521
+
522
+ static int64_t
523
+ get_index(int64_t shape, int64_t index, ndt_context_t *ctx)
524
+ {
525
+ bool overflow = false;
526
+
527
+ if (index < 0) {
528
+ index = ADDi64(index, shape, &overflow);
475
529
  }
476
530
 
477
- for (i=0, sum=0; i < noffsets-1; i++) {
478
- shape = ndt_var_indices(&start, &step, t, i, ctx);
479
- if (shape == -1) {
480
- clear_offsets(m);
481
- return -1;
482
- }
483
- sum += shape;
531
+ if (overflow || index < 0 || index >= shape) {
532
+ ndt_err_format(ctx, NDT_IndexError,
533
+ "index with value %" PRIi64 " out of bounds",
534
+ index);
535
+ return -1;
484
536
  }
485
537
 
486
- return var_init_offsets(m, t->VarDim.type, (int32_t)sum+1, ctx);
538
+ return index;
487
539
  }
488
540
 
489
541
  static int
490
- var_copy_shapes(offsets_t *m, int64_t src_index, const ndt_t *t, ndt_context_t *ctx)
542
+ var_copy_shapes(bool write, offsets_t *m, int64_t linear_index, const ndt_t *t,
543
+ ndt_context_t *ctx)
491
544
  {
492
545
  int64_t shape, start, step;
546
+ int64_t k;
493
547
 
494
548
  if (t->ndim == 0) {
495
549
  return 0;
496
550
  }
497
551
 
498
- shape = ndt_var_indices(&start, &step, t, src_index, ctx);
552
+ shape = ndt_var_indices(&start, &step, t, linear_index, ctx);
499
553
  if (shape < 0) {
500
554
  clear_offsets(m);
501
555
  return -1;
502
556
  }
503
- int32_t dst_index = m->index[t->ndim]++;
504
- m->offsets[t->ndim][dst_index] = (int32_t)shape;
505
557
 
506
- for (int64_t i = 0; i < shape; i++) {
507
- int64_t src_next = start + i * step;
508
- if (var_copy_shapes(m, src_next, t->VarDim.type, ctx) < 0) {
558
+ k = 0;
559
+ m->active[t->ndim] = true;
560
+
561
+ if (t->tag == VarDimElem) {
562
+ k = get_index(shape, t->VarDimElem.index, ctx);
563
+ if (k < 0) {
564
+ return -1;
565
+ }
566
+ shape = 1;
567
+ m->active[t->ndim] = false;
568
+ }
569
+
570
+ int32_t write_index = m->index[t->ndim]++;
571
+ if (write) {
572
+ int32_t sum = m->offsets[t->ndim][write_index];
573
+ m->offsets[t->ndim][write_index+1] = sum + (int32_t)shape;
574
+ }
575
+
576
+ for (int64_t i = k; i < k+shape; i++) {
577
+ int64_t next = start + i * step;
578
+ if (var_copy_shapes(write, m, next, t->VarDim.type, ctx) < 0) {
509
579
  clear_offsets(m);
510
580
  return -1;
511
581
  }
@@ -514,31 +584,34 @@ var_copy_shapes(offsets_t *m, int64_t src_index, const ndt_t *t, ndt_context_t *
514
584
  return 0;
515
585
  }
516
586
 
517
- static void
518
- var_sum_shapes(offsets_t *m)
587
+ const ndt_t *
588
+ var_from_offsets_and_dtype(offsets_t *m, const ndt_t *t, ndt_context_t *ctx)
519
589
  {
520
- int i, k;
590
+ const ndt_t *u;
591
+ int i;
592
+
593
+ ndt_incref(t);
521
594
 
522
595
  for (i = 1; i <= m->maxdim; i++) {
523
- int32_t sum = 0;
524
- for (k = 0; k < m->noffsets[i]; k++) {
525
- int32_t s = m->offsets[i][k];
526
- m->offsets[i][k] = sum;
527
- sum += s;
596
+ if (!m->active[i]) {
597
+ ndt_free(m->offsets[i]);
598
+ m->offsets[i] = NULL;
599
+ continue;
528
600
  }
529
- }
530
- }
531
601
 
532
- ndt_t *
533
- var_from_offsets_and_dtype(offsets_t *m, ndt_t *type, ndt_context_t *ctx)
534
- {
535
- ndt_t *t;
536
- int i;
602
+ ndt_offsets_t *offsets = ndt_offsets_from_ptr(m->offsets[i], m->index[i]+1, ctx);
537
603
 
538
- for (i=1, t=type; i <= m->maxdim; i++, type=t) {
539
- t = ndt_var_dim(type, InternalOffsets, m->noffsets[i], m->offsets[i],
540
- 0, NULL, ctx);
541
604
  m->offsets[i] = NULL;
605
+ if (offsets == NULL) {
606
+ ndt_decref(t);
607
+ clear_offsets(m);
608
+ return NULL;
609
+ }
610
+
611
+ u = ndt_var_dim(t, offsets, 0, NULL, false, ctx);
612
+ ndt_move(&t, u);
613
+ ndt_decref_offsets(offsets);
614
+
542
615
  if (t == NULL) {
543
616
  clear_offsets(m);
544
617
  return NULL;
@@ -548,33 +621,38 @@ var_from_offsets_and_dtype(offsets_t *m, ndt_t *type, ndt_context_t *ctx)
548
621
  return t;
549
622
  }
550
623
 
551
- static ndt_t *
552
- var_copy_contiguous(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
624
+ static const ndt_t *
625
+ var_copy_contiguous(const ndt_t *t, const ndt_t *dtype, int64_t linear_index,
626
+ ndt_context_t *ctx)
553
627
  {
554
- offsets_t m = {.maxdim=0, .index={0}, .noffsets={0}, .offsets={NULL}};
628
+ offsets_t m = {.maxdim=0, .index={0}, .offsets={NULL}};
555
629
 
556
- assert(t->tag == VarDim);
557
630
  assert(ndt_is_concrete(t));
558
- assert(t->Concrete.VarDim.noffsets == 2);
559
631
 
560
- if (var_init_offsets(&m, t, 2, ctx) < 0) {
561
- ndt_del(dtype);
632
+ m.maxdim = t->ndim;
633
+
634
+ if (var_copy_shapes(false, &m, linear_index, t, ctx) < 0) {
562
635
  return NULL;
563
636
  }
564
- m.maxdim = t->ndim;
565
637
 
566
- if (var_copy_shapes(&m, 0, t, ctx) < 0) {
567
- ndt_del(dtype);
638
+ if (var_init_offsets(&m, ctx) < 0) {
568
639
  return NULL;
569
640
  }
570
641
 
571
- var_sum_shapes(&m);
642
+ for (int i = 0; i <= m.maxdim; i++) {
643
+ m.index[i] = 0;
644
+ }
645
+
646
+ if (var_copy_shapes(true, &m, linear_index, t, ctx) < 0) {
647
+ return NULL;
648
+ }
572
649
 
573
650
  return var_from_offsets_and_dtype(&m, dtype, ctx);
574
651
  }
575
652
 
576
- ndt_t *
577
- ndt_copy_contiguous_dtype(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
653
+ const ndt_t *
654
+ ndt_copy_contiguous_dtype(const ndt_t *t, const ndt_t *dtype, int64_t linear_index,
655
+ ndt_context_t *ctx)
578
656
  {
579
657
  if (ndt_is_abstract(t) || ndt_is_abstract(dtype)) {
580
658
  ndt_err_format(ctx, NDT_ValueError,
@@ -586,29 +664,30 @@ ndt_copy_contiguous_dtype(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
586
664
  case FixedDim: {
587
665
  return fixed_copy_contiguous(t, dtype, ctx);
588
666
  }
589
- case VarDim: {
590
- return var_copy_contiguous(t, dtype, ctx);
667
+ case VarDim: case VarDimElem: {
668
+ return var_copy_contiguous(t, dtype, linear_index, ctx);
591
669
  }
592
670
  default:
671
+ ndt_incref(dtype);
593
672
  return dtype;
594
673
  }
595
674
  }
596
675
 
597
- ndt_t *
598
- ndt_copy_contiguous(const ndt_t *t, ndt_context_t *ctx)
676
+ const ndt_t *
677
+ ndt_copy_contiguous(const ndt_t *t, int64_t linear_index, ndt_context_t *ctx)
599
678
  {
600
- ndt_t *dtype = ndt_copy(ndt_dtype(t), ctx);
601
- if (dtype == NULL) {
602
- return NULL;
603
- }
679
+ const ndt_t *dtype = ndt_dtype(t);
604
680
 
605
- return ndt_copy_contiguous_dtype(t, dtype, ctx);
681
+ return ndt_copy_contiguous_dtype(t, dtype, linear_index, ctx);
606
682
  }
607
683
 
608
- ndt_t *
609
- ndt_copy_abstract_var_dtype(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
684
+ const ndt_t *
685
+ ndt_copy_abstract_var_dtype(const ndt_t *t, const ndt_t *dtype, ndt_context_t *ctx)
610
686
  {
687
+ bool opt = ndt_is_optional(t);
688
+
611
689
  if (t->ndim == 0) {
690
+ ndt_incref(dtype);
612
691
  return dtype;
613
692
  }
614
693
 
@@ -619,12 +698,14 @@ ndt_copy_abstract_var_dtype(const ndt_t *t, ndt_t *dtype, ndt_context_t *ctx)
619
698
  "ndt_copy_abstract_var_dtype() called on concrete type");
620
699
  return NULL;
621
700
  }
622
- ndt_t *u = ndt_copy_abstract_var_dtype(t->VarDim.type, dtype, ctx);
701
+ const ndt_t *u = ndt_copy_abstract_var_dtype(t->VarDim.type, dtype, ctx);
623
702
  if (u == NULL) {
624
703
  return NULL;
625
704
  }
626
705
 
627
- return ndt_abstract_var_dim(u, ctx);
706
+ const ndt_t *w = ndt_abstract_var_dim(u, opt, ctx);
707
+ ndt_decref(u);
708
+ return w;
628
709
  }
629
710
  default:
630
711
  ndt_err_format(ctx, NDT_ValueError,