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
@@ -0,0 +1,132 @@
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 "test.h"
36
+
37
+
38
+ const unify_testcase_t unify_tests[] = {
39
+
40
+ { "bool", "bool", "bool" },
41
+ { "bool", "?bool", "?bool" },
42
+ { "?bool", "bool", "?bool" },
43
+
44
+ { "bool", "int8", NULL },
45
+ { "bool", "?int8", NULL },
46
+ { "?bool", "int8", NULL },
47
+ { "?bool", "?int8", NULL },
48
+
49
+ { "int8", "int8", "int8" },
50
+ { "int8", "int16", "int16" },
51
+ { "int8", "int32", "int32" },
52
+ { "int8", "int64", "int64" },
53
+
54
+ { "int8", "?int8", "?int8" },
55
+ { "?int8", "int8", "?int8" },
56
+ { "?int8", "int16", "?int16" },
57
+ { "int8", "?int16", "?int16" },
58
+
59
+ { "bfloat16", "?bfloat16", "?bfloat16" },
60
+ { "float16", "?float16", "?float16" },
61
+
62
+ { "complex32", "?complex64", "?complex64" },
63
+ { "?complex64", "complex128", "?complex128" },
64
+
65
+ { "complex32", "?string", NULL },
66
+
67
+ { "2 * 3 * int64",
68
+ "2 * 4 * int64",
69
+ NULL },
70
+
71
+ { "2 * 3 * int64",
72
+ "2 * 3 * int64",
73
+ "2 * 3 * int64" },
74
+
75
+ { "2 * 3 * int64",
76
+ "2 * 3 * ?int64",
77
+ "2 * 3 * ?int64" },
78
+
79
+ { "2 * 3 * ?int64",
80
+ "2 * 3 * int64",
81
+ "2 * 3 * ?int64" },
82
+
83
+ { "2 * 3 * int32",
84
+ "2 * 3 * int64",
85
+ "2 * 3 * int64" },
86
+
87
+ { "2 * 3 * int8",
88
+ "2 * 3 * int64",
89
+ "2 * 3 * int64" },
90
+
91
+ { "2 * 3 * (int8, float32)",
92
+ "2 * 3 * (int32, float64)",
93
+ "2 * 3 * (int32, float64)" },
94
+
95
+ { "2 * 3 * (int8, {foo: complex64, bar: string})",
96
+ "2 * 3 * (int8, {foo: complex64, x: string})",
97
+ NULL },
98
+
99
+ { "2 * 3 * (int8, {foo: complex64, bar: string})",
100
+ "2 * 3 * (int8, {foo: complex128, bar: string})",
101
+ "2 * 3 * (int8, {foo: complex128, bar: string})" },
102
+
103
+ { "2 * 3 * (int8, {foo: ?Any, bar: string})",
104
+ "2 * 3 * (int8, {foo: complex128, bar: ?Any})",
105
+ "2 * 3 * (int8, {foo: ?complex128, bar: ?string})" },
106
+
107
+ { "2 * 3 * Int of int8 | Something of {foo: Any, bar: string}",
108
+ "2 * 3 * Int of int8 | Something of {foo: complex128, bar: Any}",
109
+ "2 * 3 * Int of int8 | Something of {foo: complex128, bar: string}" },
110
+
111
+ { "2 * 3 * Int of int8 | Something of {foo: ?Any, bar: string}",
112
+ "2 * 3 * Int of int8 | Something of {foo: complex128, bar: ?Any}",
113
+ "2 * 3 * Int of int8 | Something of {foo: ?complex128, bar: ?string}" },
114
+
115
+ { "var(offsets=[0,2]) * (int8, {foo: complex64, bar: string})",
116
+ "var(offsets=[0,3]) * (int8, {foo: complex128, bar: string})",
117
+ NULL },
118
+
119
+ { "var(offsets=[0,2]) * (int8, {foo: complex64, bar: string})",
120
+ "var(offsets=[0,2]) * (int8, {foo: complex128, bar: int32})",
121
+ NULL },
122
+
123
+ { "var(offsets=[0,2]) * (int8, {foo: complex64, bar: string})",
124
+ "var(offsets=[0,2]) * (int8, {foo: complex128, bar: string})",
125
+ "var(offsets=[0,2]) * (int8, {foo: complex128, bar: string})" },
126
+
127
+ { "var(offsets=[0,2]) * var(offsets=[0,3,10]) * (int8, {foo: complex64, bar: string})",
128
+ "var(offsets=[0,2]) * var(offsets=[0,3,10]) * (int8, {foo: complex128, bar: string})",
129
+ "var(offsets=[0,2]) * var(offsets=[0,3,10]) * (int8, {foo: complex128, bar: string})" },
130
+
131
+ { NULL, NULL, 0 }
132
+ };
@@ -0,0 +1,703 @@
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 <string.h>
37
+ #include <assert.h>
38
+ #include "ndtypes.h"
39
+ #include "parsefuncs.h"
40
+ #include "seq.h"
41
+
42
+
43
+ /*****************************************************************************/
44
+ /* Unify two types */
45
+ /*****************************************************************************/
46
+
47
+ /*
48
+ * Unify two types and return a type that can hold all values of both input
49
+ * types. Because of slicing, steps, etc. the returned type cannot be used
50
+ * in general to describe an existing memory block.
51
+ */
52
+
53
+ static const ndt_t *unify(const ndt_t *t, const ndt_t *u, bool replace_any, ndt_context_t *ctx);
54
+
55
+ static enum ndt
56
+ max_tag(enum ndt x, enum ndt y)
57
+ {
58
+ return x >= y ? x : y;
59
+ }
60
+
61
+ static enum ndt_encoding
62
+ max_encoding(enum ndt_encoding x, enum ndt_encoding y)
63
+ {
64
+ return x >= y ? x : y;
65
+ }
66
+
67
+ static int64_t
68
+ max_i64(int64_t x, int64_t y)
69
+ {
70
+ return x >= y ? x : y;
71
+ }
72
+
73
+ static uint16_t
74
+ max_u16(uint16_t x, uint16_t y)
75
+ {
76
+ return x >= y ? x : y;
77
+ }
78
+
79
+
80
+ static ndt_t *
81
+ unification_error(const char *msg, ndt_context_t *ctx)
82
+ {
83
+ ndt_err_format(ctx, NDT_ValueError, "unification failed: %s", msg);
84
+ return NULL;
85
+ }
86
+
87
+ static const ndt_t *
88
+ unify_common(ndt_t *w, const ndt_t *t, const ndt_t *u, ndt_context_t *ctx)
89
+ {
90
+ if ((t->flags & ~(NDT_OPTION|NDT_SUBTREE_OPTION|NDT_POINTER)) !=
91
+ (u->flags & ~(NDT_OPTION|NDT_SUBTREE_OPTION|NDT_POINTER))) {
92
+ ndt_decref(w);
93
+ return unification_error("flags differ", ctx);
94
+ }
95
+
96
+ if (ndt_is_static(w)) {
97
+ return ndt_primitive(w->tag, t->flags | u->flags, ctx);
98
+ }
99
+
100
+ w->flags = t->flags | u->flags;
101
+ return w;
102
+ }
103
+
104
+ static const ndt_t *
105
+ unify_tuple(const ndt_t *t, const ndt_t *u, bool replace_any, ndt_context_t *ctx)
106
+ {
107
+ bool opt = ndt_is_optional(t) || ndt_is_optional(u);
108
+ ndt_field_seq_t *seq;
109
+ ndt_field_t *field;
110
+ const ndt_t *tmp, *w;
111
+ int64_t shape;
112
+ int64_t i;
113
+
114
+ shape = t->Tuple.shape;
115
+ if (shape == 0) {
116
+ return mk_tuple(t->Tuple.flag, NULL, NULL, opt, ctx);
117
+ }
118
+
119
+ tmp = unify(t->Tuple.types[0], u->Tuple.types[0], replace_any, ctx);
120
+ if (tmp == NULL) {
121
+ return NULL;
122
+ }
123
+
124
+ field = mk_field(NULL, tmp, NULL, ctx);
125
+ if (field == NULL) {
126
+ return NULL;
127
+ }
128
+
129
+ seq = ndt_field_seq_new(field, ctx);
130
+ if (seq == NULL) {
131
+ return NULL;
132
+ }
133
+
134
+ for (i = 1; i < t->Tuple.shape; i++) {
135
+ tmp = unify(t->Tuple.types[i], u->Tuple.types[i], replace_any, ctx);
136
+ if (tmp == NULL) {
137
+ ndt_field_seq_del(seq);
138
+ return NULL;
139
+ }
140
+
141
+ field = mk_field(NULL, tmp, NULL, ctx);
142
+ if (field == NULL) {
143
+ ndt_field_seq_del(seq);
144
+ return NULL;
145
+ }
146
+
147
+ seq = ndt_field_seq_append(seq, field, ctx);
148
+ if (seq == NULL) {
149
+ return NULL;
150
+ }
151
+ }
152
+
153
+ w = mk_tuple(t->Tuple.flag, seq, NULL, opt, ctx);
154
+ if (w == NULL) {
155
+ return NULL;
156
+ }
157
+
158
+ return unify_common((ndt_t *)w, t, u, ctx);
159
+ }
160
+
161
+ static const ndt_t *
162
+ unify_record(const ndt_t *t, const ndt_t *u, bool replace_any, ndt_context_t *ctx)
163
+ {
164
+ bool opt = ndt_is_optional(t) || ndt_is_optional(u);
165
+ ndt_field_seq_t *seq;
166
+ ndt_field_t *field;
167
+ const ndt_t *tmp, *w;
168
+ char *name;
169
+ int64_t shape;
170
+ int64_t i;
171
+
172
+ shape = t->Record.shape;
173
+ for (i = 0; i < shape; i++) {
174
+ if (strcmp(t->Record.names[i], u->Record.names[i]) != 0) {
175
+ return unification_error("field name mismatch", ctx);
176
+ }
177
+ }
178
+
179
+ if (shape == 0) {
180
+ return mk_record(t->Record.flag, NULL, NULL, opt, ctx);
181
+ }
182
+
183
+ name = ndt_strdup(t->Record.names[0], ctx);
184
+ if (name == NULL) {
185
+ return NULL;
186
+ }
187
+
188
+ tmp = unify(t->Record.types[0], u->Record.types[0], replace_any, ctx);
189
+ if (tmp == NULL) {
190
+ ndt_free(name);
191
+ return NULL;
192
+ }
193
+
194
+ field = mk_field(name, tmp, NULL, ctx);
195
+ if (field == NULL) {
196
+ return NULL;
197
+ }
198
+
199
+ seq = ndt_field_seq_new(field, ctx);
200
+ if (seq == NULL) {
201
+ return NULL;
202
+ }
203
+
204
+ for (i = 1; i < shape; i++) {
205
+ name = ndt_strdup(t->Record.names[i], ctx);
206
+ if (name == NULL) {
207
+ ndt_field_seq_del(seq);
208
+ return NULL;
209
+ }
210
+
211
+ tmp = unify(t->Record.types[i], u->Record.types[i], replace_any, ctx);
212
+ if (tmp == NULL) {
213
+ ndt_free(name);
214
+ ndt_field_seq_del(seq);
215
+ return NULL;
216
+ }
217
+
218
+ field = mk_field(name, tmp, NULL, ctx);
219
+ if (field == NULL) {
220
+ ndt_field_seq_del(seq);
221
+ return NULL;
222
+ }
223
+
224
+ seq = ndt_field_seq_append(seq, field, ctx);
225
+ if (seq == NULL) {
226
+ return NULL;
227
+ }
228
+ }
229
+
230
+ w = mk_record(t->Record.flag, seq, NULL, opt, ctx);
231
+ if (w == NULL) {
232
+ return NULL;
233
+ }
234
+
235
+ return unify_common((ndt_t *)w, t, u, ctx);
236
+ }
237
+
238
+ static const ndt_t *
239
+ unify_union(const ndt_t *t, const ndt_t *u, bool replace_any, ndt_context_t *ctx)
240
+ {
241
+ bool opt = ndt_is_optional(t) || ndt_is_optional(u);
242
+ ndt_field_seq_t *seq;
243
+ ndt_field_t *field;
244
+ const ndt_t *tmp, *w;
245
+ char *name;
246
+ int64_t ntags;
247
+ int64_t i;
248
+
249
+ ntags = t->Union.ntags;
250
+ assert(ntags > 0);
251
+
252
+ for (i = 0; i < ntags; i++) {
253
+ if (strcmp(t->Union.tags[i], u->Union.tags[i]) != 0) {
254
+ return unification_error("tag mismatch", ctx);
255
+ }
256
+ }
257
+
258
+ name = ndt_strdup(t->Union.tags[0], ctx);
259
+ if (name == NULL) {
260
+ return NULL;
261
+ }
262
+
263
+ tmp = unify(t->Union.types[0], u->Union.types[0], replace_any, ctx);
264
+ if (tmp == NULL) {
265
+ ndt_free(name);
266
+ return NULL;
267
+ }
268
+
269
+ field = mk_field(name, tmp, NULL, ctx);
270
+ if (field == NULL) {
271
+ return NULL;
272
+ }
273
+
274
+ seq = ndt_field_seq_new(field, ctx);
275
+ if (seq == NULL) {
276
+ return NULL;
277
+ }
278
+
279
+ for (i = 1; i < ntags; i++) {
280
+ name = ndt_strdup(t->Union.tags[i], ctx);
281
+ if (name == NULL) {
282
+ ndt_field_seq_del(seq);
283
+ return NULL;
284
+ }
285
+
286
+ tmp = unify(t->Union.types[i], u->Union.types[i], replace_any, ctx);
287
+ if (tmp == NULL) {
288
+ ndt_free(name);
289
+ ndt_field_seq_del(seq);
290
+ return NULL;
291
+ }
292
+
293
+ field = mk_field(name, tmp, NULL, ctx);
294
+ if (field == NULL) {
295
+ ndt_field_seq_del(seq);
296
+ return NULL;
297
+ }
298
+
299
+ seq = ndt_field_seq_append(seq, field, ctx);
300
+ if (seq == NULL) {
301
+ return NULL;
302
+ }
303
+ }
304
+
305
+ w = mk_union(seq, opt, ctx);
306
+ if (w == NULL) {
307
+ return NULL;
308
+ }
309
+
310
+ return unify_common((ndt_t *)w, t, u, ctx);
311
+ }
312
+
313
+ static const ndt_t *
314
+ unify_primitive(const ndt_t *t, const ndt_t *u, ndt_context_t *ctx)
315
+ {
316
+ enum ndt tag = max_tag(t->tag, u->tag);
317
+ const ndt_t *w;
318
+
319
+ w = ndt_primitive(tag, 0, ctx);
320
+ if (w == NULL) {
321
+ return NULL;
322
+ }
323
+
324
+ return unify_common((ndt_t *)w, t, u, ctx);
325
+ }
326
+
327
+ static const ndt_t *
328
+ unify(const ndt_t *t, const ndt_t *u, bool replace_any, ndt_context_t *ctx)
329
+ {
330
+ bool opt = ndt_is_optional(t) || ndt_is_optional(u);
331
+ const ndt_t *type, *w;
332
+
333
+ if (replace_any && t->tag == AnyKind && u->tag == AnyKind) {
334
+ return ndt_primitive(Float64, opt, ctx);
335
+ }
336
+
337
+ if (u->tag == AnyKind) {
338
+ w = ndt_copy(t, ctx);
339
+ if (w == NULL) {
340
+ return NULL;
341
+ }
342
+
343
+ return unify_common((ndt_t *)w, t, u, ctx);
344
+ }
345
+
346
+ if (t->tag == AnyKind) {
347
+ w = ndt_copy(u, ctx);
348
+ if (w == NULL) {
349
+ return NULL;
350
+ }
351
+
352
+ return unify_common((ndt_t *)w, t, u, ctx);
353
+ }
354
+
355
+ switch (t->tag) {
356
+ case FixedDim: {
357
+ if (u->tag != FixedDim) {
358
+ return unification_error("different types", ctx);
359
+ }
360
+
361
+ if (t->FixedDim.shape != u->FixedDim.shape) {
362
+ return unification_error("mismatch in fixed dimension", ctx);
363
+ }
364
+
365
+ type = unify(t->FixedDim.type, u->FixedDim.type, replace_any, ctx);
366
+ if (type == NULL) {
367
+ return NULL;
368
+ }
369
+
370
+ w = ndt_fixed_dim(type, t->FixedDim.shape, t->Concrete.FixedDim.step, ctx);
371
+ ndt_decref(type);
372
+ if (w == NULL) {
373
+ return NULL;
374
+ }
375
+
376
+ return unify_common((ndt_t *)w, t, u, ctx);
377
+ }
378
+
379
+ case VarDim: {
380
+
381
+ if (u->tag != VarDim) {
382
+ return unification_error("different types", ctx);
383
+ }
384
+
385
+ if (ndt_is_abstract(t) || ndt_is_abstract(u)) {
386
+ return unification_error("cannot unify abstract var dimension", ctx);
387
+ }
388
+
389
+ if (t->Concrete.VarDim.nslices != 0 || u->Concrete.VarDim.nslices != 0) {
390
+ return unification_error("cannot unify sliced var dimension", ctx);
391
+ }
392
+
393
+ int32_t noffsets = t->Concrete.VarDim.offsets->n;
394
+ if (u->Concrete.VarDim.offsets->n != noffsets) {
395
+ return unification_error("offset mismatch in var dimension", ctx);
396
+ }
397
+
398
+ if (memcmp(t->Concrete.VarDim.offsets->v, u->Concrete.VarDim.offsets->v,
399
+ noffsets * (sizeof *t->Concrete.VarDim.offsets->v))) {
400
+ return unification_error("shape mismatch in var dimension", ctx);
401
+ }
402
+
403
+ type = unify(t->VarDim.type, u->VarDim.type, replace_any, ctx);
404
+ if (type == NULL) {
405
+ return NULL;
406
+ }
407
+
408
+ w = ndt_var_dim(type, t->Concrete.VarDim.offsets, 0, NULL, opt, ctx);
409
+ ndt_decref(type);
410
+ if (w == NULL) {
411
+ return NULL;
412
+ }
413
+
414
+ return unify_common((ndt_t *)w, t, u, ctx);
415
+ }
416
+
417
+ case VarDimElem: {
418
+ return unification_error("cannot unify VarDimElem", ctx);
419
+ }
420
+
421
+ case Array: {
422
+ if (u->tag != Array || u->Array.itemsize != t->Array.itemsize) {
423
+ return unification_error("different types", ctx);
424
+ }
425
+
426
+ type = unify(t->Array.type, u->Array.type, replace_any, ctx);
427
+ if (type == NULL) {
428
+ return NULL;
429
+ }
430
+
431
+ w = ndt_array(type, opt, ctx);
432
+ ndt_decref(type);
433
+ if (w == NULL) {
434
+ return NULL;
435
+ }
436
+
437
+ return unify_common((ndt_t *)w, t, u, ctx);
438
+ }
439
+
440
+ case Tuple: {
441
+ if (u->tag != Tuple) {
442
+ return unification_error("different types", ctx);
443
+ }
444
+
445
+ if (t->Tuple.flag != u->Tuple.flag ||
446
+ t->Tuple.shape != u->Tuple.shape) {
447
+ return 0;
448
+ }
449
+
450
+ return unify_tuple(t, u, replace_any, ctx);
451
+ }
452
+
453
+ case Record: {
454
+ if (u->tag != Record) {
455
+ return unification_error("different types", ctx);
456
+ }
457
+
458
+ if (t->Record.flag != u->Record.flag ||
459
+ t->Record.shape != u->Record.shape) {
460
+ return 0;
461
+ }
462
+
463
+ return unify_record(t, u, replace_any, ctx);
464
+ }
465
+
466
+ case Union: {
467
+ if (u->tag != Union) {
468
+ return unification_error("different types", ctx);
469
+ }
470
+
471
+ if (t->Union.ntags != u->Union.ntags) {
472
+ return 0;
473
+ }
474
+
475
+ return unify_union(t, u, replace_any, ctx);
476
+ }
477
+
478
+ case Ref: {
479
+ if (u->tag != Ref) {
480
+ return unification_error("different types", ctx);
481
+ }
482
+
483
+ type = unify(t->Ref.type, u->Ref.type, replace_any, ctx);
484
+ if (type == NULL) {
485
+ return NULL;
486
+ }
487
+
488
+ w = ndt_ref(type, opt, ctx);
489
+ ndt_decref(type);
490
+ if (w == NULL) {
491
+ return NULL;
492
+ }
493
+
494
+ return unify_common((ndt_t *)w, t, u, ctx);
495
+ }
496
+
497
+ case Constr: {
498
+ char *name;
499
+
500
+ if (u->tag != Constr) {
501
+ return unification_error("different types", ctx);
502
+ }
503
+
504
+ if (strcmp(t->Constr.name, u->Constr.name) != 0) {
505
+ return unification_error("different constructor names", ctx);
506
+ }
507
+
508
+ name = ndt_strdup(t->Constr.name, ctx);
509
+ if (name == NULL) {
510
+ return NULL;
511
+ }
512
+
513
+ type = unify(t->Constr.type, u->Constr.type, replace_any, ctx);
514
+ if (type == NULL) {
515
+ ndt_free(name);
516
+ return NULL;
517
+ }
518
+
519
+ w = ndt_constr(name, type, opt, ctx);
520
+ ndt_decref(type);
521
+ if (w == NULL) {
522
+ return NULL;
523
+ }
524
+
525
+ return unify_common((ndt_t *)w, t, u, ctx);
526
+ }
527
+
528
+ case Nominal: {
529
+ if (!ndt_equal(t, u)) {
530
+ return unification_error("nominal types must be identical", ctx);
531
+ }
532
+
533
+ w = ndt_copy(t, ctx);
534
+ if (w == NULL) {
535
+ return NULL;
536
+ }
537
+
538
+ return unify_common((ndt_t *)w, t, u, ctx);
539
+ }
540
+
541
+ case Categorical: {
542
+ if (!ndt_equal(t, u)) {
543
+ return unification_error("categorical types must be identical", ctx);
544
+ }
545
+
546
+ w = ndt_copy(t, ctx);
547
+ if (w == NULL) {
548
+ return NULL;
549
+ }
550
+
551
+ return unify_common((ndt_t *)w, t, u, ctx);
552
+ }
553
+
554
+ case FixedString: {
555
+ int64_t size;
556
+ enum ndt_encoding encoding;
557
+
558
+ if (u->tag != FixedString) {
559
+ return unification_error("different types", ctx);
560
+ }
561
+
562
+ size = max_i64(t->FixedString.size, u->FixedString.size);
563
+ encoding = max_encoding(t->FixedString.encoding, u->FixedString.encoding);
564
+
565
+ w = ndt_fixed_string(size, encoding, opt, ctx);
566
+ if (w == NULL) {
567
+ return NULL;
568
+ }
569
+
570
+ return unify_common((ndt_t *)w, t, u, ctx);
571
+ }
572
+
573
+ case FixedBytes: {
574
+ int64_t size;
575
+ uint16_opt_t align = {Some, 1024};
576
+
577
+ if (u->tag != FixedBytes) {
578
+ return unification_error("different types", ctx);
579
+ }
580
+
581
+ size = max_i64(t->FixedBytes.size, u->FixedBytes.size);
582
+ align.Some = max_u16(t->FixedBytes.align, u->FixedBytes.align);
583
+
584
+ w = ndt_fixed_bytes(size, align, opt, ctx);
585
+ if (w == NULL) {
586
+ return NULL;
587
+ }
588
+
589
+ return unify_common((ndt_t *)w, t, u, ctx);
590
+ }
591
+
592
+ case Bytes: {
593
+ uint16_opt_t align = {Some, 1024};
594
+
595
+ if (u->tag != Bytes) {
596
+ return unification_error("different types", ctx);
597
+ }
598
+
599
+ align.Some = max_u16(t->Bytes.target_align, u->Bytes.target_align);
600
+
601
+ w = ndt_bytes(align, opt, ctx);
602
+ if (w == NULL) {
603
+ return NULL;
604
+ }
605
+
606
+ return unify_common((ndt_t *)w, t, u, ctx);
607
+ }
608
+
609
+ case Char: {
610
+ enum ndt_encoding encoding;
611
+
612
+ if (u->tag != Char) {
613
+ return unification_error("different types", ctx);
614
+ }
615
+
616
+ encoding = max_encoding(t->Char.encoding, u->Char.encoding);
617
+
618
+ w = ndt_char(encoding, opt, ctx);
619
+ if (w == NULL) {
620
+ return NULL;
621
+ }
622
+
623
+ return unify_common((ndt_t *)w, t, u, ctx);
624
+ }
625
+
626
+ case Bool: {
627
+ if (u->tag != Bool) {
628
+ return unification_error("different types", ctx);
629
+ }
630
+
631
+ return unify_primitive(t, u, ctx);
632
+ }
633
+
634
+ case Int8: case Int16: case Int32: case Int64: {
635
+ if (!ndt_is_signed(u)) {
636
+ return unification_error("different types", ctx);
637
+ }
638
+
639
+ return unify_primitive(t, u, ctx);
640
+ }
641
+
642
+ case Uint8: case Uint16: case Uint32: case Uint64: {
643
+ if (!ndt_is_unsigned(u)) {
644
+ return unification_error("different types", ctx);
645
+ }
646
+
647
+ return unify_primitive(t, u, ctx);
648
+ }
649
+
650
+ case BFloat16: case Float16: case Float32: case Float64: {
651
+ if (!ndt_is_float(u)) {
652
+ return unification_error("different types", ctx);
653
+ }
654
+
655
+ return unify_primitive(t, u, ctx);
656
+ }
657
+
658
+ case BComplex32: case Complex32: case Complex64: case Complex128: {
659
+ if (!ndt_is_complex(u)) {
660
+ return unification_error("different types", ctx);
661
+ }
662
+
663
+ return unify_primitive(t, u, ctx);
664
+ }
665
+
666
+ case String: {
667
+ if (u->tag != String) {
668
+ return unification_error("different types", ctx);
669
+ }
670
+
671
+ w = ndt_string(opt, ctx);
672
+ if (w == NULL) {
673
+ return NULL;
674
+ }
675
+
676
+ return unify_common((ndt_t *)w, t, u, ctx);
677
+ }
678
+
679
+ case AnyKind:
680
+ case Module: case Function:
681
+ case SymbolicDim: case EllipsisDim:
682
+ case ScalarKind:
683
+ case SignedKind: case UnsignedKind:
684
+ case FloatKind: case ComplexKind:
685
+ case FixedStringKind: case FixedBytesKind:
686
+ case Typevar:
687
+ return unification_error("abstract type", ctx);
688
+ }
689
+
690
+ ndt_internal_error("invalid type tag");
691
+ }
692
+
693
+ const ndt_t *
694
+ ndt_unify(const ndt_t *t, const ndt_t *u, ndt_context_t *ctx)
695
+ {
696
+ return unify(t, u, false, ctx);
697
+ }
698
+
699
+ const ndt_t *
700
+ ndt_unify_replace_any(const ndt_t *t, const ndt_t *u, ndt_context_t *ctx)
701
+ {
702
+ return unify(t, u, true, ctx);
703
+ }