ndtypes 0.2.0dev4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +50 -0
  3. data/Gemfile +2 -0
  4. data/History.md +0 -0
  5. data/README.md +19 -0
  6. data/Rakefile +125 -0
  7. data/ext/ruby_ndtypes/extconf.rb +55 -0
  8. data/ext/ruby_ndtypes/gc_guard.c +36 -0
  9. data/ext/ruby_ndtypes/gc_guard.h +12 -0
  10. data/ext/ruby_ndtypes/ndtypes/AUTHORS.txt +5 -0
  11. data/ext/ruby_ndtypes/ndtypes/INSTALL.txt +101 -0
  12. data/ext/ruby_ndtypes/ndtypes/LICENSE.txt +29 -0
  13. data/ext/ruby_ndtypes/ndtypes/MANIFEST.in +3 -0
  14. data/ext/ruby_ndtypes/ndtypes/Makefile.in +87 -0
  15. data/ext/ruby_ndtypes/ndtypes/README.rst +47 -0
  16. data/ext/ruby_ndtypes/ndtypes/config.guess +1530 -0
  17. data/ext/ruby_ndtypes/ndtypes/config.h.in +67 -0
  18. data/ext/ruby_ndtypes/ndtypes/config.sub +1782 -0
  19. data/ext/ruby_ndtypes/ndtypes/configure +5260 -0
  20. data/ext/ruby_ndtypes/ndtypes/configure.ac +161 -0
  21. data/ext/ruby_ndtypes/ndtypes/doc/Makefile +14 -0
  22. data/ext/ruby_ndtypes/ndtypes/doc/_static/copybutton.js +66 -0
  23. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +26 -0
  24. data/ext/ruby_ndtypes/ndtypes/doc/grammar/grammar.rst +27 -0
  25. data/ext/ruby_ndtypes/ndtypes/doc/index.rst +56 -0
  26. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/context.rst +131 -0
  27. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/encodings.rst +68 -0
  28. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/fields-values.rst +175 -0
  29. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/functions.rst +72 -0
  30. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/index.rst +43 -0
  31. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/init.rst +48 -0
  32. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/io.rst +100 -0
  33. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/memory.rst +124 -0
  34. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/predicates.rst +110 -0
  35. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/typedef.rst +31 -0
  36. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/types.rst +594 -0
  37. data/ext/ruby_ndtypes/ndtypes/doc/libndtypes/util.rst +166 -0
  38. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/buffer-protocol.rst +27 -0
  39. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/index.rst +21 -0
  40. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/pattern-matching.rst +330 -0
  41. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/quickstart.rst +144 -0
  42. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +544 -0
  43. data/ext/ruby_ndtypes/ndtypes/doc/releases/index.rst +35 -0
  44. data/ext/ruby_ndtypes/ndtypes/install-sh +527 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +271 -0
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +269 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +230 -0
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.c +268 -0
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.h +109 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.in +73 -0
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile.vc +70 -0
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/README.txt +16 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +2179 -0
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +134 -0
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +428 -0
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +2543 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +735 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +176 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +543 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +110 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.c +228 -0
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +634 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.c +116 -0
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +288 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +3067 -0
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +180 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +417 -0
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +1658 -0
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +2773 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +734 -0
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +222 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +1132 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +2323 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +893 -0
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/overflow.h +161 -0
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +473 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +92 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +246 -0
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +269 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +197 -0
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.in +48 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile.vc +46 -0
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +1007 -0
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +442 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/slice.h +42 -0
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +238 -0
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +50 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +371 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +100 -0
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +55 -0
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +45 -0
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.c +82 -0
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/alloc_fail.h +49 -0
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +1657 -0
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +85 -0
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +115 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +137 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_indent.c +201 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +2397 -0
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_numba.c +57 -0
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +349 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +27839 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +350 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +231 -0
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +375 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typedef.c +65 -0
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/valgrind.supp +30 -0
  108. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/bench.c +79 -0
  109. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/indent.c +94 -0
  110. data/ext/ruby_ndtypes/ndtypes/libndtypes/tools/print_ast.c +96 -0
  111. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +474 -0
  112. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +228 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/bench.py +49 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +409 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +14 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +70 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +1332 -0
  118. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/docstrings.h +319 -0
  119. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +154 -0
  120. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +1977 -0
  121. data/ext/ruby_ndtypes/ndtypes/setup.py +288 -0
  122. data/ext/ruby_ndtypes/ndtypes/vcbuild/INSTALL.txt +41 -0
  123. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest32.bat +15 -0
  124. data/ext/ruby_ndtypes/ndtypes/vcbuild/runtest64.bat +13 -0
  125. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild32.bat +38 -0
  126. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcbuild64.bat +38 -0
  127. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcclean.bat +13 -0
  128. data/ext/ruby_ndtypes/ndtypes/vcbuild/vcdistclean.bat +14 -0
  129. data/ext/ruby_ndtypes/ruby_ndtypes.c +1003 -0
  130. data/ext/ruby_ndtypes/ruby_ndtypes.h +37 -0
  131. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +28 -0
  132. data/lib/ndtypes.rb +45 -0
  133. data/lib/ndtypes/errors.rb +2 -0
  134. data/lib/ndtypes/version.rb +6 -0
  135. data/ndtypes.gemspec +47 -0
  136. data/spec/gc_table_spec.rb +10 -0
  137. data/spec/ndtypes_spec.rb +289 -0
  138. data/spec/spec_helper.rb +241 -0
  139. metadata +242 -0
