ndtypes 0.2.0dev5 → 0.2.0dev6

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