1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <ctype.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <stdbool.h>
8 #include <math.h>
16 bool
18 {
20 }
22 bool
24 {
25 /* Открытые массивы всегда размером 0 */
28 }
30 bool
32 {
34 }
36 bool
38 {
40 }
42 bool
44 {
47 }
49 bool
51 {
53 }
55 bool
57 {
59 }
61 bool
63 {
65 }
67 bool
69 {
71 }
73 bool
75 {
77 }
79 bool
81 {
83 }
85 bool
87 {
89 }
91 bool
93 {
95 }
97 bool
99 {
101 }
103 bool
105 {
107 }
109 bool
111 {
113 }
117 bool
119 {
120 /* Две переменные a и b с типами Ta и Tb имеют одинаковый тип, если */
121 /* 1. Ta и Tb оба обозначены одним и тем же идентификатором типа, или */
122 /* 2. Ta объявлен равным Tb в объявлении типа вида Ta = Tb, или */
123 /* 3. a и b появляются в одном и том же списке идентификаторов переменных, полей записи */
124 /* или объявлении формальных параметров и не являются открытыми массивами. */
127 }
129 bool
131 {
132 /* Два списка формальных параметров совпадают если */
133 /* 1. они имеют одинаковое количество параметров, и */
134 /* 2. они имеют или одинаковый тип результата функции или не имеют никакого, и */
135 /* 3. параметры в соответствующих позициях имеют равные типы, и */
136 /* 4. параметры в соответствующих позициях - оба или параметры-значения */
137 /* или параметры-переменные. */
140 {
142 }
145 {
147 }
153 {
155 {
157 }
160 {
162 }
166 }
169 }
171 bool
173 {
174 /* Два типа Ta, и Tb равны, если */
175 /* 1. Ta и Tb - одинаковые типы, или */
176 /* 2. Ta и Tb - типы открытый массив с равными типами элементов, или */
177 /* 3. Ta и Tb - процедурные типы, чьи списки формальных параметров совпадают. */
180 || (oberon_is_open_array(a) && oberon_is_open_array(b) && oberon_is_some_types(a -> base, b -> base))
181 || (oberon_is_procedure_type(a) && oberon_is_procedure_type(b) && oberon_is_some_procedure_signatures(a, b));
182 }
184 bool
186 {
187 /* a поглощает b */
188 /* LONGREAL >= REAL >= LONGINT >= INTEGER >= SHORTINT */
190 /*
191 printf("oberon_incluses_type: a %i %i\n", a -> class, a -> size);
192 printf("oberon_incluses_type: b %i %i\n", b -> class, b -> size);
193 */
196 {
198 {
200 }
202 {
204 }
205 }
207 {
209 {
211 }
212 }
215 }
217 bool
219 {
220 /* Тип Tb есть расширение типа Ta (Ta есть базовый тип Tb) если */
221 /* 1. Ta и Tb - одинаковые типы, или */
222 /* 2. Tb - непосредственное расширение типа, являющегося расширением Ta */
223 /* Если Pa = POINTER TO Ta и Pb = POINTER TO Tb, то Pb есть расширение Pa */
224 /* (Pa есть базовый тип Pb), если Tb есть расширение Ta. */
227 {
230 }
233 {
235 }
238 {
240 }
243 {
245 {
247 }
249 }
252 }
254 bool
256 {
257 return e -> result -> class == OBERON_TYPE_STRING && e -> is_item && e -> item.mode == MODE_STRING;
258 }
260 bool
262 {
263 /* Выражение e типа Te совместимо по присваиванию с переменной v типа Tv, */
264 /* если выполнено одно из следующих условий: */
265 /* 1. Te и Tv - одинаковые типы; */
266 /* 2. Te и Tv - числовые типы и Tv поглощает Te; */
267 /* 3. Te и Tv - типы запись, Te есть расширение Tv, а v имеет динамический тип Tv; */
268 /* 4. Te и Tv - типы указатель и Te - расширение Tv; */
269 /* 5. Tv - тип указатель или процедурный тип, а e - NIL; */
270 /* 6. Tv - ARRAY n OF CHAR, e - строковая константа из m символов и m < n; */
271 /* 7. Tv - процедурный тип, а e - имя процедуры, чьи формальные параметры */
272 /* совпадают с параметрами Tv. */
273 /* Доп: Tv - символ, е - строковая константа из одного символа */
277 /*
278 printf("<<< oberon_is_assignment_compatible_expressions ===\n");
279 printf(": Te -> class == %i\n", Te -> class);
280 printf(": Tv -> class == %i\n", Tv -> class);
281 printf(":: oberon_is_some_types(Te, Tv) == %i\n", oberon_is_some_types(Te, Tv));
282 printf("::: oberon_is_number_type(Te) == %i\n", oberon_is_number_type(Te));
283 printf("::: oberon_is_number_type(Tv) == %i\n", oberon_is_number_type(Tv));
284 printf("::: oberon_incluses_type(Tv, Te) == %i\n", oberon_incluses_type(Tv, Te));
285 printf(":::: oberon_is_record_type(Te) == %i\n", oberon_is_record_type(Te));
286 printf(":::: oberon_is_record_type(Tv) == %i\n", oberon_is_record_type(Tv));
287 // printf(":::: oberon_extension_of(Te, Tv) == %i\n", oberon_extension_of(Te, Tv));
288 printf(":::: oberon_extension_of(Tv, Te) == %i\n", oberon_extension_of(Tv, Te));
289 printf("=== oberon_is_assignment_compatible_expressions >>>\n");
290 */
297 || (oberon_is_array_of_char_type(Tv) && !oberon_is_open_array(Tv) && oberon_is_const_string(e) && (strlen(e -> item.string) < Tv -> size))
298 || (oberon_is_procedure_type(Tv) && e -> is_item && e -> item.var -> class == OBERON_CLASS_PROC && oberon_is_some_procedure_signatures(Tv, e -> result))
300 }
302 static bool
304 {
305 /* Фактический параметр a типа Ta является совместимым массивом для формального параметра f типа Tf если */
306 /* 1. Tf и Ta - одинаковые типы или */
307 /* 2. Tf - открытый массив, Ta - любой массив, а типы их элементов - совместимые массивы или */
308 /* 3. f - параметр-значение типа ARRAY OF CHAR, а фактический параметр a - строка. */
311 || (oberon_is_open_array(Tf) && oberon_is_array_type(Ta) && oberon_is_compatible_arrays_types(Tf -> base, Ta -> base));
312 }
314 bool
316 {
322 }
324 void
326 {
328 {
330 }
331 }
333 bool
335 {
337 {
339 {
341 }
343 {
345 }
346 }
348 {
350 {
352 }
353 }
355 {
357 {
359 }
360 }
362 {
364 {
366 }
368 {
370 }
373 {
375 }
377 {
379 }
381 {
383 }
384 else if((oberon_is_nil_type(a) || oberon_is_pointer_to_record(a) || oberon_is_procedure_type(a))
386 {
388 }
389 }
391 {
393 {
395 }
397 {
399 }
402 {
404 }
405 }
407 {
409 {
411 }
412 }
414 {
416 {
418 }
419 }
422 }
424 bool
426 {
427 /* Пусть Tf - тип формального параметра f (не открытого массива) */
428 /* и Ta - тип соответствующего фактического параметра a. */
429 /* Для параметров-переменных Ta и Tf должны быть одинаковыми типами */
430 /* или Tf должен быть типом запись, а Ta - расширением Tf. */
434 }
436 void
437 oberon_check_compatible_var_param(oberon_context_t * ctx, oberon_type_t * Tf, oberon_type_t * Ta)
438 {
440 {
442 }
443 }
445 void
447 {
449 {
451 }
452 }
454 void
455 oberon_check_compatible_bin_expr_types(oberon_context_t * ctx, int token, oberon_type_t * a, oberon_type_t * b)
456 {
458 {
460 }
461 }
463 void
464 oberon_check_assignment_compatible(oberon_context_t * ctx, oberon_expr_t * e, oberon_type_t * Tv)
465 {
467 {
469 }
470 }
472 void
474 {
476 {
478 }
479 }
481 oberon_type_t *
483 {
485 {
487 }
488 else
489 {
491 }
492 }
494 oberon_type_t *
496 {
499 {
501 }
502 else
503 {
505 }
506 }