@@ -0,0 +1,238 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #include <stdio.h>
35
+ #include <stdlib.h>
36
+ #include <stdint.h>
37
+ #include <inttypes.h>
38
+ #include <stdbool.h>
39
+ #include <string.h>
40
+ #include <stdarg.h>
41
+ #include <assert.h>
42
+ #include "ndtypes.h"
43
+ #include "symtable.h"
44
+ #include "substitute.h"
45
+
46
+
47
+ static ndt_t *
48
+ substitute_named_ellipsis(const ndt_t *t, const symtable_t *tbl, ndt_context_t *ctx)
49
+ {
50
+ symtable_entry_t v;
51
+ ndt_t *u;
52
+ int i;
53
+
54
+ assert(t->tag == EllipsisDim && t->EllipsisDim.name != NULL);
55
+
56
+ u = ndt_substitute(t->EllipsisDim.type, tbl, true, ctx);
57
+ if (u == NULL) {
58
+ return NULL;
59
+ }
60
+
61
+ v = symtable_find(tbl, t->EllipsisDim.name);
62
+
63
+ switch (v.tag) {
64
+ case FixedSeq: {
65
+ for (i = v.FixedSeq.size-1; i >= 0; i--) {
66
+ const ndt_t *w = v.FixedSeq.dims[i];
67
+ assert(ndt_is_concrete(w));
68
+ assert(w->tag == FixedDim);
69
+
70
+ u = ndt_fixed_dim(u, w->FixedDim.shape, INT64_MAX, ctx);
71
+ if (u == NULL) {
72
+ return NULL;
73
+ }
74
+ }
75
+
76
+ return u;
77
+ }
78
+ case VarSeq: {
79
+ if (v.VarSeq.size == 0) {
80
+ return u;
81
+ }
82
+ else {
83
+ const ndt_t *w = v.VarSeq.dims[0];
84
+ return ndt_copy_contiguous_dtype(w, u, ctx);
85
+ }
86
+ }
87
+ default:
88
+ ndt_err_format(ctx, NDT_ValueError,
89
+ "variable not found or has incorrect type");
90
+ ndt_del(u);
91
+ return NULL;
92
+ }
93
+ }
94
+
95
+ ndt_t *
96
+ ndt_substitute(const ndt_t *t, const symtable_t *tbl, const bool req_concrete,
97
+ ndt_context_t *ctx)
98
+ {
99
+ ndt_t *u;
100
+
101
+ if (ndt_is_concrete(t)) {
102
+ return ndt_copy(t, ctx);
103
+ }
104
+
105
+ switch (t->tag) {
106
+ case FixedDim: {
107
+ u = ndt_substitute(t->FixedDim.type, tbl, req_concrete, ctx);
108
+ if (u == NULL) {
109
+ return NULL;
110
+ }
111
+
112
+ return ndt_fixed_dim(u, t->FixedDim.shape, t->Concrete.FixedDim.step,
113
+ ctx);
114
+ }
115
+
116
+ case VarDim: {
117
+ u = ndt_substitute(ndt_dtype(t), tbl, req_concrete, ctx);
118
+ if (u == NULL) {
119
+ return NULL;
120
+ }
121
+
122
+ return ndt_copy_abstract_var_dtype(t, u, ctx);
123
+ }
124
+
125
+ case SymbolicDim: {
126
+ u = ndt_substitute(t->SymbolicDim.type, tbl, req_concrete, ctx);
127
+ if (u == NULL) {
128
+ return NULL;
129
+ }
130
+
131
+ const int64_t shape = symtable_find_shape(tbl, t->SymbolicDim.name, ctx);
132
+ if (shape < 0) {
133
+ if (req_concrete) {
134
+ ndt_del(u);
135
+ return NULL;
136
+ }
137
+ else {
138
+ ndt_err_clear(ctx);
139
+ char *name = ndt_strdup(t->SymbolicDim.name, ctx);
140
+ if (name == NULL) {
141
+ ndt_del(u);
142
+ return NULL;
143
+ }
144
+ return ndt_symbolic_dim(name, u, ctx);
145
+ }
146
+ }
147
+
148
+ return ndt_fixed_dim(u, shape, INT64_MAX, ctx);
149
+ }
150
+
151
+ case EllipsisDim: {
152
+ if (t->EllipsisDim.name == NULL) {
153
+ return ndt_substitute(t->EllipsisDim.type, tbl, true, ctx);
154
+ }
155
+ else {
156
+ return substitute_named_ellipsis(t, tbl, ctx);
157
+ }
158
+ }
159
+
160
+ case Typevar: {
161
+ const ndt_t *v = symtable_find_typevar(tbl, t->Typevar.name, ctx);
162
+ if (v == NULL) {
163
+ if (req_concrete) {
164
+ return NULL;
165
+ }
166
+ else {
167
+ ndt_err_clear(ctx);
168
+ char *name = ndt_strdup(t->Typevar.name, ctx);
169
+ if (name == NULL) {
170
+ return NULL;
171
+ }
172
+ return ndt_typevar(name, ctx);
173
+ }
174
+ }
175
+
176
+ return ndt_substitute(v, tbl, req_concrete, ctx);
177
+ }
178
+
179
+ case Constr: {
180
+ char *name = ndt_strdup(t->Constr.name, ctx);
181
+ if (name == NULL) {
182
+ return NULL;
183
+ }
184
+
185
+ u = ndt_substitute(t->Constr.type, tbl, req_concrete, ctx);
186
+ if (u == NULL) {
187
+ ndt_free(name);
188
+ return NULL;
189
+ }
190
+
191
+ return ndt_constr(name, u, ctx);
192
+ }
193
+
194
+ case Nominal: {
195
+ char *name = ndt_strdup(t->Nominal.name, ctx);
196
+ if (name == NULL) {
197
+ return NULL;
198
+ }
199
+
200
+ u = ndt_copy(t->Nominal.type, ctx);
201
+ if (u == NULL) {
202
+ ndt_free(name);
203
+ return NULL;
204
+ }
205
+
206
+ return ndt_nominal(name, u, ctx);
207
+ }
208
+
209
+ case Ref:
210
+ u = ndt_substitute(t->Ref.type, tbl, req_concrete, ctx);
211
+ if (u == NULL) {
212
+ return NULL;
213
+ }
214
+
215
+ return ndt_ref(u, ctx);
216
+
217
+ case Bool:
218
+ case Int8: case Int16: case Int32: case Int64:
219
+ case Uint8: case Uint16: case Uint32: case Uint64:
220
+ case Float16: case Float32: case Float64:
221
+ case Complex32: case Complex64: case Complex128:
222
+ case FixedString: case FixedBytes:
223
+ case String: case Bytes:
224
+ case Char: {
225
+ u = ndt_new(t->tag, ctx);
226
+ if (u == NULL) {
227
+ return NULL;
228
+ }
229
+ *u = *t;
230
+ return u;
231
+ }
232
+
233
+ default:
234
+ ndt_err_format(ctx, NDT_NotImplementedError,
235
+ "substitution not implemented for this type");
236
+ return NULL;
237
+ }
238
+ }
@@ -0,0 +1,50 @@
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
+ #ifndef SUBSTITUTE_H
35
+ #define SUBSTITUTE_H
36
+
37
+
38
+ #include "symtable.h"
39
+
40
+
41
+ /* LOCAL SCOPE */
42
+ NDT_PRAGMA(NDT_HIDE_SYMBOLS_START)
43
+
44
+ ndt_t *ndt_substitute(const ndt_t *t, const symtable_t *tbl, const bool req_concrete, ndt_context_t *ctx);
45
+
46
+ /* END LOCAL SCOPE */
47
+ NDT_PRAGMA(NDT_HIDE_SYMBOLS_END)
48
+
49
+
50
+ #endif /* SUBSTITUTE_H */
@@ -0,0 +1,371 @@
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 <limits.h>
36
+ #include <stddef.h>
37
+ #include "ndtypes.h"
38
+ #include "symtable.h"
39
+
40
+
41
+ /*****************************************************************************/
42
+ /* Charmap */
43
+ /*****************************************************************************/
44
+
45
+ #define ALPHABET_LEN 63
46
+
47
+ static int code[UCHAR_MAX+1];
48
+ static unsigned char alpha[ALPHABET_LEN+1] =
49
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
50
+
51
+ static void
52
+ init_charmap(void)
53
+ {
54
+ int i;
55
+
56
+ for (i = 0; i < UCHAR_MAX+1; i++) {
57
+ code[i] = UCHAR_MAX;
58
+ }
59
+
60
+ for (i = 0; i < ALPHABET_LEN; i++) {
61
+ code[alpha[i]] = i;
62
+ }
63
+ }
64
+
65
+
66
+ /*****************************************************************************/
67
+ /* Global typedef map */
68
+ /*****************************************************************************/
69
+
70
+ typedef struct typedef_trie {
71
+ ndt_typedef_t def;
72
+ struct typedef_trie *next[];
73
+ } typedef_trie_t;
74
+
75
+ static typedef_trie_t *typedef_map = NULL;
76
+
77
+ static typedef_trie_t *
78
+ typedef_trie_new(ndt_context_t *ctx)
79
+ {
80
+ typedef_trie_t *t;
81
+ int i;
82
+
83
+ t = ndt_alloc_size(offsetof(typedef_trie_t, next) + ALPHABET_LEN * (sizeof t));
84
+ if (t == NULL) {
85
+ return ndt_memory_error(ctx);
86
+ }
87
+
88
+ t->def.type = NULL;
89
+ t->def.meth.init = NULL;
90
+ t->def.meth.constraint = NULL;
91
+ t->def.meth.repr = NULL;
92
+
93
+ for (i = 0; i < ALPHABET_LEN; i++) {
94
+ t->next[i] = NULL;
95
+ }
96
+
97
+ return t;
98
+ }
99
+
100
+ static void
101
+ typedef_trie_del(typedef_trie_t *t)
102
+ {
103
+ int i;
104
+
105
+ if (t == NULL) {
106
+ return;
107
+ }
108
+
109
+ ndt_del((ndt_t *)t->def.type);
110
+
111
+ for (i = 0; i < ALPHABET_LEN; i++) {
112
+ typedef_trie_del(t->next[i]);
113
+ }
114
+
115
+ ndt_free(t);
116
+ }
117
+
118
+ int
119
+ ndt_typedef_add(const char *key, ndt_t *type, const ndt_methods_t *m, ndt_context_t *ctx)
120
+ {
121
+ typedef_trie_t *t = typedef_map;
122
+ const unsigned char *cp;
123
+ int i;
124
+
125
+ for (cp = (const unsigned char *)key; *cp != '\0'; cp++) {
126
+ i = code[*cp];
127
+ if (i == UCHAR_MAX) {
128
+ ndt_err_format(ctx, NDT_ValueError,
129
+ "invalid character in typedef: '%c'", *cp);
130
+ ndt_del(type);
131
+ return -1;
132
+ }
133
+
134
+ if (t->next[i] == NULL) {
135
+ typedef_trie_t *u = typedef_trie_new(ctx);
136
+ if (u == NULL) {
137
+ ndt_del(type);
138
+ return -1;
139
+ }
140
+ t->next[i] = u;
141
+ t = u;
142
+ }
143
+ else {
144
+ t = t->next[i];
145
+ }
146
+ }
147
+
148
+ if (t->def.type) {
149
+ ndt_err_format(ctx, NDT_ValueError, "duplicate typedef '%s'", key);
150
+ ndt_del(type);
151
+ return -1;
152
+ }
153
+
154
+ t->def.type = type;
155
+
156
+ if (m != NULL) {
157
+ t->def.meth = *m;
158
+ }
159
+
160
+ return 0;
161
+ }
162
+
163
+ const ndt_typedef_t *
164
+ ndt_typedef_find(const char *key, ndt_context_t *ctx)
165
+ {
166
+ typedef_trie_t *t = typedef_map;
167
+ const unsigned char *cp;
168
+ int i;
169
+
170
+ for (cp = (const unsigned char *)key; *cp != '\0'; cp++) {
171
+ i = code[*cp];
172
+ if (i == UCHAR_MAX) {
173
+ ndt_err_format(ctx, NDT_ValueError,
174
+ "invalid character in typedef: '%c'", *cp);
175
+ return NULL;
176
+ }
177
+
178
+ if (t->next[i] == NULL) {
179
+ ndt_err_format(ctx, NDT_ValueError,
180
+ "missing typedef for key '%s'", key);
181
+ return NULL;
182
+ }
183
+ t = t->next[i];
184
+ }
185
+
186
+ if (t->def.type == NULL) {
187
+ ndt_err_format(ctx, NDT_RuntimeError,
188
+ "missing typedef for key '%s'", key);
189
+ return NULL;
190
+ }
191
+
192
+ return &t->def;
193
+ }
194
+
195
+
196
+ /*****************************************************************************/
197
+ /* Initialize/finalize global values */
198
+ /*****************************************************************************/
199
+
200
+ int
201
+ ndt_init(ndt_context_t *ctx)
202
+ {
203
+ init_charmap();
204
+
205
+ typedef_map = typedef_trie_new(ctx);
206
+ if (typedef_map == NULL) {
207
+ return -1;
208
+ }
209
+
210
+ return 0;
211
+ }
212
+
213
+ void
214
+ ndt_finalize(void)
215
+ {
216
+ typedef_trie_del(typedef_map);
217
+ typedef_map = NULL;
218
+ }
219
+
220
+
221
+ /*****************************************************************************/
222
+ /* Symbol tables for matching */
223
+ /*****************************************************************************/
224
+
225
+ symtable_t *
226
+ symtable_new(ndt_context_t *ctx)
227
+ {
228
+ symtable_t *t;
229
+ int i;
230
+
231
+ t = ndt_alloc_size(offsetof(symtable_t, next) + ALPHABET_LEN * (sizeof t));
232
+ if (t == NULL) {
233
+ return ndt_memory_error(ctx);
234
+ }
235
+
236
+ t->entry.tag = Unbound;
237
+
238
+ for (i = 0; i < ALPHABET_LEN; i++) {
239
+ t->next[i] = NULL;
240
+ }
241
+
242
+ return t;
243
+ }
244
+
245
+ void
246
+ symtable_del(symtable_t *t)
247
+ {
248
+ int i;
249
+
250
+ if (t == NULL) {
251
+ return;
252
+ }
253
+
254
+ for (i = 0; i < ALPHABET_LEN; i++) {
255
+ symtable_del(t->next[i]);
256
+ }
257
+
258
+ ndt_free(t);
259
+ }
260
+
261
+ int
262
+ symtable_add(symtable_t *t, const char *key, const symtable_entry_t entry,
263
+ ndt_context_t *ctx)
264
+ {
265
+ const unsigned char *cp;
266
+ int i;
267
+
268
+ for (cp = (const unsigned char *)key; *cp != '\0'; cp++) {
269
+ i = code[*cp];
270
+ if (i == UCHAR_MAX) {
271
+ ndt_err_format(ctx, NDT_ValueError,
272
+ "invalid character in symbol: '%c'", *cp);
273
+ return -1;
274
+ }
275
+
276
+ if (t->next[i] == NULL) {
277
+ symtable_t *u = symtable_new(ctx);
278
+ if (u == NULL) {
279
+ return -1;
280
+ }
281
+ t->next[i] = u;
282
+ t = u;
283
+ }
284
+ else {
285
+ t = t->next[i];
286
+ }
287
+ }
288
+
289
+ if (t->entry.tag != Unbound) {
290
+ ndt_err_format(ctx, NDT_ValueError, "duplicate binding for '%s'", key);
291
+ return -1;
292
+ }
293
+
294
+ t->entry = entry;
295
+ return 0;
296
+ }
297
+
298
+ symtable_entry_t
299
+ symtable_find(const symtable_t *t, const char *key)
300
+ {
301
+ symtable_entry_t unbound = { .tag=Unbound };
302
+ const unsigned char *cp;
303
+ int i;
304
+
305
+ for (cp = (const unsigned char *)key; *cp != '\0'; cp++) {
306
+ i = code[*cp];
307
+ if (i == UCHAR_MAX) {
308
+ return unbound; /* NOT REACHED */
309
+ }
310
+
311
+ if (t->next[i] == NULL) {
312
+ return unbound;
313
+ }
314
+ t = t->next[i];
315
+ }
316
+
317
+ return t->entry;
318
+ }
319
+
320
+ symtable_entry_t *
321
+ symtable_find_ptr(symtable_t *t, const char *key)
322
+ {
323
+ const unsigned char *cp;
324
+ int i;
325
+
326
+ for (cp = (const unsigned char *)key; *cp != '\0'; cp++) {
327
+ i = code[*cp];
328
+ if (i == UCHAR_MAX) {
329
+ return NULL; /* NOT REACHED */
330
+ }
331
+
332
+ if (t->next[i] == NULL) {
333
+ return NULL;
334
+ }
335
+ t = t->next[i];
336
+ }
337
+
338
+ return &t->entry;
339
+ }
340
+
341
+ int64_t
342
+ symtable_find_shape(const symtable_t *tbl, const char *key, ndt_context_t *ctx)
343
+ {
344
+ symtable_entry_t v;
345
+
346
+ v = symtable_find(tbl, key);
347
+ switch (v.tag) {
348
+ case Shape:
349
+ return v.Shape;
350
+ default:
351
+ ndt_err_format(ctx, NDT_ValueError,
352
+ "variable not found or has incorrect type");
353
+ return -1;
354
+ }
355
+ }
356
+
357
+ const ndt_t *
358
+ symtable_find_typevar(const symtable_t *tbl, const char *key, ndt_context_t *ctx)
359
+ {
360
+ symtable_entry_t v;
361
+
362
+ v = symtable_find(tbl, key);
363
+ switch (v.tag) {
364
+ case Type:
365
+ return v.Type;
366
+ default:
367
+ ndt_err_format(ctx, NDT_ValueError,
368
+ "variable not found or has incorrect type");
369
+ return NULL;
370
+ }
371
+ }