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 {
46 }
48 bool
50 {
52 }
54 bool
56 {
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 }
115 bool
117 {
119 }
121 bool
123 {
125 }
127 bool
129 {
131 }
135 bool
137 {
138 /* Две переменные a и b с типами Ta и Tb имеют одинаковый тип, если */
139 /* 1. Ta и Tb оба обозначены одним и тем же идентификатором типа, или */
140 /* 2. Ta объявлен равным Tb в объявлении типа вида Ta = Tb, или */
141 /* 3. a и b появляются в одном и том же списке идентификаторов переменных, полей записи */
142 /* или объявлении формальных параметров и не являются открытыми массивами. */
145 }
147 bool
149 {
150 /* Два списка формальных параметров совпадают если */
151 /* 1. они имеют одинаковое количество параметров, и */
152 /* 2. они имеют или одинаковый тип результата функции или не имеют никакого, и */
153 /* 3. параметры в соответствующих позициях имеют равные типы, и */
154 /* 4. параметры в соответствующих позициях - оба или параметры-значения */
155 /* или параметры-переменные. */
158 {
160 }
163 {
165 }
171 {
173 {
175 }
178 {
180 }
184 }
187 }
189 bool
191 {
192 /* Два типа Ta, и Tb равны, если */
193 /* 1. Ta и Tb - одинаковые типы, или */
194 /* 2. Ta и Tb - типы открытый массив с равными типами элементов, или */
195 /* 3. Ta и Tb - процедурные типы, чьи списки формальных параметров совпадают. */
198 || (oberon_is_open_array(a) && oberon_is_open_array(b) && oberon_is_some_types(a -> base, b -> base))
199 || (oberon_is_procedure_type(a) && oberon_is_procedure_type(b) && oberon_is_some_procedure_signatures(a, b));
200 }
202 bool
204 {
205 /* a поглощает b */
206 /* LONGREAL >= REAL >= LONGINT >= INTEGER >= SHORTINT */
208 /*
209 printf("oberon_incluses_type: a %i %i\n", a -> class, a -> size);
210 printf("oberon_incluses_type: b %i %i\n", b -> class, b -> size);
211 */
214 {
216 {
218 }
220 {
222 }
223 }
225 {
227 {
229 }
230 }
233 }
235 bool
237 {
238 /* Тип Tb есть расширение типа Ta (Ta есть базовый тип Tb) если */
239 /* 1. Ta и Tb - одинаковые типы, или */
240 /* 2. Tb - непосредственное расширение типа, являющегося расширением Ta */
241 /* Если Pa = POINTER TO Ta и Pb = POINTER TO Tb, то Pb есть расширение Pa */
242 /* (Pa есть базовый тип Pb), если Tb есть расширение Ta. */
245 {
248 }
251 {
253 }
256 {
258 }
261 {
263 {
265 }
267 }
270 }
272 bool
274 {
275 return e -> result -> class == OBERON_TYPE_STRING && e -> is_item && e -> item.mode == MODE_STRING;
276 }
278 bool
280 {
281 /* Выражение e типа Te совместимо по присваиванию с переменной v типа Tv, */
282 /* если выполнено одно из следующих условий: */
283 /* 1. Te и Tv - одинаковые типы; */
284 /* 2. Te и Tv - числовые типы и Tv поглощает Te; */
285 /* 3. Te и Tv - типы запись, Te есть расширение Tv, а v имеет динамический тип Tv; */
286 /* 4. Te и Tv - типы указатель и Te - расширение Tv; */
287 /* 5. Tv - тип указатель или процедурный тип, а e - NIL; */
288 /* 6. Tv - ARRAY n OF CHAR, e - строковая константа из m символов и m < n; */
289 /* 7. Tv - процедурный тип, а e - имя процедуры, чьи формальные параметры */
290 /* совпадают с параметрами Tv. */
291 /* Доп: Tv - символ, е - строковая константа из одного символа */
293 /* SYSTEM: переменным типа BYTE можно присваивать значения переменных типа CHAR или SHORTINT. */
297 /*
298 printf("<<< oberon_is_assignment_compatible_expressions ===\n");
299 printf(": Te -> class == %i\n", Te -> class);
300 printf(": Tv -> class == %i\n", Tv -> class);
301 printf(":: oberon_is_some_types(Te, Tv) == %i\n", oberon_is_some_types(Te, Tv));
302 printf("::: oberon_is_number_type(Te) == %i\n", oberon_is_number_type(Te));
303 printf("::: oberon_is_number_type(Tv) == %i\n", oberon_is_number_type(Tv));
304 printf("::: oberon_incluses_type(Tv, Te) == %i\n", oberon_incluses_type(Tv, Te));
305 printf(":::: oberon_is_record_type(Te) == %i\n", oberon_is_record_type(Te));
306 printf(":::: oberon_is_record_type(Tv) == %i\n", oberon_is_record_type(Tv));
307 // printf(":::: oberon_extension_of(Te, Tv) == %i\n", oberon_extension_of(Te, Tv));
308 printf(":::: oberon_extension_of(Tv, Te) == %i\n", oberon_extension_of(Tv, Te));
309 printf("=== oberon_is_assignment_compatible_expressions >>>\n");
310 */
317 || (oberon_is_array_of_char_type(Tv) && !oberon_is_open_array(Tv) && oberon_is_const_string(e) && (strlen(e -> item.string) < Tv -> size))
318 || (oberon_is_procedure_type(Tv) && e -> is_item && e -> item.var -> class == OBERON_CLASS_PROC && oberon_is_some_procedure_signatures(Tv, e -> result))
321 }
323 static bool
325 {
326 /* Фактический параметр a типа Ta является совместимым массивом для формального параметра f типа Tf если */
327 /* 1. Tf и Ta - одинаковые типы или */
328 /* 2. Tf - открытый массив, Ta - любой массив, а типы их элементов - совместимые массивы или */
329 /* 3. f - параметр-значение типа ARRAY OF CHAR, а фактический параметр a - строка. */
332 || (oberon_is_open_array(Tf) && oberon_is_array_type(Ta) && oberon_is_compatible_arrays_types(Tf -> base, Ta -> base));
333 }
335 bool
337 {
343 }
345 void
347 {
349 {
351 }
352 }
354 bool
356 {
358 {
360 {
362 }
364 {
366 }
367 }
369 {
371 {
373 }
374 }
376 {
378 {
380 }
381 }
383 {
385 {
387 }
389 {
391 }
394 {
396 }
398 {
400 }
402 {
404 }
405 else if((oberon_is_nil_type(a) || oberon_is_pointer_to_record(a) || oberon_is_procedure_type(a))
407 {
409 }
410 }
412 {
414 {
416 }
418 {
420 }
423 {
425 }
426 }
428 {
430 {
432 }
433 }
435 {
437 {
439 }
440 }
443 }
445 bool
447 {
448 /* Пусть Tf - тип формального параметра f (не открытого массива) */
449 /* и Ta - тип соответствующего фактического параметра a. */
450 /* Для параметров-переменных Ta и Tf должны быть одинаковыми типами */
451 /* или Tf должен быть типом запись, а Ta - расширением Tf. */
453 /* SYSTEM: Если формальный параметр-переменная имеет тип ARRAY OF BYTE, */
454 /* то соответствующий фактический параметр может иметь любой тип. */
459 }
461 void
462 oberon_check_compatible_var_param(oberon_context_t * ctx, oberon_type_t * Tf, oberon_type_t * Ta)
463 {
465 {
467 }
468 }
470 void
472 {
474 {
476 }
477 }
479 void
480 oberon_check_compatible_bin_expr_types(oberon_context_t * ctx, int token, oberon_type_t * a, oberon_type_t * b)
481 {
483 {
485 }
486 }
488 void
489 oberon_check_assignment_compatible(oberon_context_t * ctx, oberon_expr_t * e, oberon_type_t * Tv)
490 {
492 {
494 }
495 }
497 void
499 {
501 {
503 }
504 }
506 oberon_type_t *
508 {
510 {
512 }
513 else
514 {
516 }
517 }
519 oberon_type_t *
521 {
524 {
526 }
527 else
528 {
530 }
531 }