DEADSOFTWARE

Добавлен автокаст строки единичного размера в символ
[dsw-obn.git] / src / oberon.c
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>
10 #include "../include/oberon.h"
12 #include "oberon-internals.h"
13 #include "generator.h"
15 enum {
16 EOF_ = 0,
17 IDENT,
18 MODULE,
19 SEMICOLON,
20 END,
21 DOT,
22 VAR,
23 COLON,
24 BEGIN,
25 ASSIGN,
26 INTEGER,
27 TRUE,
28 FALSE,
29 LPAREN,
30 RPAREN,
31 EQUAL,
32 NEQ,
33 LESS,
34 LEQ,
35 GREAT,
36 GEQ,
37 IN,
38 IS,
39 PLUS,
40 MINUS,
41 OR,
42 STAR,
43 SLASH,
44 DIV,
45 MOD,
46 AND,
47 NOT,
48 PROCEDURE,
49 COMMA,
50 RETURN,
51 CONST,
52 TYPE,
53 ARRAY,
54 OF,
55 LBRACK,
56 RBRACK,
57 RECORD,
58 POINTER,
59 TO,
60 UPARROW,
61 NIL,
62 IMPORT,
63 REAL,
64 CHAR,
65 STRING,
66 IF,
67 THEN,
68 ELSE,
69 ELSIF,
70 WHILE,
71 DO,
72 REPEAT,
73 UNTIL,
74 FOR,
75 BY,
76 LOOP,
77 EXIT,
78 LBRACE,
79 RBRACE,
80 DOTDOT,
81 CASE,
82 BAR,
83 WITH
84 };
86 // =======================================================================
87 // UTILS
88 // =======================================================================
90 static void
91 oberon_error(oberon_context_t * ctx, const char * fmt, ...)
92 {
93 va_list ptr;
94 va_start(ptr, fmt);
95 fprintf(stderr, "error: ");
96 vfprintf(stderr, fmt, ptr);
97 fprintf(stderr, "\n");
98 fprintf(stderr, " code_index = %i\n", ctx -> code_index);
99 fprintf(stderr, " c = %c\n", ctx -> c);
100 fprintf(stderr, " token = %i\n", ctx -> token);
101 va_end(ptr);
102 exit(1);
105 static oberon_type_t *
106 oberon_new_type_ptr(int class)
108 oberon_type_t * x = malloc(sizeof *x);
109 memset(x, 0, sizeof *x);
110 x -> class = class;
111 return x;
114 static oberon_type_t *
115 oberon_new_type_integer(int size)
117 oberon_type_t * x;
118 x = oberon_new_type_ptr(OBERON_TYPE_INTEGER);
119 x -> size = size;
120 return x;
123 static oberon_type_t *
124 oberon_new_type_boolean()
126 oberon_type_t * x;
127 x = oberon_new_type_ptr(OBERON_TYPE_BOOLEAN);
128 return x;
131 static oberon_type_t *
132 oberon_new_type_real(int size)
134 oberon_type_t * x;
135 x = oberon_new_type_ptr(OBERON_TYPE_REAL);
136 x -> size = size;
137 return x;
140 static oberon_type_t *
141 oberon_new_type_char(int size)
143 oberon_type_t * x;
144 x = oberon_new_type_ptr(OBERON_TYPE_CHAR);
145 x -> size = size;
146 return x;
149 static oberon_type_t *
150 oberon_new_type_string(int size)
152 oberon_type_t * x;
153 x = oberon_new_type_ptr(OBERON_TYPE_STRING);
154 x -> size = size;
155 return x;
158 static oberon_type_t *
159 oberon_new_type_set(int size)
161 oberon_type_t * x;
162 x = oberon_new_type_ptr(OBERON_TYPE_SET);
163 x -> size = size;
164 return x;
167 // =======================================================================
168 // TABLE
169 // =======================================================================
171 static oberon_scope_t *
172 oberon_open_scope(oberon_context_t * ctx)
174 oberon_scope_t * scope = calloc(1, sizeof *scope);
175 oberon_object_t * list = calloc(1, sizeof *list);
177 scope -> ctx = ctx;
178 scope -> list = list;
179 scope -> up = ctx -> decl;
181 if(scope -> up)
183 scope -> local = scope -> up -> local;
184 scope -> parent = scope -> up -> parent;
185 scope -> parent_type = scope -> up -> parent_type;
186 scope -> exit_label = scope -> up -> exit_label;
189 ctx -> decl = scope;
190 return scope;
193 static void
194 oberon_close_scope(oberon_scope_t * scope)
196 oberon_context_t * ctx = scope -> ctx;
197 ctx -> decl = scope -> up;
200 static oberon_object_t *
201 oberon_find_object_in_list(oberon_object_t * list, char * name)
203 oberon_object_t * x = list;
204 while(x -> next && strcmp(x -> next -> name, name) != 0)
206 x = x -> next;
208 return x -> next;
211 static oberon_object_t *
212 oberon_find_object(oberon_scope_t * scope, char * name, bool check_it)
214 oberon_object_t * result = NULL;
216 oberon_scope_t * s = scope;
217 while(result == NULL && s != NULL)
219 result = oberon_find_object_in_list(s -> list, name);
220 s = s -> up;
223 if(check_it && result == NULL)
225 oberon_error(scope -> ctx, "undefined ident %s", name);
228 return result;
231 static oberon_object_t *
232 oberon_create_object(oberon_scope_t * scope, char * name, int class, bool export, bool read_only)
234 oberon_object_t * newvar = malloc(sizeof *newvar);
235 memset(newvar, 0, sizeof *newvar);
236 newvar -> name = name;
237 newvar -> class = class;
238 newvar -> export = export;
239 newvar -> read_only = read_only;
240 newvar -> local = scope -> local;
241 newvar -> parent = scope -> parent;
242 newvar -> parent_type = scope -> parent_type;
243 newvar -> module = scope -> ctx -> mod;
244 return newvar;
247 static oberon_object_t *
248 oberon_define_object(oberon_scope_t * scope, char * name, int class, bool export, bool read_only, bool check_upscope)
250 if(check_upscope)
252 if(oberon_find_object(scope -> up, name, false))
254 oberon_error(scope -> ctx, "already defined");
258 oberon_object_t * x = scope -> list;
259 while(x -> next && strcmp(x -> next -> name, name) != 0)
261 x = x -> next;
264 if(x -> next)
266 oberon_error(scope -> ctx, "already defined");
269 oberon_object_t * newvar;
270 newvar = oberon_create_object(scope, name, class, export, read_only);
271 x -> next = newvar;
273 return newvar;
276 static oberon_object_t *
277 oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type, int export)
279 oberon_object_t * id;
280 id = oberon_define_object(scope, name, OBERON_CLASS_TYPE, export, false, false);
281 id -> type = type;
282 oberon_generator_init_type(scope -> ctx, type);
283 return id;
286 // =======================================================================
287 // SCANER
288 // =======================================================================
290 static void
291 oberon_get_char(oberon_context_t * ctx)
293 if(ctx -> code[ctx -> code_index])
295 ctx -> code_index += 1;
296 ctx -> c = ctx -> code[ctx -> code_index];
300 static void
301 oberon_init_scaner(oberon_context_t * ctx, const char * code)
303 ctx -> code = code;
304 ctx -> code_index = 0;
305 ctx -> c = ctx -> code[ctx -> code_index];
308 static void
309 oberon_read_ident(oberon_context_t * ctx)
311 int len = 0;
312 int i = ctx -> code_index;
314 int c = ctx -> code[i];
315 while(isalnum(c))
317 i += 1;
318 len += 1;
319 c = ctx -> code[i];
322 char * ident = malloc(len + 1);
323 memcpy(ident, &ctx->code[ctx->code_index], len);
324 ident[len] = 0;
326 ctx -> code_index = i;
327 ctx -> c = ctx -> code[i];
328 ctx -> string = ident;
329 ctx -> token = IDENT;
331 if(strcmp(ident, "MODULE") == 0)
333 ctx -> token = MODULE;
335 else if(strcmp(ident, "END") == 0)
337 ctx -> token = END;
339 else if(strcmp(ident, "VAR") == 0)
341 ctx -> token = VAR;
343 else if(strcmp(ident, "BEGIN") == 0)
345 ctx -> token = BEGIN;
347 else if(strcmp(ident, "TRUE") == 0)
349 ctx -> token = TRUE;
351 else if(strcmp(ident, "FALSE") == 0)
353 ctx -> token = FALSE;
355 else if(strcmp(ident, "OR") == 0)
357 ctx -> token = OR;
359 else if(strcmp(ident, "DIV") == 0)
361 ctx -> token = DIV;
363 else if(strcmp(ident, "MOD") == 0)
365 ctx -> token = MOD;
367 else if(strcmp(ident, "PROCEDURE") == 0)
369 ctx -> token = PROCEDURE;
371 else if(strcmp(ident, "RETURN") == 0)
373 ctx -> token = RETURN;
375 else if(strcmp(ident, "CONST") == 0)
377 ctx -> token = CONST;
379 else if(strcmp(ident, "TYPE") == 0)
381 ctx -> token = TYPE;
383 else if(strcmp(ident, "ARRAY") == 0)
385 ctx -> token = ARRAY;
387 else if(strcmp(ident, "OF") == 0)
389 ctx -> token = OF;
391 else if(strcmp(ident, "RECORD") == 0)
393 ctx -> token = RECORD;
395 else if(strcmp(ident, "POINTER") == 0)
397 ctx -> token = POINTER;
399 else if(strcmp(ident, "TO") == 0)
401 ctx -> token = TO;
403 else if(strcmp(ident, "NIL") == 0)
405 ctx -> token = NIL;
407 else if(strcmp(ident, "IMPORT") == 0)
409 ctx -> token = IMPORT;
411 else if(strcmp(ident, "IN") == 0)
413 ctx -> token = IN;
415 else if(strcmp(ident, "IS") == 0)
417 ctx -> token = IS;
419 else if(strcmp(ident, "IF") == 0)
421 ctx -> token = IF;
423 else if(strcmp(ident, "THEN") == 0)
425 ctx -> token = THEN;
427 else if(strcmp(ident, "ELSE") == 0)
429 ctx -> token = ELSE;
431 else if(strcmp(ident, "ELSIF") == 0)
433 ctx -> token = ELSIF;
435 else if(strcmp(ident, "WHILE") == 0)
437 ctx -> token = WHILE;
439 else if(strcmp(ident, "DO") == 0)
441 ctx -> token = DO;
443 else if(strcmp(ident, "REPEAT") == 0)
445 ctx -> token = REPEAT;
447 else if(strcmp(ident, "UNTIL") == 0)
449 ctx -> token = UNTIL;
451 else if(strcmp(ident, "FOR") == 0)
453 ctx -> token = FOR;
455 else if(strcmp(ident, "BY") == 0)
457 ctx -> token = BY;
459 else if(strcmp(ident, "LOOP") == 0)
461 ctx -> token = LOOP;
463 else if(strcmp(ident, "EXIT") == 0)
465 ctx -> token = EXIT;
467 else if(strcmp(ident, "CASE") == 0)
469 ctx -> token = CASE;
471 else if(strcmp(ident, "WITH") == 0)
473 ctx -> token = WITH;
477 #define ISHEXDIGIT(x) \
478 (((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F'))
480 static void
481 oberon_read_number(oberon_context_t * ctx)
483 long integer;
484 double real;
485 char * ident;
486 int start_i;
487 int exp_i;
488 int end_i;
490 /*
491 * mode = 0 == DEC
492 * mode = 1 == HEX
493 * mode = 2 == REAL
494 * mode = 3 == LONGREAL
495 * mode = 4 == CHAR
496 */
497 int mode = 0;
498 start_i = ctx -> code_index;
500 while(isdigit(ctx -> c))
502 oberon_get_char(ctx);
505 end_i = ctx -> code_index;
507 if(ISHEXDIGIT(ctx -> c))
509 mode = 1;
510 while(ISHEXDIGIT(ctx -> c))
512 oberon_get_char(ctx);
515 end_i = ctx -> code_index;
517 if(ctx -> c == 'H')
519 mode = 1;
520 oberon_get_char(ctx);
522 else if(ctx -> c == 'X')
524 mode = 4;
525 oberon_get_char(ctx);
527 else
529 oberon_error(ctx, "invalid hex number");
532 else if(ctx -> c == '.')
534 oberon_get_char(ctx);
535 if(ctx -> c == '.')
537 /* Чит: избегаем конфликта с DOTDOT */
538 ctx -> code_index -= 1;
540 else
542 mode = 2;
544 while(isdigit(ctx -> c))
546 oberon_get_char(ctx);
549 if(ctx -> c == 'E' || ctx -> c == 'D')
551 exp_i = ctx -> code_index;
553 if(ctx -> c == 'D')
555 mode = 3;
558 oberon_get_char(ctx);
560 if(ctx -> c == '+' || ctx -> c == '-')
562 oberon_get_char(ctx);
565 while(isdigit(ctx -> c))
567 oberon_get_char(ctx);
568 }
571 end_i = ctx -> code_index;
574 if(mode == 0)
576 if(ctx -> c == 'H')
578 mode = 1;
579 oberon_get_char(ctx);
581 else if(ctx -> c == 'X')
583 mode = 4;
584 oberon_get_char(ctx);
588 int len = end_i - start_i;
589 ident = malloc(len + 1);
590 memcpy(ident, &ctx -> code[start_i], len);
591 ident[len] = 0;
593 ctx -> longmode = false;
594 if(mode == 3)
596 int i = exp_i - start_i;
597 ident[i] = 'E';
598 ctx -> longmode = true;
601 switch(mode)
603 case 0:
604 integer = atol(ident);
605 real = integer;
606 ctx -> token = INTEGER;
607 break;
608 case 1:
609 sscanf(ident, "%lx", &integer);
610 real = integer;
611 ctx -> token = INTEGER;
612 break;
613 case 2:
614 case 3:
615 sscanf(ident, "%lf", &real);
616 ctx -> token = REAL;
617 break;
618 case 4:
619 sscanf(ident, "%lx", &integer);
620 real = integer;
621 ctx -> token = CHAR;
622 break;
623 default:
624 oberon_error(ctx, "oberon_read_number: wat");
625 break;
628 ctx -> string = ident;
629 ctx -> integer = integer;
630 ctx -> real = real;
633 static void
634 oberon_skip_space(oberon_context_t * ctx)
636 while(isspace(ctx -> c))
638 oberon_get_char(ctx);
642 static void
643 oberon_read_comment(oberon_context_t * ctx)
645 int nesting = 1;
646 while(nesting >= 1)
648 if(ctx -> c == '(')
650 oberon_get_char(ctx);
651 if(ctx -> c == '*')
653 oberon_get_char(ctx);
654 nesting += 1;
657 else if(ctx -> c == '*')
659 oberon_get_char(ctx);
660 if(ctx -> c == ')')
662 oberon_get_char(ctx);
663 nesting -= 1;
666 else if(ctx -> c == 0)
668 oberon_error(ctx, "unterminated comment");
670 else
672 oberon_get_char(ctx);
677 static void oberon_read_string(oberon_context_t * ctx)
679 int c = ctx -> c;
680 oberon_get_char(ctx);
682 int start = ctx -> code_index;
684 while(ctx -> c != 0 && ctx -> c != c)
686 oberon_get_char(ctx);
689 if(ctx -> c == 0)
691 oberon_error(ctx, "unterminated string");
694 int end = ctx -> code_index;
696 oberon_get_char(ctx);
698 char * string = calloc(1, end - start + 1);
699 strncpy(string, &ctx -> code[start], end - start);
701 ctx -> token = STRING;
702 ctx -> string = string;
704 printf("oberon_read_string: string ((%s))\n", string);
707 static void oberon_read_token(oberon_context_t * ctx);
709 static void
710 oberon_read_symbol(oberon_context_t * ctx)
712 int c = ctx -> c;
713 switch(c)
715 case 0:
716 ctx -> token = EOF_;
717 break;
718 case ';':
719 ctx -> token = SEMICOLON;
720 oberon_get_char(ctx);
721 break;
722 case ':':
723 ctx -> token = COLON;
724 oberon_get_char(ctx);
725 if(ctx -> c == '=')
727 ctx -> token = ASSIGN;
728 oberon_get_char(ctx);
730 break;
731 case '.':
732 ctx -> token = DOT;
733 oberon_get_char(ctx);
734 if(ctx -> c == '.')
736 ctx -> token = DOTDOT;
737 oberon_get_char(ctx);
739 break;
740 case '(':
741 ctx -> token = LPAREN;
742 oberon_get_char(ctx);
743 if(ctx -> c == '*')
745 oberon_get_char(ctx);
746 oberon_read_comment(ctx);
747 oberon_read_token(ctx);
749 break;
750 case ')':
751 ctx -> token = RPAREN;
752 oberon_get_char(ctx);
753 break;
754 case '=':
755 ctx -> token = EQUAL;
756 oberon_get_char(ctx);
757 break;
758 case '#':
759 ctx -> token = NEQ;
760 oberon_get_char(ctx);
761 break;
762 case '<':
763 ctx -> token = LESS;
764 oberon_get_char(ctx);
765 if(ctx -> c == '=')
767 ctx -> token = LEQ;
768 oberon_get_char(ctx);
770 break;
771 case '>':
772 ctx -> token = GREAT;
773 oberon_get_char(ctx);
774 if(ctx -> c == '=')
776 ctx -> token = GEQ;
777 oberon_get_char(ctx);
779 break;
780 case '+':
781 ctx -> token = PLUS;
782 oberon_get_char(ctx);
783 break;
784 case '-':
785 ctx -> token = MINUS;
786 oberon_get_char(ctx);
787 break;
788 case '*':
789 ctx -> token = STAR;
790 oberon_get_char(ctx);
791 if(ctx -> c == ')')
793 oberon_get_char(ctx);
794 oberon_error(ctx, "unstarted comment");
796 break;
797 case '/':
798 ctx -> token = SLASH;
799 oberon_get_char(ctx);
800 break;
801 case '&':
802 ctx -> token = AND;
803 oberon_get_char(ctx);
804 break;
805 case '~':
806 ctx -> token = NOT;
807 oberon_get_char(ctx);
808 break;
809 case ',':
810 ctx -> token = COMMA;
811 oberon_get_char(ctx);
812 break;
813 case '[':
814 ctx -> token = LBRACK;
815 oberon_get_char(ctx);
816 break;
817 case ']':
818 ctx -> token = RBRACK;
819 oberon_get_char(ctx);
820 break;
821 case '^':
822 ctx -> token = UPARROW;
823 oberon_get_char(ctx);
824 break;
825 case '"':
826 oberon_read_string(ctx);
827 break;
828 case '\'':
829 oberon_read_string(ctx);
830 break;
831 case '{':
832 ctx -> token = LBRACE;
833 oberon_get_char(ctx);
834 break;
835 case '}':
836 ctx -> token = RBRACE;
837 oberon_get_char(ctx);
838 break;
839 case '|':
840 ctx -> token = BAR;
841 oberon_get_char(ctx);
842 break;
843 default:
844 oberon_error(ctx, "invalid char %c", ctx -> c);
845 break;
849 static void
850 oberon_read_token(oberon_context_t * ctx)
852 oberon_skip_space(ctx);
854 int c = ctx -> c;
855 if(isalpha(c))
857 oberon_read_ident(ctx);
859 else if(isdigit(c))
861 oberon_read_number(ctx);
863 else
865 oberon_read_symbol(ctx);
869 // =======================================================================
870 // EXPRESSION
871 // =======================================================================
873 static void oberon_expect_token(oberon_context_t * ctx, int token);
874 static oberon_expr_t * oberon_expr(oberon_context_t * ctx);
875 static void oberon_assert_token(oberon_context_t * ctx, int token);
876 static char * oberon_assert_ident(oberon_context_t * ctx);
877 static void oberon_type(oberon_context_t * ctx, oberon_type_t ** type);
878 static oberon_item_t * oberon_const_expr(oberon_context_t * ctx);
879 static oberon_expr_t * oberno_make_dereferencing(oberon_context_t * ctx, oberon_expr_t * expr);
881 static oberon_expr_t *
882 oberon_new_operator(int op, oberon_type_t * result, oberon_expr_t * left, oberon_expr_t * right)
884 oberon_oper_t * operator;
885 operator = malloc(sizeof *operator);
886 memset(operator, 0, sizeof *operator);
888 operator -> is_item = 0;
889 operator -> result = result;
890 operator -> read_only = 1;
891 operator -> op = op;
892 operator -> left = left;
893 operator -> right = right;
895 return (oberon_expr_t *) operator;
898 static oberon_expr_t *
899 oberon_new_item(int mode, oberon_type_t * result, int read_only)
901 oberon_item_t * item;
902 item = malloc(sizeof *item);
903 memset(item, 0, sizeof *item);
905 item -> is_item = 1;
906 item -> result = result;
907 item -> read_only = read_only;
908 item -> mode = mode;
910 return (oberon_expr_t *)item;
913 static oberon_expr_t *
914 oberon_make_unary_op(oberon_context_t * ctx, int token, oberon_expr_t * a)
916 oberon_expr_t * expr;
917 oberon_type_t * result;
919 result = a -> result;
921 if(token == MINUS)
923 if(result -> class == OBERON_TYPE_SET)
925 expr = oberon_new_operator(OP_COMPLEMENTATION, result, a, NULL);
927 else if(result -> class == OBERON_TYPE_INTEGER)
929 expr = oberon_new_operator(OP_UNARY_MINUS, result, a, NULL);
931 else
933 oberon_error(ctx, "incompatible operator type");
936 else if(token == NOT)
938 if(result -> class != OBERON_TYPE_BOOLEAN)
940 oberon_error(ctx, "incompatible operator type");
943 expr = oberon_new_operator(OP_LOGIC_NOT, result, a, NULL);
945 else
947 oberon_error(ctx, "oberon_make_unary_op: wat");
950 return expr;
953 static void
954 oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first, int const_expr)
956 oberon_expr_t * last;
958 *num_expr = 1;
959 if(const_expr)
961 *first = last = (oberon_expr_t *) oberon_const_expr(ctx);
963 else
965 *first = last = oberon_expr(ctx);
967 while(ctx -> token == COMMA)
969 oberon_assert_token(ctx, COMMA);
970 oberon_expr_t * current;
972 if(const_expr)
974 current = (oberon_expr_t *) oberon_const_expr(ctx);
976 else
978 current = oberon_expr(ctx);
981 last -> next = current;
982 last = current;
983 *num_expr += 1;
987 static oberon_expr_t *
988 oberon_cast_expr(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * pref)
990 return oberon_new_operator(OP_CAST, pref, expr, NULL);
993 static oberon_expr_t *
994 oberno_make_record_cast(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * rec)
996 oberon_type_t * from = expr -> result;
997 oberon_type_t * to = rec;
999 printf("oberno_make_record_cast: from class %i to class %i\n", from -> class, to -> class);
1001 if(from -> class == OBERON_TYPE_POINTER && to -> class == OBERON_TYPE_POINTER)
1003 printf("oberno_make_record_cast: pointers\n");
1004 from = from -> base;
1005 to = to -> base;
1008 if(from -> class != OBERON_TYPE_RECORD || to -> class != OBERON_TYPE_RECORD)
1010 oberon_error(ctx, "must be record type");
1013 return oberon_cast_expr(ctx, expr, rec);
1016 static oberon_type_t *
1017 oberon_get_equal_expr_type(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b)
1019 oberon_type_t * result;
1020 if(a -> class == OBERON_TYPE_REAL && b -> class == OBERON_TYPE_INTEGER)
1022 result = a;
1024 else if(b -> class == OBERON_TYPE_REAL && a -> class == OBERON_TYPE_INTEGER)
1026 result = b;
1028 else if(a -> class != b -> class)
1030 oberon_error(ctx, "oberon_get_equal_expr_type: incompatible types");
1032 else if(a -> size > b -> size)
1034 result = a;
1036 else
1038 result = b;
1041 return result;
1044 static void
1045 oberon_check_record_compatibility(oberon_context_t * ctx, oberon_type_t * from, oberon_type_t * to)
1047 if(from -> class == OBERON_TYPE_POINTER && to -> class == OBERON_TYPE_POINTER)
1049 from = from -> base;
1050 to = to -> base;
1053 if(from -> class != OBERON_TYPE_RECORD || to -> class != OBERON_TYPE_RECORD)
1055 oberon_error(ctx, "not a record");
1058 oberon_type_t * t = from;
1059 while(t != NULL && t != to)
1061 t = t -> base;
1064 if(t == NULL)
1066 oberon_error(ctx, "incompatible record types");
1070 static void
1071 oberon_check_dst(oberon_context_t * ctx, oberon_expr_t * dst)
1073 if(dst -> is_item == false)
1075 oberon_error(ctx, "not variable");
1078 switch(dst -> item.mode)
1080 case MODE_VAR:
1081 case MODE_CALL:
1082 case MODE_INDEX:
1083 case MODE_FIELD:
1084 case MODE_DEREF:
1085 case MODE_NEW:
1086 /* accept */
1087 break;
1088 default:
1089 oberon_error(ctx, "not variable");
1090 break;
1094 static void
1095 oberon_check_src(oberon_context_t * ctx, oberon_expr_t * src)
1097 if(src -> is_item)
1099 if(src -> item.mode == MODE_TYPE)
1101 oberon_error(ctx, "not variable");
1106 static oberon_expr_t *
1107 oberon_autocast_to(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * pref)
1109 // Допускается:
1110 // Если классы типов равны
1111 // Если INTEGER переводится в REAL
1112 // Есди STRING переводится в CHAR
1113 // Есди STRING переводится в ARRAY OF CHAR
1115 oberon_check_src(ctx, expr);
1117 bool error = false;
1118 if(pref -> class != expr -> result -> class)
1120 printf("expr class %i\n", expr -> result -> class);
1121 printf("pref class %i\n", pref -> class);
1123 if(expr -> result -> class == OBERON_TYPE_STRING)
1125 if(pref -> class == OBERON_TYPE_CHAR)
1127 if(expr -> is_item && expr -> item.mode == MODE_STRING)
1129 if(strlen(expr -> item.string) != 1)
1131 error = true;
1134 else
1136 error = true;
1139 else if(pref -> class == OBERON_TYPE_ARRAY)
1141 if(pref -> base -> class != OBERON_TYPE_CHAR)
1143 error = true;
1146 else
1148 error = true;
1151 else if(expr -> result -> class == OBERON_TYPE_INTEGER)
1153 if(pref -> class != OBERON_TYPE_REAL)
1155 error = true;
1158 else
1160 error = true;
1164 if(error)
1166 oberon_error(ctx, "oberon_autocast_to: incompatible types");
1169 if(pref -> class == OBERON_TYPE_CHAR)
1171 if(expr -> result -> class == OBERON_TYPE_STRING)
1173 int c = expr -> item.string[0];
1174 expr = oberon_new_item(MODE_CHAR, ctx -> char_type, true);
1175 expr -> item.integer = c;
1178 else if(pref -> class == OBERON_TYPE_INTEGER || pref -> class == OBERON_TYPE_REAL)
1180 if(expr -> result -> size > pref -> size)
1182 oberon_error(ctx, "incompatible size");
1184 else
1186 expr = oberon_cast_expr(ctx, expr, pref);
1189 else if(pref -> class == OBERON_TYPE_RECORD)
1191 oberon_check_record_compatibility(ctx, expr -> result, pref);
1192 expr = oberno_make_record_cast(ctx, expr, pref);
1194 else if(pref -> class == OBERON_TYPE_POINTER)
1196 assert(pref -> base);
1197 if(expr -> result -> base -> class == OBERON_TYPE_RECORD)
1199 oberon_check_record_compatibility(ctx, expr -> result, pref);
1200 expr = oberno_make_record_cast(ctx, expr, pref);
1202 else if(expr -> result -> base != pref -> base)
1204 if(expr -> result -> base -> class != OBERON_TYPE_VOID)
1206 oberon_error(ctx, "incompatible pointer types");
1211 return expr;
1214 static void
1215 oberon_autocast_binary_op(oberon_context_t * ctx, oberon_expr_t ** ea, oberon_expr_t ** eb)
1217 oberon_type_t * a = (*ea) -> result;
1218 oberon_type_t * b = (*eb) -> result;
1219 oberon_type_t * preq = oberon_get_equal_expr_type(ctx, a, b);
1220 *ea = oberon_autocast_to(ctx, *ea, preq);
1221 *eb = oberon_autocast_to(ctx, *eb, preq);
1224 static void
1225 oberon_autocast_call(oberon_context_t * ctx, oberon_item_t * desig)
1227 if(desig -> mode != MODE_CALL)
1229 oberon_error(ctx, "expected mode CALL");
1232 oberon_type_t * fn = desig -> parent -> result;
1233 int num_args = desig -> num_args;
1234 int num_decl = fn -> num_decl;
1236 if(num_args < num_decl)
1238 oberon_error(ctx, "too few arguments");
1240 else if(num_args > num_decl)
1242 oberon_error(ctx, "too many arguments");
1245 /* Делаем проверку на запись и делаем автокаст */
1246 oberon_expr_t * casted[num_args];
1247 oberon_expr_t * arg = desig -> args;
1248 oberon_object_t * param = fn -> decl;
1249 for(int i = 0; i < num_args; i++)
1251 if(param -> class == OBERON_CLASS_VAR_PARAM)
1253 if(arg -> result != param -> type)
1255 oberon_error(ctx, "incompatible type");
1257 if(arg -> read_only)
1259 oberon_error(ctx, "assign to read-only var");
1261 casted[i] = arg;
1263 else
1265 casted[i] = oberon_autocast_to(ctx, arg, param -> type);
1268 arg = arg -> next;
1269 param = param -> next;
1272 /* Создаём новый список выражений */
1273 if(num_args > 0)
1275 arg = casted[0];
1276 for(int i = 0; i < num_args - 1; i++)
1278 casted[i] -> next = casted[i + 1];
1280 desig -> args = arg;
1284 static oberon_expr_t *
1285 oberon_make_call_func(oberon_context_t * ctx, oberon_item_t * item, int num_args, oberon_expr_t * list_args)
1287 oberon_type_t * signature = item -> result;
1288 if(signature -> class != OBERON_TYPE_PROCEDURE)
1290 oberon_error(ctx, "not a procedure");
1293 oberon_expr_t * call;
1295 if(signature -> sysproc)
1297 if(signature -> genfunc == NULL)
1299 oberon_error(ctx, "not a function-procedure");
1302 call = signature -> genfunc(ctx, num_args, list_args);
1304 else
1306 if(signature -> base -> class == OBERON_TYPE_VOID)
1308 oberon_error(ctx, "attempt to call procedure in expression");
1311 call = oberon_new_item(MODE_CALL, signature -> base, true);
1312 call -> item.parent = item;
1313 call -> item.num_args = num_args;
1314 call -> item.args = list_args;
1315 oberon_autocast_call(ctx, (oberon_item_t *) call);
1318 return call;
1321 static void
1322 oberon_make_call_proc(oberon_context_t * ctx, oberon_item_t * item, int num_args, oberon_expr_t * list_args)
1324 oberon_type_t * signature = item -> result;
1325 if(signature -> class != OBERON_TYPE_PROCEDURE)
1327 oberon_error(ctx, "not a procedure");
1330 oberon_expr_t * call;
1332 if(signature -> sysproc)
1334 if(signature -> genproc == NULL)
1336 oberon_error(ctx, "not a procedure");
1339 signature -> genproc(ctx, num_args, list_args);
1341 else
1343 if(signature -> base -> class != OBERON_TYPE_VOID)
1345 oberon_error(ctx, "attempt to call function as non-typed procedure");
1348 call = oberon_new_item(MODE_CALL, signature -> base, true);
1349 call -> item.parent = item;
1350 call -> item.num_args = num_args;
1351 call -> item.args = list_args;
1352 oberon_autocast_call(ctx, (oberon_item_t *) call);
1353 oberon_generate_call_proc(ctx, call);
1357 #define ISEXPR(x) \
1358 (((x) == PLUS) \
1359 || ((x) == MINUS) \
1360 || ((x) == IDENT) \
1361 || ((x) == INTEGER) \
1362 || ((x) == REAL) \
1363 || ((x) == CHAR) \
1364 || ((x) == STRING) \
1365 || ((x) == NIL) \
1366 || ((x) == LPAREN) \
1367 || ((x) == NOT) \
1368 || ((x) == TRUE) \
1369 || ((x) == FALSE))
1371 static oberon_expr_t *
1372 oberno_make_dereferencing(oberon_context_t * ctx, oberon_expr_t * expr)
1374 printf("oberno_make_dereferencing\n");
1375 if(expr -> result -> class != OBERON_TYPE_POINTER)
1377 oberon_error(ctx, "not a pointer");
1380 assert(expr -> is_item);
1382 oberon_expr_t * selector;
1383 selector = oberon_new_item(MODE_DEREF, expr -> result -> base, expr -> read_only);
1384 selector -> item.parent = (oberon_item_t *) expr;
1386 return selector;
1389 static oberon_expr_t *
1390 oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, oberon_expr_t * index)
1392 if(desig -> result -> class == OBERON_TYPE_POINTER)
1394 desig = oberno_make_dereferencing(ctx, desig);
1397 assert(desig -> is_item);
1399 if(desig -> result -> class != OBERON_TYPE_ARRAY)
1401 oberon_error(ctx, "not array");
1404 oberon_type_t * base;
1405 base = desig -> result -> base;
1407 if(index -> result -> class != OBERON_TYPE_INTEGER)
1409 oberon_error(ctx, "index must be integer");
1412 // Статическая проверка границ массива
1413 if(desig -> result -> size != 0)
1415 if(index -> is_item)
1417 if(index -> item.mode == MODE_INTEGER)
1419 int arr_size = desig -> result -> size;
1420 int index_int = index -> item.integer;
1421 if(index_int < 0 || index_int > arr_size - 1)
1423 oberon_error(ctx, "not in range (dimension size 0..%i)", arr_size - 1);
1429 oberon_expr_t * selector;
1430 selector = oberon_new_item(MODE_INDEX, base, desig -> read_only);
1431 selector -> item.parent = (oberon_item_t *) desig;
1432 selector -> item.num_args = 1;
1433 selector -> item.args = index;
1435 return selector;
1438 static oberon_expr_t *
1439 oberon_make_record_selector(oberon_context_t * ctx, oberon_expr_t * expr, char * name)
1441 if(expr -> result -> class == OBERON_TYPE_POINTER)
1443 expr = oberno_make_dereferencing(ctx, expr);
1446 assert(expr -> is_item);
1448 if(expr -> result -> class != OBERON_TYPE_RECORD)
1450 oberon_error(ctx, "not record");
1453 oberon_type_t * rec = expr -> result;
1455 oberon_object_t * field;
1456 field = oberon_find_object(rec -> scope, name, true);
1458 if(field -> export == 0)
1460 if(field -> module != ctx -> mod)
1462 oberon_error(ctx, "field not exported");
1466 int read_only = 0;
1467 if(field -> read_only)
1469 if(field -> module != ctx -> mod)
1471 read_only = 1;
1475 oberon_expr_t * selector;
1476 selector = oberon_new_item(MODE_FIELD, field -> type, read_only);
1477 selector -> item.var = field;
1478 selector -> item.parent = (oberon_item_t *) expr;
1480 return selector;
1483 #define ISSELECTOR(x) \
1484 (((x) == LBRACK) \
1485 || ((x) == DOT) \
1486 || ((x) == UPARROW) \
1487 || ((x) == LPAREN))
1489 static oberon_object_t *
1490 oberon_qualident(oberon_context_t * ctx, char ** xname, int check)
1492 char * name;
1493 oberon_object_t * x;
1495 name = oberon_assert_ident(ctx);
1496 x = oberon_find_object(ctx -> decl, name, check);
1498 if(x != NULL)
1500 if(x -> class == OBERON_CLASS_MODULE)
1502 oberon_assert_token(ctx, DOT);
1503 name = oberon_assert_ident(ctx);
1504 /* Наличие объектов в левых модулях всегда проверяется */
1505 x = oberon_find_object(x -> module -> decl, name, 1);
1507 if(x -> export == 0)
1509 oberon_error(ctx, "not exported");
1514 if(xname)
1516 *xname = name;
1519 return x;
1522 static oberon_expr_t *
1523 oberon_ident_item(oberon_context_t * ctx, char * name)
1525 bool read_only;
1526 oberon_object_t * x;
1527 oberon_expr_t * expr;
1529 x = oberon_find_object(ctx -> decl, name, true);
1531 read_only = false;
1532 if(x -> class == OBERON_CLASS_CONST || x -> class == OBERON_CLASS_PROC)
1534 read_only = true;
1537 expr = oberon_new_item(MODE_VAR, x -> type, read_only);
1538 expr -> item.var = x;
1539 return expr;
1542 static oberon_expr_t *
1543 oberon_qualident_expr(oberon_context_t * ctx)
1545 oberon_object_t * var;
1546 oberon_expr_t * expr;
1548 var = oberon_qualident(ctx, NULL, 1);
1550 int read_only = 0;
1551 if(var -> read_only)
1553 if(var -> module != ctx -> mod)
1555 read_only = 1;
1559 switch(var -> class)
1561 case OBERON_CLASS_CONST:
1562 // TODO copy value
1563 expr = (oberon_expr_t *) var -> value;
1564 break;
1565 case OBERON_CLASS_TYPE:
1566 expr = oberon_new_item(MODE_TYPE, var -> type, read_only);
1567 break;
1568 case OBERON_CLASS_VAR:
1569 case OBERON_CLASS_VAR_PARAM:
1570 case OBERON_CLASS_PARAM:
1571 expr = oberon_new_item(MODE_VAR, var -> type, read_only);
1572 break;
1573 case OBERON_CLASS_PROC:
1574 expr = oberon_new_item(MODE_VAR, var -> type, true);
1575 break;
1576 default:
1577 oberon_error(ctx, "invalid designator");
1578 break;
1581 expr -> item.var = var;
1583 return expr;
1586 static oberon_expr_t *
1587 oberon_designator(oberon_context_t * ctx)
1589 char * name;
1590 oberon_expr_t * expr;
1592 expr = oberon_qualident_expr(ctx);
1594 while(expr -> result -> class != OBERON_TYPE_PROCEDURE && ISSELECTOR(ctx -> token))
1596 switch(ctx -> token)
1598 case DOT:
1599 oberon_assert_token(ctx, DOT);
1600 name = oberon_assert_ident(ctx);
1601 expr = oberon_make_record_selector(ctx, expr, name);
1602 break;
1603 case LBRACK:
1604 oberon_assert_token(ctx, LBRACK);
1605 int num_indexes = 0;
1606 oberon_expr_t * indexes = NULL;
1607 oberon_expr_list(ctx, &num_indexes, &indexes, 0);
1608 oberon_assert_token(ctx, RBRACK);
1610 for(int i = 0; i < num_indexes; i++)
1612 expr = oberon_make_array_selector(ctx, expr, indexes);
1613 indexes = indexes -> next;
1615 break;
1616 case UPARROW:
1617 oberon_assert_token(ctx, UPARROW);
1618 expr = oberno_make_dereferencing(ctx, expr);
1619 break;
1620 case LPAREN:
1621 oberon_assert_token(ctx, LPAREN);
1622 oberon_object_t * objtype = oberon_qualident(ctx, NULL, 1);
1623 if(objtype -> class != OBERON_CLASS_TYPE)
1625 oberon_error(ctx, "must be type");
1627 oberon_assert_token(ctx, RPAREN);
1628 expr = oberno_make_record_cast(ctx, expr, objtype -> type);
1629 break;
1630 default:
1631 oberon_error(ctx, "oberon_designator: wat");
1632 break;
1636 return expr;
1639 static oberon_expr_t *
1640 oberon_opt_func_parens(oberon_context_t * ctx, oberon_expr_t * expr)
1642 /* Если есть скобки - значит вызов. Если нет, то передаём указатель. */
1643 if(ctx -> token == LPAREN)
1645 oberon_assert_token(ctx, LPAREN);
1647 int num_args = 0;
1648 oberon_expr_t * arguments = NULL;
1650 if(ISEXPR(ctx -> token))
1652 oberon_expr_list(ctx, &num_args, &arguments, 0);
1655 assert(expr -> is_item == 1);
1656 expr = oberon_make_call_func(ctx, (oberon_item_t *) expr, num_args, arguments);
1658 oberon_assert_token(ctx, RPAREN);
1661 return expr;
1664 static void
1665 oberon_opt_proc_parens(oberon_context_t * ctx, oberon_expr_t * expr)
1667 assert(expr -> is_item);
1669 int num_args = 0;
1670 oberon_expr_t * arguments = NULL;
1672 if(ctx -> token == LPAREN)
1674 oberon_assert_token(ctx, LPAREN);
1676 if(ISEXPR(ctx -> token))
1678 oberon_expr_list(ctx, &num_args, &arguments, 0);
1681 oberon_assert_token(ctx, RPAREN);
1684 /* Вызов происходит даже без скобок */
1685 oberon_make_call_proc(ctx, (oberon_item_t *) expr, num_args, arguments);
1688 static oberon_type_t *
1689 oberon_get_type_of_int_value(oberon_context_t * ctx, int64_t i)
1691 if(i >= -128 && i <= 127)
1693 return ctx -> byte_type;
1695 else if(i >= -32768 && i <= 32767)
1697 return ctx -> shortint_type;
1699 else if(i >= -2147483648 && i <= 2147483647)
1701 return ctx -> int_type;
1703 else
1705 return ctx -> longint_type;
1709 static oberon_expr_t *
1710 oberon_integer_item(oberon_context_t * ctx, int64_t i)
1712 oberon_expr_t * expr;
1713 oberon_type_t * result;
1714 result = oberon_get_type_of_int_value(ctx, i);
1715 expr = oberon_new_item(MODE_INTEGER, result, true);
1716 expr -> item.integer = i;
1717 return expr;
1720 static oberon_expr_t *
1721 oberon_element(oberon_context_t * ctx)
1723 oberon_expr_t * e1;
1724 oberon_expr_t * e2;
1726 e1 = oberon_expr(ctx);
1727 if(e1 -> result -> class != OBERON_TYPE_INTEGER)
1729 oberon_error(ctx, "expected integer");
1732 e2 = NULL;
1733 if(ctx -> token == DOTDOT)
1735 oberon_assert_token(ctx, DOTDOT);
1736 e2 = oberon_expr(ctx);
1737 if(e2 -> result -> class != OBERON_TYPE_INTEGER)
1739 oberon_error(ctx, "expected integer");
1743 oberon_expr_t * set;
1744 set = oberon_new_operator(OP_RANGE, ctx -> set_type, e1, e2);
1745 return set;
1748 static oberon_expr_t *
1749 oberon_set(oberon_context_t * ctx)
1751 oberon_expr_t * set;
1752 oberon_expr_t * elements;
1753 set = oberon_new_item(MODE_SET, ctx -> set_type, true);
1754 set -> item.integer = 0;
1756 oberon_assert_token(ctx, LBRACE);
1757 if(ISEXPR(ctx -> token))
1759 elements = oberon_element(ctx);
1760 set = oberon_new_operator(OP_UNION, ctx -> set_type, set, elements);
1761 while(ctx -> token == COMMA)
1763 oberon_assert_token(ctx, COMMA);
1764 elements = oberon_element(ctx);
1765 set = oberon_new_operator(OP_UNION, ctx -> set_type, set, elements);
1768 oberon_assert_token(ctx, RBRACE);
1770 return set;
1773 static oberon_expr_t *
1774 oberon_factor(oberon_context_t * ctx)
1776 oberon_expr_t * expr;
1777 oberon_type_t * result;
1779 switch(ctx -> token)
1781 case IDENT:
1782 expr = oberon_designator(ctx);
1783 expr = oberon_opt_func_parens(ctx, expr);
1784 break;
1785 case INTEGER:
1786 expr = oberon_integer_item(ctx, ctx -> integer);
1787 oberon_assert_token(ctx, INTEGER);
1788 break;
1789 case CHAR:
1790 result = ctx -> char_type;
1791 expr = oberon_new_item(MODE_CHAR, result, true);
1792 expr -> item.integer = ctx -> integer;
1793 oberon_assert_token(ctx, CHAR);
1794 break;
1795 case STRING:
1796 result = ctx -> string_type;
1797 expr = oberon_new_item(MODE_STRING, result, true);
1798 expr -> item.string = ctx -> string;
1799 oberon_assert_token(ctx, STRING);
1800 break;
1801 case REAL:
1802 result = (ctx -> longmode) ? (ctx -> longreal_type) : (ctx -> real_type);
1803 expr = oberon_new_item(MODE_REAL, result, 1);
1804 expr -> item.real = ctx -> real;
1805 oberon_assert_token(ctx, REAL);
1806 break;
1807 case TRUE:
1808 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type, true);
1809 expr -> item.boolean = true;
1810 oberon_assert_token(ctx, TRUE);
1811 break;
1812 case FALSE:
1813 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type, true);
1814 expr -> item.boolean = false;
1815 oberon_assert_token(ctx, FALSE);
1816 break;
1817 case LBRACE:
1818 expr = oberon_set(ctx);
1819 break;
1820 case LPAREN:
1821 oberon_assert_token(ctx, LPAREN);
1822 expr = oberon_expr(ctx);
1823 oberon_assert_token(ctx, RPAREN);
1824 break;
1825 case NOT:
1826 oberon_assert_token(ctx, NOT);
1827 expr = oberon_factor(ctx);
1828 expr = oberon_make_unary_op(ctx, NOT, expr);
1829 break;
1830 case NIL:
1831 oberon_assert_token(ctx, NIL);
1832 expr = oberon_new_item(MODE_NIL, ctx -> void_ptr_type, true);
1833 break;
1834 default:
1835 oberon_error(ctx, "invalid expression");
1838 return expr;
1841 #define ITMAKESBOOLEAN(x) \
1842 (((x) >= EQUAL && (x) <= GEQ) || ((x) == OR) || ((x) == AND))
1844 #define ITUSEONLYINTEGER(x) \
1845 ((x) >= LESS && (x) <= GEQ)
1847 #define ITUSEONLYBOOLEAN(x) \
1848 (((x) == OR) || ((x) == AND))
1850 static void
1851 oberon_autocast_to_real(oberon_context_t * ctx, oberon_expr_t ** e)
1853 oberon_expr_t * expr = *e;
1854 if(expr -> result -> class == OBERON_TYPE_INTEGER)
1856 if(expr -> result -> size <= ctx -> real_type -> size)
1858 *e = oberon_cast_expr(ctx, expr, ctx -> real_type);
1860 else
1862 *e = oberon_cast_expr(ctx, expr, ctx -> longreal_type);
1865 else if(expr -> result -> class != OBERON_TYPE_REAL)
1867 oberon_error(ctx, "required numeric type");
1871 static oberon_expr_t *
1872 oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
1874 oberon_expr_t * expr;
1875 oberon_type_t * result;
1877 bool error = false;
1878 if(token == IN)
1880 if(a -> result -> class != OBERON_TYPE_INTEGER)
1882 oberon_error(ctx, "must be integer");
1885 if(b -> result -> class != OBERON_TYPE_SET)
1887 oberon_error(ctx, "must be set");
1890 result = ctx -> bool_type;
1891 expr = oberon_new_operator(OP_IN, result, a, b);
1893 else if(token == IS)
1895 oberon_type_t * v = a -> result;
1896 if(v -> class == OBERON_TYPE_POINTER)
1898 v = v -> base;
1899 if(v -> class != OBERON_TYPE_RECORD)
1901 oberon_error(ctx, "must be record");
1904 else if(v -> class != OBERON_TYPE_RECORD)
1906 oberon_error(ctx, "must be record");
1907 }
1909 if(b -> is_item == false || b -> item.mode != MODE_TYPE)
1911 oberon_error(ctx, "requires type");
1914 oberon_type_t * t = b -> result;
1915 if(t -> class == OBERON_TYPE_POINTER)
1917 t = t -> base;
1918 if(t -> class != OBERON_TYPE_RECORD)
1920 oberon_error(ctx, "must be record");
1923 else if(t -> class != OBERON_TYPE_RECORD)
1925 oberon_error(ctx, "must be record");
1928 result = ctx -> bool_type;
1929 expr = oberon_new_operator(OP_IS, result, a, b);
1931 else if(ITMAKESBOOLEAN(token))
1933 if(ITUSEONLYINTEGER(token))
1935 if(a -> result -> class == OBERON_TYPE_INTEGER
1936 || b -> result -> class == OBERON_TYPE_INTEGER
1937 || a -> result -> class == OBERON_TYPE_REAL
1938 || b -> result -> class == OBERON_TYPE_REAL)
1940 // accept
1942 else
1944 oberon_error(ctx, "used only with numeric types");
1947 else if(ITUSEONLYBOOLEAN(token))
1949 if(a -> result -> class != OBERON_TYPE_BOOLEAN
1950 || b -> result -> class != OBERON_TYPE_BOOLEAN)
1952 oberon_error(ctx, "used only with boolean type");
1956 oberon_autocast_binary_op(ctx, &a, &b);
1957 result = ctx -> bool_type;
1959 if(token == EQUAL)
1961 expr = oberon_new_operator(OP_EQ, result, a, b);
1963 else if(token == NEQ)
1965 expr = oberon_new_operator(OP_NEQ, result, a, b);
1967 else if(token == LESS)
1969 expr = oberon_new_operator(OP_LSS, result, a, b);
1971 else if(token == LEQ)
1973 expr = oberon_new_operator(OP_LEQ, result, a, b);
1975 else if(token == GREAT)
1977 expr = oberon_new_operator(OP_GRT, result, a, b);
1979 else if(token == GEQ)
1981 expr = oberon_new_operator(OP_GEQ, result, a, b);
1983 else if(token == OR)
1985 expr = oberon_new_operator(OP_LOGIC_OR, result, a, b);
1987 else if(token == AND)
1989 expr = oberon_new_operator(OP_LOGIC_AND, result, a, b);
1991 else
1993 oberon_error(ctx, "oberon_make_bin_op: bool wat");
1996 else if(token == SLASH)
1998 if(a -> result -> class == OBERON_TYPE_SET
1999 || b -> result -> class == OBERON_TYPE_SET)
2001 oberon_autocast_binary_op(ctx, &a, &b);
2002 result = a -> result;
2003 expr = oberon_new_operator(OP_SYM_DIFFERENCE, result, a, b);
2005 else
2007 oberon_autocast_to_real(ctx, &a);
2008 oberon_autocast_to_real(ctx, &b);
2009 oberon_autocast_binary_op(ctx, &a, &b);
2010 result = a -> result;
2011 expr = oberon_new_operator(OP_DIV, result, a, b);
2014 else if(token == DIV)
2016 if(a -> result -> class != OBERON_TYPE_INTEGER
2017 || b -> result -> class != OBERON_TYPE_INTEGER)
2019 oberon_error(ctx, "operator DIV requires integer type");
2022 oberon_autocast_binary_op(ctx, &a, &b);
2023 expr = oberon_new_operator(OP_DIV, a -> result, a, b);
2025 else
2027 oberon_autocast_binary_op(ctx, &a, &b);
2028 result = a -> result;
2029 if(result -> class == OBERON_TYPE_SET)
2031 switch(token)
2033 case PLUS:
2034 expr = oberon_new_operator(OP_UNION, result, a, b);
2035 break;
2036 case MINUS:
2037 expr = oberon_new_operator(OP_DIFFERENCE, result, a, b);
2038 break;
2039 case STAR:
2040 expr = oberon_new_operator(OP_INTERSECTION, result, a, b);
2041 break;
2042 default:
2043 error = true;
2044 break;
2047 else if(result -> class == OBERON_TYPE_INTEGER
2048 || result -> class == OBERON_TYPE_REAL)
2050 switch(token)
2052 case PLUS:
2053 expr = oberon_new_operator(OP_ADD, result, a, b);
2054 break;
2055 case MINUS:
2056 expr = oberon_new_operator(OP_SUB, result, a, b);
2057 break;
2058 case STAR:
2059 expr = oberon_new_operator(OP_MUL, result, a, b);
2060 break;
2061 case MOD:
2062 expr = oberon_new_operator(OP_MOD, result, a, b);
2063 break;
2064 default:
2065 error = true;
2066 break;
2069 else
2071 error = true;
2075 if(error)
2077 oberon_error(ctx, "invalid operation");
2080 return expr;
2083 #define ISMULOP(x) \
2084 ((x) >= STAR && (x) <= AND)
2086 static oberon_expr_t *
2087 oberon_term_expr(oberon_context_t * ctx)
2089 oberon_expr_t * expr;
2091 expr = oberon_factor(ctx);
2092 while(ISMULOP(ctx -> token))
2094 int token = ctx -> token;
2095 oberon_read_token(ctx);
2097 oberon_expr_t * inter = oberon_factor(ctx);
2098 expr = oberon_make_bin_op(ctx, token, expr, inter);
2101 return expr;
2104 #define ISADDOP(x) \
2105 ((x) >= PLUS && (x) <= OR)
2107 static oberon_expr_t *
2108 oberon_simple_expr(oberon_context_t * ctx)
2110 oberon_expr_t * expr;
2112 int minus = 0;
2113 if(ctx -> token == PLUS)
2115 minus = 0;
2116 oberon_assert_token(ctx, PLUS);
2118 else if(ctx -> token == MINUS)
2120 minus = 1;
2121 oberon_assert_token(ctx, MINUS);
2124 expr = oberon_term_expr(ctx);
2126 if(minus)
2128 expr = oberon_make_unary_op(ctx, MINUS, expr);
2131 while(ISADDOP(ctx -> token))
2133 int token = ctx -> token;
2134 oberon_read_token(ctx);
2136 oberon_expr_t * inter = oberon_term_expr(ctx);
2137 expr = oberon_make_bin_op(ctx, token, expr, inter);
2140 return expr;
2143 #define ISRELATION(x) \
2144 ((x) >= EQUAL && (x) <= IS)
2146 static oberon_expr_t *
2147 oberon_expr(oberon_context_t * ctx)
2149 oberon_expr_t * expr;
2151 expr = oberon_simple_expr(ctx);
2152 while(ISRELATION(ctx -> token))
2154 int token = ctx -> token;
2155 oberon_read_token(ctx);
2157 oberon_expr_t * inter = oberon_simple_expr(ctx);
2158 expr = oberon_make_bin_op(ctx, token, expr, inter);
2161 return expr;
2164 static void
2165 oberon_check_const(oberon_context_t * ctx, oberon_expr_t * expr)
2167 if(expr -> is_item == 0)
2169 oberon_error(ctx, "const expression are required");
2172 switch(expr -> item.mode)
2174 case MODE_INTEGER:
2175 case MODE_BOOLEAN:
2176 case MODE_NIL:
2177 case MODE_REAL:
2178 case MODE_CHAR:
2179 case MODE_STRING:
2180 case MODE_TYPE:
2181 /* accept */
2182 break;
2183 default:
2184 oberon_error(ctx, "const expression are required");
2185 break;
2189 static oberon_item_t *
2190 oberon_const_expr(oberon_context_t * ctx)
2192 oberon_expr_t * expr;
2193 expr = oberon_expr(ctx);
2194 oberon_check_const(ctx, expr);
2195 return (oberon_item_t *) expr;
2198 // =======================================================================
2199 // PARSER
2200 // =======================================================================
2202 static void oberon_decl_seq(oberon_context_t * ctx);
2203 static void oberon_statement_seq(oberon_context_t * ctx);
2204 static void oberon_initialize_decl(oberon_context_t * ctx);
2206 static void
2207 oberon_expect_token(oberon_context_t * ctx, int token)
2209 if(ctx -> token != token)
2211 oberon_error(ctx, "unexpected token %i (%i)", ctx -> token, token);
2215 static void
2216 oberon_assert_token(oberon_context_t * ctx, int token)
2218 oberon_expect_token(ctx, token);
2219 oberon_read_token(ctx);
2222 static char *
2223 oberon_assert_ident(oberon_context_t * ctx)
2225 oberon_expect_token(ctx, IDENT);
2226 char * ident = ctx -> string;
2227 oberon_read_token(ctx);
2228 return ident;
2231 static void
2232 oberon_def(oberon_context_t * ctx, int * export, int * read_only)
2234 switch(ctx -> token)
2236 case STAR:
2237 oberon_assert_token(ctx, STAR);
2238 *export = 1;
2239 *read_only = 0;
2240 break;
2241 case MINUS:
2242 oberon_assert_token(ctx, MINUS);
2243 *export = 1;
2244 *read_only = 1;
2245 break;
2246 default:
2247 *export = 0;
2248 *read_only = 0;
2249 break;
2253 static oberon_object_t *
2254 oberon_ident_def(oberon_context_t * ctx, int class, bool check_upscope)
2256 char * name;
2257 int export;
2258 int read_only;
2259 oberon_object_t * x;
2261 name = oberon_assert_ident(ctx);
2262 oberon_def(ctx, &export, &read_only);
2264 x = oberon_define_object(ctx -> decl, name, class, export, read_only, check_upscope);
2265 return x;
2268 static void
2269 oberon_ident_list(oberon_context_t * ctx, int class, bool check_upscope, int * num, oberon_object_t ** list)
2271 *num = 1;
2272 *list = oberon_ident_def(ctx, class, check_upscope);
2273 while(ctx -> token == COMMA)
2275 oberon_assert_token(ctx, COMMA);
2276 oberon_ident_def(ctx, class, check_upscope);
2277 *num += 1;
2281 static void
2282 oberon_var_decl(oberon_context_t * ctx)
2284 int num;
2285 oberon_object_t * list;
2286 oberon_type_t * type;
2287 type = oberon_new_type_ptr(OBERON_TYPE_VOID);
2289 oberon_ident_list(ctx, OBERON_CLASS_VAR, false, &num, &list);
2290 oberon_assert_token(ctx, COLON);
2291 oberon_type(ctx, &type);
2293 oberon_object_t * var = list;
2294 for(int i = 0; i < num; i++)
2296 var -> type = type;
2297 var = var -> next;
2301 static oberon_object_t *
2302 oberon_fp_section(oberon_context_t * ctx, int * num_decl)
2304 int class = OBERON_CLASS_PARAM;
2305 if(ctx -> token == VAR)
2307 oberon_read_token(ctx);
2308 class = OBERON_CLASS_VAR_PARAM;
2311 int num;
2312 oberon_object_t * list;
2313 oberon_ident_list(ctx, class, false, &num, &list);
2315 oberon_assert_token(ctx, COLON);
2317 oberon_type_t * type;
2318 type = oberon_new_type_ptr(OBERON_TYPE_VOID);
2319 oberon_type(ctx, &type);
2321 oberon_object_t * param = list;
2322 for(int i = 0; i < num; i++)
2324 param -> type = type;
2325 param = param -> next;
2328 *num_decl += num;
2329 return list;
2332 #define ISFPSECTION \
2333 ((ctx -> token == VAR) || (ctx -> token == IDENT))
2335 static void
2336 oberon_formal_pars(oberon_context_t * ctx, oberon_type_t * signature)
2338 oberon_assert_token(ctx, LPAREN);
2340 if(ISFPSECTION)
2342 signature -> decl = oberon_fp_section(ctx, &signature -> num_decl);
2343 while(ctx -> token == SEMICOLON)
2345 oberon_assert_token(ctx, SEMICOLON);
2346 oberon_fp_section(ctx, &signature -> num_decl);
2350 oberon_assert_token(ctx, RPAREN);
2352 if(ctx -> token == COLON)
2354 oberon_assert_token(ctx, COLON);
2356 oberon_object_t * typeobj;
2357 typeobj = oberon_qualident(ctx, NULL, 1);
2358 if(typeobj -> class != OBERON_CLASS_TYPE)
2360 oberon_error(ctx, "function result is not type");
2362 signature -> base = typeobj -> type;
2366 static void
2367 oberon_opt_formal_pars(oberon_context_t * ctx, oberon_type_t ** type)
2369 oberon_type_t * signature;
2370 signature = *type;
2371 signature -> class = OBERON_TYPE_PROCEDURE;
2372 signature -> num_decl = 0;
2373 signature -> base = ctx -> void_type;
2374 signature -> decl = NULL;
2376 if(ctx -> token == LPAREN)
2378 oberon_formal_pars(ctx, signature);
2382 static void
2383 oberon_compare_signatures(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b)
2385 if(a -> num_decl != b -> num_decl)
2387 oberon_error(ctx, "number parameters not matched");
2390 int num_param = a -> num_decl;
2391 oberon_object_t * param_a = a -> decl;
2392 oberon_object_t * param_b = b -> decl;
2393 for(int i = 0; i < num_param; i++)
2395 if(strcmp(param_a -> name, param_b -> name) != 0)
2397 oberon_error(ctx, "param %i name not matched", i + 1);
2400 if(param_a -> type != param_b -> type)
2402 oberon_error(ctx, "param %i type not matched", i + 1);
2405 param_a = param_a -> next;
2406 param_b = param_b -> next;
2410 static void
2411 oberon_make_return(oberon_context_t * ctx, oberon_expr_t * expr)
2413 oberon_object_t * proc = ctx -> decl -> parent;
2414 oberon_type_t * result_type = proc -> type -> base;
2416 if(result_type -> class == OBERON_TYPE_VOID)
2418 if(expr != NULL)
2420 oberon_error(ctx, "procedure has no result type");
2423 else
2425 if(expr == NULL)
2427 oberon_error(ctx, "procedure requires expression on result");
2430 expr = oberon_autocast_to(ctx, expr, result_type);
2433 proc -> has_return = 1;
2435 oberon_generate_return(ctx, expr);
2438 static void
2439 oberon_proc_decl_body(oberon_context_t * ctx, oberon_object_t * proc)
2441 oberon_assert_token(ctx, SEMICOLON);
2443 ctx -> decl = proc -> scope;
2445 oberon_decl_seq(ctx);
2447 oberon_generate_begin_proc(ctx, proc);
2449 if(ctx -> token == BEGIN)
2451 oberon_assert_token(ctx, BEGIN);
2452 oberon_statement_seq(ctx);
2455 oberon_assert_token(ctx, END);
2456 char * name = oberon_assert_ident(ctx);
2457 if(strcmp(name, proc -> name) != 0)
2459 oberon_error(ctx, "procedure name not matched");
2462 if(proc -> type -> base -> class == OBERON_TYPE_VOID
2463 && proc -> has_return == 0)
2465 oberon_make_return(ctx, NULL);
2468 if(proc -> has_return == 0)
2470 oberon_error(ctx, "procedure requires return");
2473 oberon_generate_end_proc(ctx);
2474 oberon_close_scope(ctx -> decl);
2477 static void
2478 oberon_proc_decl(oberon_context_t * ctx)
2480 oberon_assert_token(ctx, PROCEDURE);
2482 int forward = 0;
2483 if(ctx -> token == UPARROW)
2485 oberon_assert_token(ctx, UPARROW);
2486 forward = 1;
2489 char * name;
2490 int export;
2491 int read_only;
2492 name = oberon_assert_ident(ctx);
2493 oberon_def(ctx, &export, &read_only);
2495 oberon_scope_t * proc_scope;
2496 proc_scope = oberon_open_scope(ctx);
2497 ctx -> decl -> local = 1;
2499 oberon_type_t * signature;
2500 signature = oberon_new_type_ptr(OBERON_TYPE_VOID);
2501 oberon_opt_formal_pars(ctx, &signature);
2503 //oberon_initialize_decl(ctx);
2504 oberon_generator_init_type(ctx, signature);
2505 oberon_close_scope(ctx -> decl);
2507 oberon_object_t * proc;
2508 proc = oberon_find_object(ctx -> decl, name, 0);
2509 if(proc == NULL)
2511 proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, export, read_only, false);
2512 proc -> type = signature;
2513 proc -> scope = proc_scope;
2514 oberon_generator_init_proc(ctx, proc);
2516 else
2518 if(proc -> class != OBERON_CLASS_PROC)
2520 oberon_error(ctx, "mult definition");
2523 if(forward == 0)
2525 if(proc -> linked)
2527 oberon_error(ctx, "mult procedure definition");
2531 if(proc -> export != export || proc -> read_only != read_only)
2533 oberon_error(ctx, "export type not matched");
2536 oberon_compare_signatures(ctx, proc -> type, signature);
2539 proc_scope -> parent = proc;
2540 oberon_object_t * param = proc_scope -> list -> next;
2541 while(param)
2543 param -> parent = proc;
2544 param = param -> next;
2547 if(forward == 0)
2549 proc -> linked = 1;
2550 oberon_proc_decl_body(ctx, proc);
2554 static void
2555 oberon_const_decl(oberon_context_t * ctx)
2557 oberon_item_t * value;
2558 oberon_object_t * constant;
2560 constant = oberon_ident_def(ctx, OBERON_CLASS_CONST, false);
2561 oberon_assert_token(ctx, EQUAL);
2562 value = oberon_const_expr(ctx);
2563 constant -> value = value;
2566 static void
2567 oberon_make_array_type(oberon_context_t * ctx, oberon_expr_t * size, oberon_type_t * base, oberon_type_t ** type)
2569 if(size -> is_item == 0)
2571 oberon_error(ctx, "requires constant");
2574 if(size -> item.mode != MODE_INTEGER)
2576 oberon_error(ctx, "requires integer constant");
2579 oberon_type_t * arr;
2580 arr = *type;
2581 arr -> class = OBERON_TYPE_ARRAY;
2582 arr -> size = size -> item.integer;
2583 arr -> base = base;
2586 static void
2587 oberon_qualident_type(oberon_context_t * ctx, oberon_type_t ** type)
2589 char * name;
2590 oberon_object_t * to;
2592 to = oberon_qualident(ctx, &name, 0);
2594 //name = oberon_assert_ident(ctx);
2595 //to = oberon_find_object(ctx -> decl, name, 0);
2597 if(to != NULL)
2599 if(to -> class != OBERON_CLASS_TYPE)
2601 oberon_error(ctx, "not a type");
2604 else
2606 to = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, false, false, false);
2607 to -> type = oberon_new_type_ptr(OBERON_TYPE_VOID);
2610 *type = to -> type;
2613 static void oberon_opt_formal_pars(oberon_context_t * ctx, oberon_type_t ** type);
2615 /*
2616 * Правило граматики "type". Указатель type должен указывать на существующий объект!
2617 */
2619 static void
2620 oberon_make_multiarray(oberon_context_t * ctx, oberon_expr_t * sizes, oberon_type_t * base, oberon_type_t ** type)
2622 if(sizes == NULL)
2624 *type = base;
2625 return;
2628 oberon_type_t * dim;
2629 dim = oberon_new_type_ptr(OBERON_TYPE_VOID);
2631 oberon_make_multiarray(ctx, sizes -> next, base, &dim);
2633 oberon_make_array_type(ctx, sizes, dim, type);
2636 static void
2637 oberon_make_open_array(oberon_context_t * ctx, oberon_type_t * base, oberon_type_t * type)
2639 type -> class = OBERON_TYPE_ARRAY;
2640 type -> size = 0;
2641 type -> base = base;
2644 static void
2645 oberon_field_list(oberon_context_t * ctx, oberon_type_t * rec, oberon_scope_t * modscope)
2647 if(ctx -> token == IDENT)
2649 int num;
2650 oberon_object_t * list;
2651 oberon_type_t * type;
2652 type = oberon_new_type_ptr(OBERON_TYPE_VOID);
2654 oberon_ident_list(ctx, OBERON_CLASS_FIELD, true, &num, &list);
2655 oberon_assert_token(ctx, COLON);
2657 oberon_scope_t * current = ctx -> decl;
2658 ctx -> decl = modscope;
2659 oberon_type(ctx, &type);
2660 ctx -> decl = current;
2662 oberon_object_t * field = list;
2663 for(int i = 0; i < num; i++)
2665 field -> type = type;
2666 field = field -> next;
2669 rec -> num_decl += num;
2673 static void
2674 oberon_type_record_body(oberon_context_t * ctx, oberon_type_t * rec)
2676 oberon_scope_t * modscope = ctx -> mod -> decl;
2677 oberon_scope_t * oldscope = ctx -> decl;
2678 ctx -> decl = modscope;
2680 if(ctx -> token == LPAREN)
2682 oberon_assert_token(ctx, LPAREN);
2684 oberon_object_t * typeobj;
2685 typeobj = oberon_qualident(ctx, NULL, true);
2687 if(typeobj -> class != OBERON_CLASS_TYPE)
2689 oberon_error(ctx, "base must be type");
2692 oberon_type_t * base = typeobj -> type;
2693 if(base -> class == OBERON_TYPE_POINTER)
2695 base = base -> base;
2698 if(base -> class != OBERON_TYPE_RECORD)
2700 oberon_error(ctx, "base must be record type");
2703 rec -> base = base;
2704 ctx -> decl = base -> scope;
2706 oberon_assert_token(ctx, RPAREN);
2708 else
2710 ctx -> decl = NULL;
2713 oberon_scope_t * this_scope;
2714 this_scope = oberon_open_scope(ctx);
2715 this_scope -> local = true;
2716 this_scope -> parent = NULL;
2717 this_scope -> parent_type = rec;
2719 oberon_field_list(ctx, rec, modscope);
2720 while(ctx -> token == SEMICOLON)
2722 oberon_assert_token(ctx, SEMICOLON);
2723 oberon_field_list(ctx, rec, modscope);
2726 rec -> scope = this_scope;
2727 rec -> decl = this_scope -> list -> next;
2728 ctx -> decl = oldscope;
2731 static void
2732 oberon_type(oberon_context_t * ctx, oberon_type_t ** type)
2734 if(ctx -> token == IDENT)
2736 oberon_qualident_type(ctx, type);
2738 else if(ctx -> token == ARRAY)
2740 oberon_assert_token(ctx, ARRAY);
2742 int num_sizes = 0;
2743 oberon_expr_t * sizes;
2745 if(ISEXPR(ctx -> token))
2747 oberon_expr_list(ctx, &num_sizes, &sizes, 1);
2750 oberon_assert_token(ctx, OF);
2752 oberon_type_t * base;
2753 base = oberon_new_type_ptr(OBERON_TYPE_VOID);
2754 oberon_type(ctx, &base);
2756 if(num_sizes == 0)
2758 oberon_make_open_array(ctx, base, *type);
2760 else
2762 oberon_make_multiarray(ctx, sizes, base, type);
2765 else if(ctx -> token == RECORD)
2767 oberon_type_t * rec;
2768 rec = *type;
2769 rec -> class = OBERON_TYPE_RECORD;
2770 rec -> module = ctx -> mod;
2772 oberon_assert_token(ctx, RECORD);
2773 oberon_type_record_body(ctx, rec);
2774 oberon_assert_token(ctx, END);
2776 *type = rec;
2778 else if(ctx -> token == POINTER)
2780 oberon_assert_token(ctx, POINTER);
2781 oberon_assert_token(ctx, TO);
2783 oberon_type_t * base;
2784 base = oberon_new_type_ptr(OBERON_TYPE_VOID);
2785 oberon_type(ctx, &base);
2787 oberon_type_t * ptr;
2788 ptr = *type;
2789 ptr -> class = OBERON_TYPE_POINTER;
2790 ptr -> base = base;
2792 else if(ctx -> token == PROCEDURE)
2794 oberon_open_scope(ctx);
2795 oberon_assert_token(ctx, PROCEDURE);
2796 oberon_opt_formal_pars(ctx, type);
2797 oberon_close_scope(ctx -> decl);
2799 else
2801 oberon_error(ctx, "invalid type declaration");
2805 static void
2806 oberon_type_decl(oberon_context_t * ctx)
2808 char * name;
2809 oberon_object_t * newtype;
2810 oberon_type_t * type;
2811 int export;
2812 int read_only;
2814 name = oberon_assert_ident(ctx);
2815 oberon_def(ctx, &export, &read_only);
2817 newtype = oberon_find_object(ctx -> decl, name, 0);
2818 if(newtype == NULL)
2820 newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, export, read_only, false);
2821 newtype -> type = oberon_new_type_ptr(OBERON_TYPE_VOID);
2822 assert(newtype -> type);
2824 else
2826 if(newtype -> class != OBERON_CLASS_TYPE)
2828 oberon_error(ctx, "mult definition");
2831 if(newtype -> linked)
2833 oberon_error(ctx, "mult definition - already linked");
2836 newtype -> export = export;
2837 newtype -> read_only = read_only;
2840 oberon_assert_token(ctx, EQUAL);
2842 type = newtype -> type;
2843 oberon_type(ctx, &type);
2845 if(type -> class == OBERON_TYPE_VOID)
2847 oberon_error(ctx, "recursive alias declaration");
2850 newtype -> type = type;
2851 newtype -> linked = 1;
2854 static void oberon_prevent_recursive_object(oberon_context_t * ctx, oberon_object_t * x);
2855 static void oberon_prevent_recursive_type(oberon_context_t * ctx, oberon_type_t * type);
2857 static void
2858 oberon_prevent_recursive_pointer(oberon_context_t * ctx, oberon_type_t * type)
2860 if(type -> class != OBERON_TYPE_POINTER
2861 && type -> class != OBERON_TYPE_ARRAY)
2863 return;
2866 if(type -> recursive)
2868 oberon_error(ctx, "recursive pointer declaration");
2871 if(type -> class == OBERON_TYPE_POINTER
2872 && type -> base -> class == OBERON_TYPE_POINTER)
2874 oberon_error(ctx, "attempt to make pointer to pointer");
2877 type -> recursive = 1;
2879 oberon_prevent_recursive_pointer(ctx, type -> base);
2881 type -> recursive = 0;
2884 static void
2885 oberon_prevent_recursive_record(oberon_context_t * ctx, oberon_type_t * type)
2887 if(type -> class != OBERON_TYPE_RECORD)
2889 return;
2892 if(type -> recursive)
2894 oberon_error(ctx, "recursive record declaration");
2897 type -> recursive = 1;
2899 int num_fields = type -> num_decl;
2900 oberon_object_t * field = type -> decl;
2901 for(int i = 0; i < num_fields; i++)
2903 oberon_prevent_recursive_object(ctx, field);
2904 field = field -> next;
2907 type -> recursive = 0;
2909 static void
2910 oberon_prevent_recursive_procedure(oberon_context_t * ctx, oberon_type_t * type)
2912 if(type -> class != OBERON_TYPE_PROCEDURE)
2914 return;
2917 if(type -> recursive)
2919 oberon_error(ctx, "recursive procedure declaration");
2922 type -> recursive = 1;
2924 int num_fields = type -> num_decl;
2925 oberon_object_t * field = type -> decl;
2926 for(int i = 0; i < num_fields; i++)
2928 oberon_prevent_recursive_object(ctx, field);
2929 field = field -> next;
2932 type -> recursive = 0;
2935 static void
2936 oberon_prevent_recursive_array(oberon_context_t * ctx, oberon_type_t * type)
2938 if(type -> class != OBERON_TYPE_ARRAY)
2940 return;
2943 if(type -> recursive)
2945 oberon_error(ctx, "recursive array declaration");
2948 type -> recursive = 1;
2950 oberon_prevent_recursive_type(ctx, type -> base);
2952 type -> recursive = 0;
2955 static void
2956 oberon_prevent_recursive_type(oberon_context_t * ctx, oberon_type_t * type)
2958 if(type -> class == OBERON_TYPE_POINTER)
2960 oberon_prevent_recursive_pointer(ctx, type);
2962 else if(type -> class == OBERON_TYPE_RECORD)
2964 oberon_prevent_recursive_record(ctx, type);
2966 else if(type -> class == OBERON_TYPE_ARRAY)
2968 oberon_prevent_recursive_array(ctx, type);
2970 else if(type -> class == OBERON_TYPE_PROCEDURE)
2972 oberon_prevent_recursive_procedure(ctx, type);
2976 static void
2977 oberon_prevent_recursive_object(oberon_context_t * ctx, oberon_object_t * x)
2979 switch(x -> class)
2981 case OBERON_CLASS_VAR:
2982 case OBERON_CLASS_TYPE:
2983 case OBERON_CLASS_PARAM:
2984 case OBERON_CLASS_VAR_PARAM:
2985 case OBERON_CLASS_FIELD:
2986 oberon_prevent_recursive_type(ctx, x -> type);
2987 break;
2988 case OBERON_CLASS_CONST:
2989 case OBERON_CLASS_PROC:
2990 case OBERON_CLASS_MODULE:
2991 break;
2992 default:
2993 oberon_error(ctx, "oberon_prevent_recursive_object: wat");
2994 break;
2998 static void
2999 oberon_prevent_recursive_decl(oberon_context_t * ctx)
3001 oberon_object_t * x = ctx -> decl -> list -> next;
3003 while(x)
3005 oberon_prevent_recursive_object(ctx, x);
3006 x = x -> next;
3010 static void oberon_initialize_object(oberon_context_t * ctx, oberon_object_t * x);
3011 static void oberon_initialize_type(oberon_context_t * ctx, oberon_type_t * type);
3013 static void
3014 oberon_initialize_record_fields(oberon_context_t * ctx, oberon_type_t * type)
3016 if(type -> class != OBERON_TYPE_RECORD)
3018 return;
3021 int num_fields = type -> num_decl;
3022 oberon_object_t * field = type -> decl;
3023 for(int i = 0; i < num_fields; i++)
3025 if(field -> type -> class == OBERON_TYPE_POINTER)
3027 oberon_initialize_type(ctx, field -> type);
3030 oberon_initialize_object(ctx, field);
3031 field = field -> next;
3034 oberon_generator_init_record(ctx, type);
3037 static void
3038 oberon_initialize_type(oberon_context_t * ctx, oberon_type_t * type)
3040 if(type -> class == OBERON_TYPE_VOID)
3042 oberon_error(ctx, "undeclarated type");
3045 if(type -> initialized)
3047 return;
3050 type -> initialized = 1;
3052 if(type -> class == OBERON_TYPE_POINTER)
3054 oberon_initialize_type(ctx, type -> base);
3055 oberon_generator_init_type(ctx, type);
3057 else if(type -> class == OBERON_TYPE_ARRAY)
3059 if(type -> size != 0)
3061 if(type -> base -> class == OBERON_TYPE_ARRAY)
3063 if(type -> base -> size == 0)
3065 oberon_error(ctx, "open array not allowed as array element");
3070 oberon_initialize_type(ctx, type -> base);
3071 oberon_generator_init_type(ctx, type);
3073 else if(type -> class == OBERON_TYPE_RECORD)
3075 oberon_generator_init_type(ctx, type);
3076 oberon_initialize_record_fields(ctx, type);
3078 else if(type -> class == OBERON_TYPE_PROCEDURE)
3080 int num_fields = type -> num_decl;
3081 oberon_object_t * field = type -> decl;
3082 for(int i = 0; i < num_fields; i++)
3084 oberon_initialize_object(ctx, field);
3085 field = field -> next;
3086 }
3088 oberon_generator_init_type(ctx, type);
3090 else
3092 oberon_generator_init_type(ctx, type);
3096 static void
3097 oberon_initialize_object(oberon_context_t * ctx, oberon_object_t * x)
3099 if(x -> initialized)
3101 return;
3104 x -> initialized = 1;
3106 switch(x -> class)
3108 case OBERON_CLASS_TYPE:
3109 oberon_initialize_type(ctx, x -> type);
3110 break;
3111 case OBERON_CLASS_VAR:
3112 case OBERON_CLASS_FIELD:
3113 if(x -> type -> class == OBERON_TYPE_ARRAY)
3115 if(x -> type -> size == 0)
3117 oberon_error(ctx, "open array not allowed as variable or field");
3120 oberon_initialize_type(ctx, x -> type);
3121 oberon_generator_init_var(ctx, x);
3122 break;
3123 case OBERON_CLASS_PARAM:
3124 case OBERON_CLASS_VAR_PARAM:
3125 oberon_initialize_type(ctx, x -> type);
3126 oberon_generator_init_var(ctx, x);
3127 break;
3128 case OBERON_CLASS_CONST:
3129 case OBERON_CLASS_PROC:
3130 case OBERON_CLASS_MODULE:
3131 break;
3132 default:
3133 oberon_error(ctx, "oberon_initialize_object: wat");
3134 break;
3138 static void
3139 oberon_initialize_decl(oberon_context_t * ctx)
3141 oberon_object_t * x = ctx -> decl -> list;
3143 while(x -> next)
3145 oberon_initialize_object(ctx, x -> next);
3146 x = x -> next;
3147 }
3150 static void
3151 oberon_prevent_undeclarated_procedures(oberon_context_t * ctx)
3153 oberon_object_t * x = ctx -> decl -> list;
3155 while(x -> next)
3157 if(x -> next -> class == OBERON_CLASS_PROC)
3159 if(x -> next -> linked == 0)
3161 oberon_error(ctx, "unresolved forward declaration");
3164 x = x -> next;
3165 }
3168 static void
3169 oberon_decl_seq(oberon_context_t * ctx)
3171 if(ctx -> token == CONST)
3173 oberon_assert_token(ctx, CONST);
3174 while(ctx -> token == IDENT)
3176 oberon_const_decl(ctx);
3177 oberon_assert_token(ctx, SEMICOLON);
3181 if(ctx -> token == TYPE)
3183 oberon_assert_token(ctx, TYPE);
3184 while(ctx -> token == IDENT)
3186 oberon_type_decl(ctx);
3187 oberon_assert_token(ctx, SEMICOLON);
3191 if(ctx -> token == VAR)
3193 oberon_assert_token(ctx, VAR);
3194 while(ctx -> token == IDENT)
3196 oberon_var_decl(ctx);
3197 oberon_assert_token(ctx, SEMICOLON);
3201 oberon_prevent_recursive_decl(ctx);
3202 oberon_initialize_decl(ctx);
3204 while(ctx -> token == PROCEDURE)
3206 oberon_proc_decl(ctx);
3207 oberon_assert_token(ctx, SEMICOLON);
3210 oberon_prevent_undeclarated_procedures(ctx);
3213 static oberon_expr_t *
3214 oberon_make_temp_var_item(oberon_context_t * ctx, oberon_type_t * type)
3216 oberon_object_t * x;
3217 oberon_expr_t * expr;
3219 x = oberon_create_object(ctx -> decl, "TEMP", OBERON_CLASS_VAR, false, false);
3220 x -> local = true;
3221 x -> type = type;
3222 oberon_generator_init_temp_var(ctx, x);
3224 expr = oberon_new_item(MODE_VAR, type, false);
3225 expr -> item.var = x;
3226 return expr;
3229 static void
3230 oberon_statement_seq(oberon_context_t * ctx);
3232 static void
3233 oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
3235 if(dst -> read_only)
3237 oberon_error(ctx, "read-only destination");
3240 oberon_check_dst(ctx, dst);
3241 src = oberon_autocast_to(ctx, src, dst -> result);
3242 oberon_generate_assign(ctx, src, dst);
3245 static oberon_expr_t *
3246 oberon_case_labels(oberon_context_t * ctx, oberon_expr_t * val)
3248 oberon_expr_t * e1;
3249 oberon_expr_t * e2;
3250 oberon_expr_t * cond;
3251 oberon_expr_t * cond2;
3253 e1 = (oberon_expr_t *) oberon_const_expr(ctx);
3254 oberon_autocast_to(ctx, e1, val -> result);
3256 e2 = NULL;
3257 if(ctx -> token == DOTDOT)
3259 oberon_assert_token(ctx, DOTDOT);
3260 e2 = (oberon_expr_t *) oberon_const_expr(ctx);
3261 oberon_autocast_to(ctx, e2, val -> result);
3264 if(e2 == NULL)
3266 /* val == e1 */
3267 cond = oberon_make_bin_op(ctx, EQUAL, val, e1);
3269 else
3271 /* val >= e1 && val <= e2 */
3272 cond = oberon_make_bin_op(ctx, GEQ, val, e1);
3273 cond2 = oberon_make_bin_op(ctx, LEQ, val, e2);
3274 cond = oberon_make_bin_op(ctx, AND, cond, cond2);
3277 return cond;
3280 static void
3281 oberon_case(oberon_context_t * ctx, oberon_expr_t * val, gen_label_t * end)
3283 oberon_expr_t * cond;
3284 oberon_expr_t * cond2;
3285 gen_label_t * this_end;
3287 if(ISEXPR(ctx -> token))
3289 this_end = oberon_generator_reserve_label(ctx);
3291 cond = oberon_case_labels(ctx, val);
3292 while(ctx -> token == COMMA)
3294 oberon_assert_token(ctx, COMMA);
3295 /* cond || cond2 */
3296 cond2 = oberon_case_labels(ctx, val);
3297 cond = oberon_make_bin_op(ctx, OR, cond, cond2);
3299 oberon_assert_token(ctx, COLON);
3301 oberon_generate_branch(ctx, cond, false, this_end);
3302 oberon_statement_seq(ctx);
3303 oberon_generate_goto(ctx, end);
3305 oberon_generate_label(ctx, this_end);
3309 static void
3310 oberon_case_statement(oberon_context_t * ctx)
3312 oberon_expr_t * val;
3313 oberon_expr_t * expr;
3314 gen_label_t * end;
3316 end = oberon_generator_reserve_label(ctx);
3318 oberon_assert_token(ctx, CASE);
3319 expr = oberon_expr(ctx);
3320 val = oberon_make_temp_var_item(ctx, expr -> result);
3321 oberon_assign(ctx, expr, val);
3322 oberon_assert_token(ctx, OF);
3323 oberon_case(ctx, val, end);
3324 while(ctx -> token == BAR)
3326 oberon_assert_token(ctx, BAR);
3327 oberon_case(ctx, val, end);
3330 if(ctx -> token == ELSE)
3332 oberon_assert_token(ctx, ELSE);
3333 oberon_statement_seq(ctx);
3336 oberon_generate_label(ctx, end);
3337 oberon_assert_token(ctx, END);
3340 static void
3341 oberon_with_guard_do(oberon_context_t * ctx, gen_label_t * end)
3343 oberon_expr_t * val;
3344 oberon_expr_t * var;
3345 oberon_expr_t * type;
3346 oberon_expr_t * cond;
3347 oberon_expr_t * cast;
3348 oberon_type_t * old_type;
3349 gen_var_t * old_var;
3350 gen_label_t * this_end;
3352 this_end = oberon_generator_reserve_label(ctx);
3354 var = oberon_qualident_expr(ctx);
3355 oberon_assert_token(ctx, COLON);
3356 type = oberon_qualident_expr(ctx);
3357 cond = oberon_make_bin_op(ctx, IS, var, type);
3359 oberon_assert_token(ctx, DO);
3360 oberon_generate_branch(ctx, cond, false, this_end);
3362 /* Сохраняем ссылку во временной переменной */
3363 val = oberon_make_temp_var_item(ctx, type -> result);
3364 cast = oberno_make_record_cast(ctx, var, type -> result);
3365 oberon_assign(ctx, cast, val);
3366 /* Подменяем тип у оригинальной переменной */
3367 old_type = var -> item.var -> type;
3368 var -> item.var -> type = type -> result;
3369 /* Подменяем ссылку на переменную */
3370 old_var = var -> item.var -> gen_var;
3371 var -> item.var -> gen_var = val -> item.var -> gen_var;
3373 oberon_statement_seq(ctx);
3374 oberon_generate_goto(ctx, end);
3375 oberon_generate_label(ctx, this_end);
3377 /* Возвращаем исходное состояние */
3378 var -> item.var -> gen_var = old_var;
3379 var -> item.var -> type = old_type;
3382 static void
3383 oberon_with_statement(oberon_context_t * ctx)
3385 gen_label_t * end;
3386 end = oberon_generator_reserve_label(ctx);
3388 oberon_assert_token(ctx, WITH);
3389 oberon_with_guard_do(ctx, end);
3390 while(ctx -> token == BAR)
3392 oberon_assert_token(ctx, BAR);
3393 oberon_with_guard_do(ctx, end);
3396 if(ctx -> token == ELSE)
3398 oberon_assert_token(ctx, ELSE);
3399 oberon_statement_seq(ctx);
3402 oberon_generate_label(ctx, end);
3403 oberon_assert_token(ctx, END);
3406 static void
3407 oberon_statement(oberon_context_t * ctx)
3409 oberon_expr_t * item1;
3410 oberon_expr_t * item2;
3412 if(ctx -> token == IDENT)
3414 item1 = oberon_designator(ctx);
3415 if(ctx -> token == ASSIGN)
3417 oberon_assert_token(ctx, ASSIGN);
3418 item2 = oberon_expr(ctx);
3419 oberon_assign(ctx, item2, item1);
3421 else
3423 oberon_opt_proc_parens(ctx, item1);
3426 else if(ctx -> token == IF)
3428 gen_label_t * end;
3429 gen_label_t * els;
3430 oberon_expr_t * cond;
3432 els = oberon_generator_reserve_label(ctx);
3433 end = oberon_generator_reserve_label(ctx);
3435 oberon_assert_token(ctx, IF);
3436 cond = oberon_expr(ctx);
3437 if(cond -> result -> class != OBERON_TYPE_BOOLEAN)
3439 oberon_error(ctx, "condition must be boolean");
3441 oberon_assert_token(ctx, THEN);
3442 oberon_generate_branch(ctx, cond, false, els);
3443 oberon_statement_seq(ctx);
3444 oberon_generate_goto(ctx, end);
3445 oberon_generate_label(ctx, els);
3447 while(ctx -> token == ELSIF)
3449 els = oberon_generator_reserve_label(ctx);
3451 oberon_assert_token(ctx, ELSIF);
3452 cond = oberon_expr(ctx);
3453 if(cond -> result -> class != OBERON_TYPE_BOOLEAN)
3455 oberon_error(ctx, "condition must be boolean");
3457 oberon_assert_token(ctx, THEN);
3458 oberon_generate_branch(ctx, cond, false, els);
3459 oberon_statement_seq(ctx);
3460 oberon_generate_goto(ctx, end);
3461 oberon_generate_label(ctx, els);
3464 if(ctx -> token == ELSE)
3466 oberon_assert_token(ctx, ELSE);
3467 oberon_statement_seq(ctx);
3470 oberon_generate_label(ctx, end);
3471 oberon_assert_token(ctx, END);
3473 else if(ctx -> token == WHILE)
3475 gen_label_t * begin;
3476 gen_label_t * end;
3477 oberon_expr_t * cond;
3479 begin = oberon_generator_reserve_label(ctx);
3480 end = oberon_generator_reserve_label(ctx);
3482 oberon_assert_token(ctx, WHILE);
3483 oberon_generate_label(ctx, begin);
3484 cond = oberon_expr(ctx);
3485 if(cond -> result -> class != OBERON_TYPE_BOOLEAN)
3487 oberon_error(ctx, "condition must be boolean");
3489 oberon_generate_branch(ctx, cond, false, end);
3491 oberon_assert_token(ctx, DO);
3492 oberon_statement_seq(ctx);
3493 oberon_generate_goto(ctx, begin);
3495 oberon_assert_token(ctx, END);
3496 oberon_generate_label(ctx, end);
3498 else if(ctx -> token == REPEAT)
3500 gen_label_t * begin;
3501 oberon_expr_t * cond;
3503 begin = oberon_generator_reserve_label(ctx);
3504 oberon_generate_label(ctx, begin);
3505 oberon_assert_token(ctx, REPEAT);
3507 oberon_statement_seq(ctx);
3509 oberon_assert_token(ctx, UNTIL);
3511 cond = oberon_expr(ctx);
3512 if(cond -> result -> class != OBERON_TYPE_BOOLEAN)
3514 oberon_error(ctx, "condition must be boolean");
3517 oberon_generate_branch(ctx, cond, true, begin);
3519 else if(ctx -> token == FOR)
3521 oberon_expr_t * from;
3522 oberon_expr_t * index;
3523 oberon_expr_t * to;
3524 oberon_expr_t * bound;
3525 oberon_expr_t * by;
3526 oberon_expr_t * cond;
3527 oberon_expr_t * count;
3528 gen_label_t * begin;
3529 gen_label_t * end;
3530 char * iname;
3531 int op;
3533 begin = oberon_generator_reserve_label(ctx);
3534 end = oberon_generator_reserve_label(ctx);
3536 oberon_assert_token(ctx, FOR);
3537 iname = oberon_assert_ident(ctx);
3538 index = oberon_ident_item(ctx, iname);
3539 oberon_assert_token(ctx, ASSIGN);
3540 from = oberon_expr(ctx);
3541 oberon_assign(ctx, from, index);
3542 oberon_assert_token(ctx, TO);
3543 bound = oberon_make_temp_var_item(ctx, index -> result);
3544 to = oberon_expr(ctx);
3545 oberon_assign(ctx, to, bound);
3546 if(ctx -> token == BY)
3548 oberon_assert_token(ctx, BY);
3549 by = (oberon_expr_t *) oberon_const_expr(ctx);
3551 else
3553 by = oberon_integer_item(ctx, 1);
3556 if(by -> result -> class != OBERON_TYPE_INTEGER)
3558 oberon_error(ctx, "must be integer");
3561 if(by -> item.integer > 0)
3563 op = LEQ;
3565 else if(by -> item.integer < 0)
3567 op = GEQ;
3569 else
3571 oberon_error(ctx, "zero step not allowed");
3574 oberon_assert_token(ctx, DO);
3575 oberon_generate_label(ctx, begin);
3576 cond = oberon_make_bin_op(ctx, op, index, bound);
3577 oberon_generate_branch(ctx, cond, false, end);
3578 oberon_statement_seq(ctx);
3579 count = oberon_make_bin_op(ctx, PLUS, index, by);
3580 oberon_assign(ctx, count, index);
3581 oberon_generate_goto(ctx, begin);
3582 oberon_generate_label(ctx, end);
3583 oberon_assert_token(ctx, END);
3585 else if(ctx -> token == LOOP)
3587 gen_label_t * begin;
3588 gen_label_t * end;
3590 begin = oberon_generator_reserve_label(ctx);
3591 end = oberon_generator_reserve_label(ctx);
3593 oberon_open_scope(ctx);
3594 oberon_assert_token(ctx, LOOP);
3595 oberon_generate_label(ctx, begin);
3596 ctx -> decl -> exit_label = end;
3597 oberon_statement_seq(ctx);
3598 oberon_generate_goto(ctx, begin);
3599 oberon_generate_label(ctx, end);
3600 oberon_assert_token(ctx, END);
3601 oberon_close_scope(ctx -> decl);
3603 else if(ctx -> token == EXIT)
3605 oberon_assert_token(ctx, EXIT);
3606 if(ctx -> decl -> exit_label == NULL)
3608 oberon_error(ctx, "not in LOOP-END");
3610 oberon_generate_goto(ctx, ctx -> decl -> exit_label);
3612 else if(ctx -> token == CASE)
3614 oberon_case_statement(ctx);
3616 else if(ctx -> token == WITH)
3618 oberon_with_statement(ctx);
3620 else if(ctx -> token == RETURN)
3622 oberon_assert_token(ctx, RETURN);
3623 if(ISEXPR(ctx -> token))
3625 oberon_expr_t * expr;
3626 expr = oberon_expr(ctx);
3627 oberon_make_return(ctx, expr);
3629 else
3631 oberon_make_return(ctx, NULL);
3636 static void
3637 oberon_statement_seq(oberon_context_t * ctx)
3639 oberon_statement(ctx);
3640 while(ctx -> token == SEMICOLON)
3642 oberon_assert_token(ctx, SEMICOLON);
3643 oberon_statement(ctx);
3647 static void
3648 oberon_import_module(oberon_context_t * ctx, char * alias, char * name)
3650 oberon_module_t * m = ctx -> module_list;
3651 while(m && strcmp(m -> name, name) != 0)
3653 m = m -> next;
3656 if(m == NULL)
3658 const char * code;
3659 code = ctx -> import_module(name);
3660 if(code == NULL)
3662 oberon_error(ctx, "no such module");
3665 m = oberon_compile_module(ctx, code);
3666 assert(m);
3669 if(m -> ready == 0)
3671 oberon_error(ctx, "cyclic module import");
3674 oberon_object_t * ident;
3675 ident = oberon_define_object(ctx -> decl, alias, OBERON_CLASS_MODULE, false, false, false);
3676 ident -> module = m;
3679 static void
3680 oberon_import_decl(oberon_context_t * ctx)
3682 char * alias;
3683 char * name;
3685 alias = name = oberon_assert_ident(ctx);
3686 if(ctx -> token == ASSIGN)
3688 oberon_assert_token(ctx, ASSIGN);
3689 name = oberon_assert_ident(ctx);
3692 oberon_import_module(ctx, alias, name);
3695 static void
3696 oberon_import_list(oberon_context_t * ctx)
3698 oberon_assert_token(ctx, IMPORT);
3700 oberon_import_decl(ctx);
3701 while(ctx -> token == COMMA)
3703 oberon_assert_token(ctx, COMMA);
3704 oberon_import_decl(ctx);
3707 oberon_assert_token(ctx, SEMICOLON);
3710 static void
3711 oberon_parse_module(oberon_context_t * ctx)
3713 char * name1;
3714 char * name2;
3715 oberon_read_token(ctx);
3717 oberon_assert_token(ctx, MODULE);
3718 name1 = oberon_assert_ident(ctx);
3719 oberon_assert_token(ctx, SEMICOLON);
3720 ctx -> mod -> name = name1;
3722 oberon_generator_init_module(ctx, ctx -> mod);
3724 if(ctx -> token == IMPORT)
3726 oberon_import_list(ctx);
3729 oberon_decl_seq(ctx);
3731 oberon_generate_begin_module(ctx);
3732 if(ctx -> token == BEGIN)
3734 oberon_assert_token(ctx, BEGIN);
3735 oberon_statement_seq(ctx);
3737 oberon_generate_end_module(ctx);
3739 oberon_assert_token(ctx, END);
3740 name2 = oberon_assert_ident(ctx);
3741 oberon_expect_token(ctx, DOT);
3743 if(strcmp(name1, name2) != 0)
3745 oberon_error(ctx, "module name not matched");
3748 oberon_generator_fini_module(ctx -> mod);
3751 // =======================================================================
3752 // LIBRARY
3753 // =======================================================================
3755 static void
3756 register_default_types(oberon_context_t * ctx)
3758 ctx -> void_type = oberon_new_type_ptr(OBERON_TYPE_VOID);
3759 oberon_generator_init_type(ctx, ctx -> void_type);
3761 ctx -> void_ptr_type = oberon_new_type_ptr(OBERON_TYPE_POINTER);
3762 ctx -> void_ptr_type -> base = ctx -> void_type;
3763 oberon_generator_init_type(ctx, ctx -> void_ptr_type);
3765 ctx -> string_type = oberon_new_type_string(1);
3766 oberon_generator_init_type(ctx, ctx -> string_type);
3768 ctx -> bool_type = oberon_new_type_boolean();
3769 oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type, 1);
3771 ctx -> byte_type = oberon_new_type_integer(1);
3772 oberon_define_type(ctx -> world_scope, "BYTE", ctx -> byte_type, 1);
3774 ctx -> shortint_type = oberon_new_type_integer(2);
3775 oberon_define_type(ctx -> world_scope, "SHORTINT", ctx -> shortint_type, 1);
3777 ctx -> int_type = oberon_new_type_integer(4);
3778 oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type, 1);
3780 ctx -> longint_type = oberon_new_type_integer(8);
3781 oberon_define_type(ctx -> world_scope, "LONGINT", ctx -> longint_type, 1);
3783 ctx -> real_type = oberon_new_type_real(4);
3784 oberon_define_type(ctx -> world_scope, "REAL", ctx -> real_type, 1);
3786 ctx -> longreal_type = oberon_new_type_real(8);
3787 oberon_define_type(ctx -> world_scope, "LONGREAL", ctx -> longreal_type, 1);
3789 ctx -> char_type = oberon_new_type_char(1);
3790 oberon_define_type(ctx -> world_scope, "CHAR", ctx -> char_type, 1);
3792 ctx -> set_type = oberon_new_type_set(4);
3793 oberon_define_type(ctx -> world_scope, "SET", ctx -> set_type, 1);
3796 static void
3797 oberon_new_intrinsic(oberon_context_t * ctx, char * name, GenerateFuncCallback f, GenerateProcCallback p)
3799 oberon_object_t * proc;
3800 proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, true, false, false);
3801 proc -> type = oberon_new_type_ptr(OBERON_TYPE_PROCEDURE);
3802 proc -> type -> sysproc = true;
3803 proc -> type -> genfunc = f;
3804 proc -> type -> genproc = p;
3807 static oberon_expr_t *
3808 oberon_make_min_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
3810 if(num_args < 1)
3812 oberon_error(ctx, "too few arguments");
3815 if(num_args > 1)
3817 oberon_error(ctx, "too mach arguments");
3820 oberon_expr_t * arg;
3821 arg = list_args;
3823 if(!arg -> is_item || arg -> item.mode != MODE_TYPE)
3825 oberon_error(ctx, "MIN accept only type");
3828 oberon_expr_t * expr;
3829 int bits = arg -> result -> size * 8;
3830 switch(arg -> result -> class)
3832 case OBERON_TYPE_INTEGER:
3833 expr = oberon_integer_item(ctx, -powl(2, bits - 1));
3834 break;
3835 case OBERON_TYPE_SET:
3836 expr = oberon_integer_item(ctx, 0);
3837 break;
3838 default:
3839 oberon_error(ctx, "allowed only basic types");
3840 break;
3843 return expr;
3846 static oberon_expr_t *
3847 oberon_make_max_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
3849 if(num_args < 1)
3851 oberon_error(ctx, "too few arguments");
3854 if(num_args > 1)
3856 oberon_error(ctx, "too mach arguments");
3859 oberon_expr_t * arg;
3860 arg = list_args;
3862 if(!arg -> is_item || arg -> item.mode != MODE_TYPE)
3864 oberon_error(ctx, "MAX accept only type");
3867 oberon_expr_t * expr;
3868 int bits = arg -> result -> size * 8;
3869 switch(arg -> result -> class)
3871 case OBERON_TYPE_INTEGER:
3872 expr = oberon_integer_item(ctx, powl(2, bits - 1) - 1);
3873 break;
3874 case OBERON_TYPE_SET:
3875 expr = oberon_integer_item(ctx, bits);
3876 break;
3877 default:
3878 oberon_error(ctx, "allowed only basic types");
3879 break;
3882 return expr;
3885 static oberon_expr_t *
3886 oberon_make_size_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
3888 if(num_args < 1)
3890 oberon_error(ctx, "too few arguments");
3893 if(num_args > 1)
3895 oberon_error(ctx, "too mach arguments");
3898 oberon_expr_t * arg;
3899 arg = list_args;
3901 if(!arg -> is_item || arg -> item.mode != MODE_TYPE)
3903 oberon_error(ctx, "SIZE accept only type");
3906 int size;
3907 oberon_expr_t * expr;
3908 oberon_type_t * type = arg -> result;
3909 switch(type -> class)
3911 case OBERON_TYPE_INTEGER:
3912 case OBERON_TYPE_BOOLEAN:
3913 case OBERON_TYPE_REAL:
3914 case OBERON_TYPE_CHAR:
3915 case OBERON_TYPE_SET:
3916 size = type -> size;
3917 break;
3918 default:
3919 oberon_error(ctx, "TODO SIZE");
3920 break;
3923 expr = oberon_integer_item(ctx, size);
3924 return expr;
3927 static oberon_expr_t *
3928 oberon_make_abs_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
3930 if(num_args < 1)
3932 oberon_error(ctx, "too few arguments");
3935 if(num_args > 1)
3937 oberon_error(ctx, "too mach arguments");
3940 oberon_expr_t * arg;
3941 arg = list_args;
3942 oberon_check_src(ctx, arg);
3944 oberon_type_t * result_type;
3945 result_type = arg -> result;
3947 if(result_type -> class != OBERON_TYPE_INTEGER)
3949 oberon_error(ctx, "ABS accepts only integers");
3952 oberon_expr_t * expr;
3953 expr = oberon_new_operator(OP_ABS, result_type, arg, NULL);
3954 return expr;
3957 static void
3958 oberon_make_new_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
3960 if(num_args < 1)
3962 oberon_error(ctx, "too few arguments");
3966 oberon_expr_t * dst;
3967 dst = list_args;
3968 oberon_check_dst(ctx, dst);
3970 oberon_type_t * type;
3971 type = dst -> result;
3973 if(type -> class != OBERON_TYPE_POINTER)
3975 oberon_error(ctx, "not a pointer");
3978 type = type -> base;
3980 oberon_expr_t * src;
3981 src = oberon_new_item(MODE_NEW, dst -> result, 0);
3982 src -> item.num_args = 0;
3983 src -> item.args = NULL;
3985 int max_args = 1;
3986 if(type -> class == OBERON_TYPE_ARRAY)
3988 if(type -> size == 0)
3990 oberon_type_t * x = type;
3991 while(x -> class == OBERON_TYPE_ARRAY)
3993 if(x -> size == 0)
3995 max_args += 1;
3997 x = x -> base;
4001 if(num_args < max_args)
4003 oberon_error(ctx, "too few arguments");
4006 if(num_args > max_args)
4008 oberon_error(ctx, "too mach arguments");
4011 int num_sizes = max_args - 1;
4012 oberon_expr_t * size_list = list_args -> next;
4014 oberon_expr_t * arg = size_list;
4015 for(int i = 0; i < max_args - 1; i++)
4017 oberon_check_src(ctx, arg);
4018 if(arg -> result -> class != OBERON_TYPE_INTEGER)
4020 oberon_error(ctx, "size must be integer");
4022 arg = arg -> next;
4025 src -> item.num_args = num_sizes;
4026 src -> item.args = size_list;
4028 else if(type -> class != OBERON_TYPE_RECORD)
4030 oberon_error(ctx, "oberon_make_new_call: wat");
4033 if(num_args > max_args)
4035 oberon_error(ctx, "too mach arguments");
4038 oberon_assign(ctx, src, dst);
4041 oberon_context_t *
4042 oberon_create_context(ModuleImportCallback import_module)
4044 oberon_context_t * ctx = calloc(1, sizeof *ctx);
4046 oberon_scope_t * world_scope;
4047 world_scope = oberon_open_scope(ctx);
4048 ctx -> world_scope = world_scope;
4050 ctx -> import_module = import_module;
4052 oberon_generator_init_context(ctx);
4054 register_default_types(ctx);
4056 /* Functions */
4057 oberon_new_intrinsic(ctx, "ABS", oberon_make_abs_call, NULL);
4058 oberon_new_intrinsic(ctx, "MIN", oberon_make_min_call, NULL);
4059 oberon_new_intrinsic(ctx, "MAX", oberon_make_max_call, NULL);
4060 oberon_new_intrinsic(ctx, "SIZE", oberon_make_size_call, NULL);
4062 /* Procedures */
4063 oberon_new_intrinsic(ctx, "NEW", NULL, oberon_make_new_call);
4065 return ctx;
4068 void
4069 oberon_destroy_context(oberon_context_t * ctx)
4071 oberon_generator_destroy_context(ctx);
4072 free(ctx);
4075 oberon_module_t *
4076 oberon_compile_module(oberon_context_t * ctx, const char * newcode)
4078 const char * code = ctx -> code;
4079 int code_index = ctx -> code_index;
4080 char c = ctx -> c;
4081 int token = ctx -> token;
4082 char * string = ctx -> string;
4083 int integer = ctx -> integer;
4084 int real = ctx -> real;
4085 bool longmode = ctx -> longmode;
4086 oberon_scope_t * decl = ctx -> decl;
4087 oberon_module_t * mod = ctx -> mod;
4089 oberon_scope_t * module_scope;
4090 module_scope = oberon_open_scope(ctx);
4092 oberon_module_t * module;
4093 module = calloc(1, sizeof *module);
4094 module -> decl = module_scope;
4095 module -> next = ctx -> module_list;
4097 ctx -> mod = module;
4098 ctx -> module_list = module;
4100 oberon_init_scaner(ctx, newcode);
4101 oberon_parse_module(ctx);
4103 module -> ready = 1;
4105 ctx -> code = code;
4106 ctx -> code_index = code_index;
4107 ctx -> c = c;
4108 ctx -> token = token;
4109 ctx -> string = string;
4110 ctx -> integer = integer;
4111 ctx -> real = real;
4112 ctx -> longmode = longmode;
4113 ctx -> decl = decl;
4114 ctx -> mod = mod;
4116 return module;