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>
9 #include "../include/oberon.h"
11 #include "oberon-internals.h"
12 #include "generator.h"
14 enum {
15 EOF_ = 0,
16 IDENT,
17 MODULE,
18 SEMICOLON,
19 END,
20 DOT,
21 VAR,
22 COLON,
23 BEGIN,
24 ASSIGN,
25 INTEGER,
26 TRUE,
27 FALSE,
28 LPAREN,
29 RPAREN,
30 EQUAL,
31 NEQ,
32 LESS,
33 LEQ,
34 GREAT,
35 GEQ,
36 IN,
37 IS,
38 PLUS,
39 MINUS,
40 OR,
41 STAR,
42 SLASH,
43 DIV,
44 MOD,
45 AND,
46 NOT,
47 PROCEDURE,
48 COMMA,
49 RETURN,
50 CONST,
51 TYPE,
52 ARRAY,
53 OF,
54 LBRACE,
55 RBRACE,
56 RECORD,
57 POINTER,
58 TO,
59 UPARROW,
60 NIL,
61 IMPORT,
62 REAL,
63 CHAR,
64 STRING
65 };
67 // =======================================================================
68 // UTILS
69 // =======================================================================
71 static void
72 oberon_error(oberon_context_t * ctx, const char * fmt, ...)
73 {
74 va_list ptr;
75 va_start(ptr, fmt);
76 fprintf(stderr, "error: ");
77 vfprintf(stderr, fmt, ptr);
78 fprintf(stderr, "\n");
79 fprintf(stderr, " code_index = %i\n", ctx -> code_index);
80 fprintf(stderr, " c = %c\n", ctx -> c);
81 fprintf(stderr, " token = %i\n", ctx -> token);
82 va_end(ptr);
83 exit(1);
84 }
86 static oberon_type_t *
87 oberon_new_type_ptr(int class)
88 {
89 oberon_type_t * x = malloc(sizeof *x);
90 memset(x, 0, sizeof *x);
91 x -> class = class;
92 return x;
93 }
95 static oberon_type_t *
96 oberon_new_type_integer(int size)
97 {
98 oberon_type_t * x;
99 x = oberon_new_type_ptr(OBERON_TYPE_INTEGER);
100 x -> size = size;
101 return x;
104 static oberon_type_t *
105 oberon_new_type_boolean()
107 oberon_type_t * x;
108 x = oberon_new_type_ptr(OBERON_TYPE_BOOLEAN);
109 return x;
112 static oberon_type_t *
113 oberon_new_type_real(int size)
115 oberon_type_t * x;
116 x = oberon_new_type_ptr(OBERON_TYPE_REAL);
117 x -> size = size;
118 return x;
121 static oberon_type_t *
122 oberon_new_type_char(int size)
124 oberon_type_t * x;
125 x = oberon_new_type_ptr(OBERON_TYPE_CHAR);
126 x -> size = size;
127 return x;
130 static oberon_type_t *
131 oberon_new_type_string(int size)
133 oberon_type_t * x;
134 x = oberon_new_type_ptr(OBERON_TYPE_STRING);
135 x -> size = size;
136 return x;
139 // =======================================================================
140 // TABLE
141 // =======================================================================
143 static oberon_scope_t *
144 oberon_open_scope(oberon_context_t * ctx)
146 oberon_scope_t * scope = calloc(1, sizeof *scope);
147 oberon_object_t * list = calloc(1, sizeof *list);
149 scope -> ctx = ctx;
150 scope -> list = list;
151 scope -> up = ctx -> decl;
153 if(scope -> up)
155 scope -> local = scope -> up -> local;
156 scope -> parent = scope -> up -> parent;
157 scope -> parent_type = scope -> up -> parent_type;
160 ctx -> decl = scope;
161 return scope;
164 static void
165 oberon_close_scope(oberon_scope_t * scope)
167 oberon_context_t * ctx = scope -> ctx;
168 ctx -> decl = scope -> up;
171 static oberon_object_t *
172 oberon_find_object_in_list(oberon_object_t * list, char * name)
174 oberon_object_t * x = list;
175 while(x -> next && strcmp(x -> next -> name, name) != 0)
177 x = x -> next;
179 return x -> next;
182 static oberon_object_t *
183 oberon_find_object(oberon_scope_t * scope, char * name, bool check_it)
185 oberon_object_t * result = NULL;
187 oberon_scope_t * s = scope;
188 while(result == NULL && s != NULL)
190 result = oberon_find_object_in_list(s -> list, name);
191 s = s -> up;
194 if(check_it && result == NULL)
196 oberon_error(scope -> ctx, "undefined ident %s", name);
199 return result;
202 static oberon_object_t *
203 oberon_define_object(oberon_scope_t * scope, char * name, int class, bool export, bool read_only, bool check_upscope)
205 if(check_upscope)
207 if(oberon_find_object(scope -> up, name, false))
209 oberon_error(scope -> ctx, "already defined");
213 oberon_object_t * x = scope -> list;
214 while(x -> next && strcmp(x -> next -> name, name) != 0)
216 x = x -> next;
219 if(x -> next)
221 oberon_error(scope -> ctx, "already defined");
224 oberon_object_t * newvar = malloc(sizeof *newvar);
225 memset(newvar, 0, sizeof *newvar);
226 newvar -> name = name;
227 newvar -> class = class;
228 newvar -> export = export;
229 newvar -> read_only = read_only;
230 newvar -> local = scope -> local;
231 newvar -> parent = scope -> parent;
232 newvar -> parent_type = scope -> parent_type;
233 newvar -> module = scope -> ctx -> mod;
235 x -> next = newvar;
237 return newvar;
240 static oberon_object_t *
241 oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type, int export)
243 oberon_object_t * id;
244 id = oberon_define_object(scope, name, OBERON_CLASS_TYPE, export, false, false);
245 id -> type = type;
246 oberon_generator_init_type(scope -> ctx, type);
247 return id;
250 // =======================================================================
251 // SCANER
252 // =======================================================================
254 static void
255 oberon_get_char(oberon_context_t * ctx)
257 if(ctx -> code[ctx -> code_index])
259 ctx -> code_index += 1;
260 ctx -> c = ctx -> code[ctx -> code_index];
264 static void
265 oberon_init_scaner(oberon_context_t * ctx, const char * code)
267 ctx -> code = code;
268 ctx -> code_index = 0;
269 ctx -> c = ctx -> code[ctx -> code_index];
272 static void
273 oberon_read_ident(oberon_context_t * ctx)
275 int len = 0;
276 int i = ctx -> code_index;
278 int c = ctx -> code[i];
279 while(isalnum(c))
281 i += 1;
282 len += 1;
283 c = ctx -> code[i];
286 char * ident = malloc(len + 1);
287 memcpy(ident, &ctx->code[ctx->code_index], len);
288 ident[len] = 0;
290 ctx -> code_index = i;
291 ctx -> c = ctx -> code[i];
292 ctx -> string = ident;
293 ctx -> token = IDENT;
295 if(strcmp(ident, "MODULE") == 0)
297 ctx -> token = MODULE;
299 else if(strcmp(ident, "END") == 0)
301 ctx -> token = END;
303 else if(strcmp(ident, "VAR") == 0)
305 ctx -> token = VAR;
307 else if(strcmp(ident, "BEGIN") == 0)
309 ctx -> token = BEGIN;
311 else if(strcmp(ident, "TRUE") == 0)
313 ctx -> token = TRUE;
315 else if(strcmp(ident, "FALSE") == 0)
317 ctx -> token = FALSE;
319 else if(strcmp(ident, "OR") == 0)
321 ctx -> token = OR;
323 else if(strcmp(ident, "DIV") == 0)
325 ctx -> token = DIV;
327 else if(strcmp(ident, "MOD") == 0)
329 ctx -> token = MOD;
331 else if(strcmp(ident, "PROCEDURE") == 0)
333 ctx -> token = PROCEDURE;
335 else if(strcmp(ident, "RETURN") == 0)
337 ctx -> token = RETURN;
339 else if(strcmp(ident, "CONST") == 0)
341 ctx -> token = CONST;
343 else if(strcmp(ident, "TYPE") == 0)
345 ctx -> token = TYPE;
347 else if(strcmp(ident, "ARRAY") == 0)
349 ctx -> token = ARRAY;
351 else if(strcmp(ident, "OF") == 0)
353 ctx -> token = OF;
355 else if(strcmp(ident, "RECORD") == 0)
357 ctx -> token = RECORD;
359 else if(strcmp(ident, "POINTER") == 0)
361 ctx -> token = POINTER;
363 else if(strcmp(ident, "TO") == 0)
365 ctx -> token = TO;
367 else if(strcmp(ident, "NIL") == 0)
369 ctx -> token = NIL;
371 else if(strcmp(ident, "IMPORT") == 0)
373 ctx -> token = IMPORT;
375 else if(strcmp(ident, "IN") == 0)
377 ctx -> token = IN;
379 else if(strcmp(ident, "IS") == 0)
381 ctx -> token = IS;
385 static void
386 oberon_read_number(oberon_context_t * ctx)
388 long integer;
389 double real;
390 char * ident;
391 int start_i;
392 int exp_i;
393 int end_i;
395 /*
396 * mode = 0 == DEC
397 * mode = 1 == HEX
398 * mode = 2 == REAL
399 * mode = 3 == LONGREAL
400 * mode = 4 == CHAR
401 */
402 int mode = 0;
403 start_i = ctx -> code_index;
405 while(isdigit(ctx -> c))
407 oberon_get_char(ctx);
410 end_i = ctx -> code_index;
412 if(isxdigit(ctx -> c))
414 mode = 1;
415 while(isxdigit(ctx -> c))
417 oberon_get_char(ctx);
420 end_i = ctx -> code_index;
422 if(ctx -> c == 'H')
424 mode = 1;
425 oberon_get_char(ctx);
427 else if(ctx -> c == 'X')
429 mode = 4;
430 oberon_get_char(ctx);
432 else
434 oberon_error(ctx, "invalid hex number");
437 else if(ctx -> c == '.')
439 mode = 2;
440 oberon_get_char(ctx);
442 while(isdigit(ctx -> c))
444 oberon_get_char(ctx);
447 if(ctx -> c == 'E' || ctx -> c == 'D')
449 exp_i = ctx -> code_index;
451 if(ctx -> c == 'D')
453 mode = 3;
456 oberon_get_char(ctx);
458 if(ctx -> c == '+' || ctx -> c == '-')
460 oberon_get_char(ctx);
463 while(isdigit(ctx -> c))
465 oberon_get_char(ctx);
470 end_i = ctx -> code_index;
473 if(mode == 0)
475 if(ctx -> c == 'H')
477 mode = 1;
478 oberon_get_char(ctx);
480 else if(ctx -> c == 'X')
482 mode = 4;
483 oberon_get_char(ctx);
487 int len = end_i - start_i;
488 ident = malloc(len + 1);
489 memcpy(ident, &ctx -> code[start_i], len);
490 ident[len] = 0;
492 ctx -> longmode = false;
493 if(mode == 3)
495 int i = exp_i - start_i;
496 ident[i] = 'E';
497 ctx -> longmode = true;
500 switch(mode)
502 case 0:
503 integer = atol(ident);
504 real = integer;
505 ctx -> token = INTEGER;
506 break;
507 case 1:
508 sscanf(ident, "%lx", &integer);
509 real = integer;
510 ctx -> token = INTEGER;
511 break;
512 case 2:
513 case 3:
514 sscanf(ident, "%lf", &real);
515 ctx -> token = REAL;
516 break;
517 case 4:
518 sscanf(ident, "%lx", &integer);
519 real = integer;
520 ctx -> token = CHAR;
521 break;
522 default:
523 oberon_error(ctx, "oberon_read_number: wat");
524 break;
527 ctx -> string = ident;
528 ctx -> integer = integer;
529 ctx -> real = real;
532 static void
533 oberon_skip_space(oberon_context_t * ctx)
535 while(isspace(ctx -> c))
537 oberon_get_char(ctx);
541 static void
542 oberon_read_comment(oberon_context_t * ctx)
544 int nesting = 1;
545 while(nesting >= 1)
547 if(ctx -> c == '(')
549 oberon_get_char(ctx);
550 if(ctx -> c == '*')
552 oberon_get_char(ctx);
553 nesting += 1;
556 else if(ctx -> c == '*')
558 oberon_get_char(ctx);
559 if(ctx -> c == ')')
561 oberon_get_char(ctx);
562 nesting -= 1;
565 else if(ctx -> c == 0)
567 oberon_error(ctx, "unterminated comment");
569 else
571 oberon_get_char(ctx);
576 static void oberon_read_string(oberon_context_t * ctx)
578 int c = ctx -> c;
579 oberon_get_char(ctx);
581 int start = ctx -> code_index;
583 while(ctx -> c != 0 && ctx -> c != c)
585 oberon_get_char(ctx);
588 if(ctx -> c == 0)
590 oberon_error(ctx, "unterminated string");
593 int end = ctx -> code_index;
595 oberon_get_char(ctx);
597 char * string = calloc(1, end - start + 1);
598 strncpy(string, &ctx -> code[start], end - start);
600 ctx -> token = STRING;
601 ctx -> string = string;
603 printf("oberon_read_string: string ((%s))\n", string);
606 static void oberon_read_token(oberon_context_t * ctx);
608 static void
609 oberon_read_symbol(oberon_context_t * ctx)
611 int c = ctx -> c;
612 switch(c)
614 case 0:
615 ctx -> token = EOF_;
616 break;
617 case ';':
618 ctx -> token = SEMICOLON;
619 oberon_get_char(ctx);
620 break;
621 case ':':
622 ctx -> token = COLON;
623 oberon_get_char(ctx);
624 if(ctx -> c == '=')
626 ctx -> token = ASSIGN;
627 oberon_get_char(ctx);
629 break;
630 case '.':
631 ctx -> token = DOT;
632 oberon_get_char(ctx);
633 break;
634 case '(':
635 ctx -> token = LPAREN;
636 oberon_get_char(ctx);
637 if(ctx -> c == '*')
639 oberon_get_char(ctx);
640 oberon_read_comment(ctx);
641 oberon_read_token(ctx);
643 break;
644 case ')':
645 ctx -> token = RPAREN;
646 oberon_get_char(ctx);
647 break;
648 case '=':
649 ctx -> token = EQUAL;
650 oberon_get_char(ctx);
651 break;
652 case '#':
653 ctx -> token = NEQ;
654 oberon_get_char(ctx);
655 break;
656 case '<':
657 ctx -> token = LESS;
658 oberon_get_char(ctx);
659 if(ctx -> c == '=')
661 ctx -> token = LEQ;
662 oberon_get_char(ctx);
664 break;
665 case '>':
666 ctx -> token = GREAT;
667 oberon_get_char(ctx);
668 if(ctx -> c == '=')
670 ctx -> token = GEQ;
671 oberon_get_char(ctx);
673 break;
674 case '+':
675 ctx -> token = PLUS;
676 oberon_get_char(ctx);
677 break;
678 case '-':
679 ctx -> token = MINUS;
680 oberon_get_char(ctx);
681 break;
682 case '*':
683 ctx -> token = STAR;
684 oberon_get_char(ctx);
685 if(ctx -> c == ')')
687 oberon_get_char(ctx);
688 oberon_error(ctx, "unstarted comment");
690 break;
691 case '/':
692 ctx -> token = SLASH;
693 oberon_get_char(ctx);
694 break;
695 case '&':
696 ctx -> token = AND;
697 oberon_get_char(ctx);
698 break;
699 case '~':
700 ctx -> token = NOT;
701 oberon_get_char(ctx);
702 break;
703 case ',':
704 ctx -> token = COMMA;
705 oberon_get_char(ctx);
706 break;
707 case '[':
708 ctx -> token = LBRACE;
709 oberon_get_char(ctx);
710 break;
711 case ']':
712 ctx -> token = RBRACE;
713 oberon_get_char(ctx);
714 break;
715 case '^':
716 ctx -> token = UPARROW;
717 oberon_get_char(ctx);
718 break;
719 case '"':
720 oberon_read_string(ctx);
721 break;
722 case '\'':
723 oberon_read_string(ctx);
724 break;
725 default:
726 oberon_error(ctx, "invalid char %c", ctx -> c);
727 break;
731 static void
732 oberon_read_token(oberon_context_t * ctx)
734 oberon_skip_space(ctx);
736 int c = ctx -> c;
737 if(isalpha(c))
739 oberon_read_ident(ctx);
741 else if(isdigit(c))
743 oberon_read_number(ctx);
745 else
747 oberon_read_symbol(ctx);
751 // =======================================================================
752 // EXPRESSION
753 // =======================================================================
755 static void oberon_expect_token(oberon_context_t * ctx, int token);
756 static oberon_expr_t * oberon_expr(oberon_context_t * ctx);
757 static void oberon_assert_token(oberon_context_t * ctx, int token);
758 static char * oberon_assert_ident(oberon_context_t * ctx);
759 static void oberon_type(oberon_context_t * ctx, oberon_type_t ** type);
760 static oberon_item_t * oberon_const_expr(oberon_context_t * ctx);
761 static oberon_expr_t * oberno_make_dereferencing(oberon_context_t * ctx, oberon_expr_t * expr);
763 static oberon_expr_t *
764 oberon_new_operator(int op, oberon_type_t * result, oberon_expr_t * left, oberon_expr_t * right)
766 oberon_oper_t * operator;
767 operator = malloc(sizeof *operator);
768 memset(operator, 0, sizeof *operator);
770 operator -> is_item = 0;
771 operator -> result = result;
772 operator -> read_only = 1;
773 operator -> op = op;
774 operator -> left = left;
775 operator -> right = right;
777 return (oberon_expr_t *) operator;
780 static oberon_expr_t *
781 oberon_new_item(int mode, oberon_type_t * result, int read_only)
783 oberon_item_t * item;
784 item = malloc(sizeof *item);
785 memset(item, 0, sizeof *item);
787 item -> is_item = 1;
788 item -> result = result;
789 item -> read_only = read_only;
790 item -> mode = mode;
792 return (oberon_expr_t *)item;
795 static oberon_expr_t *
796 oberon_make_unary_op(oberon_context_t * ctx, int token, oberon_expr_t * a)
798 oberon_expr_t * expr;
799 oberon_type_t * result;
801 result = a -> result;
803 if(token == MINUS)
805 if(result -> class != OBERON_TYPE_INTEGER)
807 oberon_error(ctx, "incompatible operator type");
810 expr = oberon_new_operator(OP_UNARY_MINUS, result, a, NULL);
812 else if(token == NOT)
814 if(result -> class != OBERON_TYPE_BOOLEAN)
816 oberon_error(ctx, "incompatible operator type");
819 expr = oberon_new_operator(OP_LOGIC_NOT, result, a, NULL);
821 else
823 oberon_error(ctx, "oberon_make_unary_op: wat");
826 return expr;
829 static void
830 oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first, int const_expr)
832 oberon_expr_t * last;
834 *num_expr = 1;
835 if(const_expr)
837 *first = last = (oberon_expr_t *) oberon_const_expr(ctx);
839 else
841 *first = last = oberon_expr(ctx);
843 while(ctx -> token == COMMA)
845 oberon_assert_token(ctx, COMMA);
846 oberon_expr_t * current;
848 if(const_expr)
850 current = (oberon_expr_t *) oberon_const_expr(ctx);
852 else
854 current = oberon_expr(ctx);
857 last -> next = current;
858 last = current;
859 *num_expr += 1;
863 static oberon_expr_t *
864 oberon_cast_expr(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * pref)
866 return oberon_new_operator(OP_CAST, pref, expr, NULL);
869 static oberon_expr_t *
870 oberno_make_record_cast(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * rec)
872 oberon_type_t * from = expr -> result;
873 oberon_type_t * to = rec;
875 printf("oberno_make_record_cast: from class %i to class %i\n", from -> class, to -> class);
877 if(from -> class == OBERON_TYPE_POINTER && to -> class == OBERON_TYPE_POINTER)
879 printf("oberno_make_record_cast: pointers\n");
880 from = from -> base;
881 to = to -> base;
884 if(from -> class != OBERON_TYPE_RECORD || to -> class != OBERON_TYPE_RECORD)
886 oberon_error(ctx, "must be record type");
889 return oberon_cast_expr(ctx, expr, rec);
892 static oberon_type_t *
893 oberon_get_equal_expr_type(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b)
895 oberon_type_t * result;
896 if(a -> class == OBERON_TYPE_REAL && b -> class == OBERON_TYPE_INTEGER)
898 result = a;
900 else if(b -> class == OBERON_TYPE_REAL && a -> class == OBERON_TYPE_INTEGER)
902 result = b;
904 else if(a -> class != b -> class)
906 oberon_error(ctx, "oberon_get_equal_expr_type: incompatible types");
908 else if(a -> size > b -> size)
910 result = a;
912 else
914 result = b;
917 return result;
920 static void
921 oberon_check_record_compatibility(oberon_context_t * ctx, oberon_type_t * from, oberon_type_t * to)
923 if(from -> class == OBERON_TYPE_POINTER && to -> class == OBERON_TYPE_POINTER)
925 from = from -> base;
926 to = to -> base;
929 if(from -> class != OBERON_TYPE_RECORD || to -> class != OBERON_TYPE_RECORD)
931 oberon_error(ctx, "not a record");
934 oberon_type_t * t = from;
935 while(t != NULL && t != to)
937 t = t -> base;
940 if(t == NULL)
942 oberon_error(ctx, "incompatible record types");
946 static oberon_expr_t *
947 oberon_autocast_to(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * pref)
949 // Допускается:
950 // Если классы типов равны
951 // Если INTEGER переводится в REAL
952 // Есди STRING переводится в ARRAY OF CHAR
954 bool error = false;
955 if(pref -> class != expr -> result -> class)
957 printf("expr class %i\n", expr -> result -> class);
958 printf("pref class %i\n", pref -> class);
960 if(expr -> result -> class == OBERON_TYPE_STRING)
962 if(pref -> class == OBERON_TYPE_ARRAY)
964 if(pref -> base -> class != OBERON_TYPE_CHAR)
966 error = true;
969 else
971 error = true;
974 else if(expr -> result -> class == OBERON_TYPE_INTEGER)
976 if(pref -> class != OBERON_TYPE_REAL)
978 error = true;
981 else
983 error = true;
987 if(error)
989 oberon_error(ctx, "oberon_autocast_to: incompatible types");
992 if(pref -> class == OBERON_TYPE_INTEGER || pref -> class == OBERON_TYPE_REAL)
994 if(expr -> result -> size > pref -> size)
996 oberon_error(ctx, "incompatible size");
998 else
1000 expr = oberon_cast_expr(ctx, expr, pref);
1003 else if(pref -> class == OBERON_TYPE_RECORD)
1005 oberon_check_record_compatibility(ctx, expr -> result, pref);
1006 expr = oberno_make_record_cast(ctx, expr, pref);
1008 else if(pref -> class == OBERON_TYPE_POINTER)
1010 assert(pref -> base);
1011 if(expr -> result -> base -> class == OBERON_TYPE_RECORD)
1013 oberon_check_record_compatibility(ctx, expr -> result, pref);
1014 expr = oberno_make_record_cast(ctx, expr, pref);
1016 else if(expr -> result -> base != pref -> base)
1018 if(expr -> result -> base -> class != OBERON_TYPE_VOID)
1020 oberon_error(ctx, "incompatible pointer types");
1025 return expr;
1028 static void
1029 oberon_autocast_binary_op(oberon_context_t * ctx, oberon_expr_t ** ea, oberon_expr_t ** eb)
1031 oberon_type_t * a = (*ea) -> result;
1032 oberon_type_t * b = (*eb) -> result;
1033 oberon_type_t * preq = oberon_get_equal_expr_type(ctx, a, b);
1034 *ea = oberon_autocast_to(ctx, *ea, preq);
1035 *eb = oberon_autocast_to(ctx, *eb, preq);
1038 static void
1039 oberon_autocast_call(oberon_context_t * ctx, oberon_item_t * desig)
1041 if(desig -> mode != MODE_CALL)
1043 oberon_error(ctx, "expected mode CALL");
1046 oberon_type_t * fn = desig -> parent -> result;
1047 int num_args = desig -> num_args;
1048 int num_decl = fn -> num_decl;
1050 if(num_args < num_decl)
1052 oberon_error(ctx, "too few arguments");
1054 else if(num_args > num_decl)
1056 oberon_error(ctx, "too many arguments");
1059 /* Делаем проверку на запись и делаем автокаст */
1060 oberon_expr_t * casted[num_args];
1061 oberon_expr_t * arg = desig -> args;
1062 oberon_object_t * param = fn -> decl;
1063 for(int i = 0; i < num_args; i++)
1065 if(param -> class == OBERON_CLASS_VAR_PARAM)
1067 if(arg -> read_only)
1069 oberon_error(ctx, "assign to read-only var");
1073 casted[i] = oberon_autocast_to(ctx, arg, param -> type);
1074 arg = arg -> next;
1075 param = param -> next;
1078 /* Создаём новый список выражений */
1079 if(num_args > 0)
1081 arg = casted[0];
1082 for(int i = 0; i < num_args - 1; i++)
1084 casted[i] -> next = casted[i + 1];
1086 desig -> args = arg;
1090 static oberon_expr_t *
1091 oberon_make_call_func(oberon_context_t * ctx, oberon_item_t * item, int num_args, oberon_expr_t * list_args)
1093 oberon_type_t * signature = item -> result;
1094 if(signature -> class != OBERON_TYPE_PROCEDURE)
1096 oberon_error(ctx, "not a procedure");
1099 oberon_expr_t * call;
1101 if(signature -> sysproc)
1103 if(signature -> genfunc == NULL)
1105 oberon_error(ctx, "not a function-procedure");
1108 call = signature -> genfunc(ctx, num_args, list_args);
1110 else
1112 if(signature -> base -> class == OBERON_TYPE_VOID)
1114 oberon_error(ctx, "attempt to call procedure in expression");
1117 call = oberon_new_item(MODE_CALL, signature -> base, true);
1118 call -> item.parent = item;
1119 call -> item.num_args = num_args;
1120 call -> item.args = list_args;
1121 oberon_autocast_call(ctx, (oberon_item_t *) call);
1124 return call;
1127 static void
1128 oberon_make_call_proc(oberon_context_t * ctx, oberon_item_t * item, int num_args, oberon_expr_t * list_args)
1130 oberon_type_t * signature = item -> result;
1131 if(signature -> class != OBERON_TYPE_PROCEDURE)
1133 oberon_error(ctx, "not a procedure");
1136 oberon_expr_t * call;
1138 if(signature -> sysproc)
1140 if(signature -> genproc == NULL)
1142 oberon_error(ctx, "not a procedure");
1145 signature -> genproc(ctx, num_args, list_args);
1147 else
1149 if(signature -> base -> class != OBERON_TYPE_VOID)
1151 oberon_error(ctx, "attempt to call function as non-typed procedure");
1154 call = oberon_new_item(MODE_CALL, signature -> base, true);
1155 call -> item.parent = item;
1156 call -> item.num_args = num_args;
1157 call -> item.args = list_args;
1158 oberon_autocast_call(ctx, (oberon_item_t *) call);
1159 oberon_generate_call_proc(ctx, call);
1163 /*
1164 static void
1165 oberon_make_call_proc(oberon_context_t * ctx, oberon_object_t * proc, int num_args, oberon_expr_t * list_args)
1167 switch(proc -> class)
1169 case OBERON_CLASS_PROC:
1170 if(proc -> class != OBERON_CLASS_PROC)
1172 oberon_error(ctx, "not a procedure");
1174 break;
1175 case OBERON_CLASS_VAR:
1176 case OBERON_CLASS_VAR_PARAM:
1177 case OBERON_CLASS_PARAM:
1178 if(proc -> type -> class != OBERON_TYPE_PROCEDURE)
1180 oberon_error(ctx, "not a procedure");
1182 break;
1183 default:
1184 oberon_error(ctx, "not a procedure");
1185 break;
1188 if(proc -> sysproc)
1190 if(proc -> genproc == NULL)
1192 oberon_error(ctx, "requres non-typed procedure");
1195 proc -> genproc(ctx, num_args, list_args);
1197 else
1199 if(proc -> type -> base -> class != OBERON_TYPE_VOID)
1201 oberon_error(ctx, "attempt to call function as non-typed procedure");
1204 oberon_expr_t * call;
1205 call = oberon_new_item(MODE_CALL, proc -> type -> base, 1);
1206 call -> item.var = proc;
1207 call -> item.num_args = num_args;
1208 call -> item.args = list_args;
1209 oberon_autocast_call(ctx, call);
1210 oberon_generate_call_proc(ctx, call);
1213 */
1215 #define ISEXPR(x) \
1216 (((x) == PLUS) \
1217 || ((x) == MINUS) \
1218 || ((x) == IDENT) \
1219 || ((x) == INTEGER) \
1220 || ((x) == REAL) \
1221 || ((x) == CHAR) \
1222 || ((x) == STRING) \
1223 || ((x) == NIL) \
1224 || ((x) == LPAREN) \
1225 || ((x) == NOT) \
1226 || ((x) == TRUE) \
1227 || ((x) == FALSE))
1229 static oberon_expr_t *
1230 oberno_make_dereferencing(oberon_context_t * ctx, oberon_expr_t * expr)
1232 printf("oberno_make_dereferencing\n");
1233 if(expr -> result -> class != OBERON_TYPE_POINTER)
1235 oberon_error(ctx, "not a pointer");
1238 assert(expr -> is_item);
1240 oberon_expr_t * selector;
1241 selector = oberon_new_item(MODE_DEREF, expr -> result -> base, expr -> read_only);
1242 selector -> item.parent = (oberon_item_t *) expr;
1244 return selector;
1247 static oberon_expr_t *
1248 oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, oberon_expr_t * index)
1250 if(desig -> result -> class == OBERON_TYPE_POINTER)
1252 desig = oberno_make_dereferencing(ctx, desig);
1255 assert(desig -> is_item);
1257 if(desig -> result -> class != OBERON_TYPE_ARRAY)
1259 oberon_error(ctx, "not array");
1262 oberon_type_t * base;
1263 base = desig -> result -> base;
1265 if(index -> result -> class != OBERON_TYPE_INTEGER)
1267 oberon_error(ctx, "index must be integer");
1270 // Статическая проверка границ массива
1271 if(desig -> result -> size != 0)
1273 if(index -> is_item)
1275 if(index -> item.mode == MODE_INTEGER)
1277 int arr_size = desig -> result -> size;
1278 int index_int = index -> item.integer;
1279 if(index_int < 0 || index_int > arr_size - 1)
1281 oberon_error(ctx, "not in range (dimension size 0..%i)", arr_size - 1);
1287 oberon_expr_t * selector;
1288 selector = oberon_new_item(MODE_INDEX, base, desig -> read_only);
1289 selector -> item.parent = (oberon_item_t *) desig;
1290 selector -> item.num_args = 1;
1291 selector -> item.args = index;
1293 return selector;
1296 static oberon_expr_t *
1297 oberon_make_record_selector(oberon_context_t * ctx, oberon_expr_t * expr, char * name)
1299 if(expr -> result -> class == OBERON_TYPE_POINTER)
1301 expr = oberno_make_dereferencing(ctx, expr);
1304 assert(expr -> is_item);
1306 if(expr -> result -> class != OBERON_TYPE_RECORD)
1308 oberon_error(ctx, "not record");
1311 oberon_type_t * rec = expr -> result;
1313 oberon_object_t * field;
1314 field = oberon_find_object(rec -> scope, name, true);
1316 if(field -> export == 0)
1318 if(field -> module != ctx -> mod)
1320 oberon_error(ctx, "field not exported");
1324 int read_only = 0;
1325 if(field -> read_only)
1327 if(field -> module != ctx -> mod)
1329 read_only = 1;
1333 oberon_expr_t * selector;
1334 selector = oberon_new_item(MODE_FIELD, field -> type, read_only);
1335 selector -> item.var = field;
1336 selector -> item.parent = (oberon_item_t *) expr;
1338 return selector;
1341 #define ISSELECTOR(x) \
1342 (((x) == LBRACE) \
1343 || ((x) == DOT) \
1344 || ((x) == UPARROW) \
1345 || ((x) == LPAREN))
1347 static oberon_object_t *
1348 oberon_qualident(oberon_context_t * ctx, char ** xname, int check)
1350 char * name;
1351 oberon_object_t * x;
1353 name = oberon_assert_ident(ctx);
1354 x = oberon_find_object(ctx -> decl, name, check);
1356 if(x != NULL)
1358 if(x -> class == OBERON_CLASS_MODULE)
1360 oberon_assert_token(ctx, DOT);
1361 name = oberon_assert_ident(ctx);
1362 /* Наличие объектов в левых модулях всегда проверяется */
1363 x = oberon_find_object(x -> module -> decl, name, 1);
1365 if(x -> export == 0)
1367 oberon_error(ctx, "not exported");
1372 if(xname)
1374 *xname = name;
1377 return x;
1380 static oberon_expr_t *
1381 oberon_designator(oberon_context_t * ctx)
1383 char * name;
1384 oberon_object_t * var;
1385 oberon_expr_t * expr;
1387 var = oberon_qualident(ctx, NULL, 1);
1389 int read_only = 0;
1390 if(var -> read_only)
1392 if(var -> module != ctx -> mod)
1394 read_only = 1;
1398 switch(var -> class)
1400 case OBERON_CLASS_CONST:
1401 // TODO copy value
1402 expr = (oberon_expr_t *) var -> value;
1403 break;
1404 case OBERON_CLASS_VAR:
1405 case OBERON_CLASS_VAR_PARAM:
1406 case OBERON_CLASS_PARAM:
1407 expr = oberon_new_item(MODE_VAR, var -> type, read_only);
1408 break;
1409 case OBERON_CLASS_PROC:
1410 expr = oberon_new_item(MODE_VAR, var -> type, 1);
1411 break;
1412 default:
1413 oberon_error(ctx, "invalid designator");
1414 break;
1416 expr -> item.var = var;
1418 while(expr -> result -> class != OBERON_TYPE_PROCEDURE && ISSELECTOR(ctx -> token))
1420 switch(ctx -> token)
1422 case DOT:
1423 oberon_assert_token(ctx, DOT);
1424 name = oberon_assert_ident(ctx);
1425 expr = oberon_make_record_selector(ctx, expr, name);
1426 break;
1427 case LBRACE:
1428 oberon_assert_token(ctx, LBRACE);
1429 int num_indexes = 0;
1430 oberon_expr_t * indexes = NULL;
1431 oberon_expr_list(ctx, &num_indexes, &indexes, 0);
1432 oberon_assert_token(ctx, RBRACE);
1434 for(int i = 0; i < num_indexes; i++)
1436 expr = oberon_make_array_selector(ctx, expr, indexes);
1437 indexes = indexes -> next;
1439 break;
1440 case UPARROW:
1441 oberon_assert_token(ctx, UPARROW);
1442 expr = oberno_make_dereferencing(ctx, expr);
1443 break;
1444 case LPAREN:
1445 oberon_assert_token(ctx, LPAREN);
1446 oberon_object_t * objtype = oberon_qualident(ctx, NULL, 1);
1447 if(objtype -> class != OBERON_CLASS_TYPE)
1449 oberon_error(ctx, "must be type");
1451 oberon_assert_token(ctx, RPAREN);
1452 expr = oberno_make_record_cast(ctx, expr, objtype -> type);
1453 break;
1454 default:
1455 oberon_error(ctx, "oberon_designator: wat");
1456 break;
1460 return expr;
1463 static oberon_expr_t *
1464 oberon_opt_func_parens(oberon_context_t * ctx, oberon_expr_t * expr)
1466 /* Если есть скобки - значит вызов. Если нет, то передаём указатель. */
1467 if(ctx -> token == LPAREN)
1469 oberon_assert_token(ctx, LPAREN);
1471 int num_args = 0;
1472 oberon_expr_t * arguments = NULL;
1474 if(ISEXPR(ctx -> token))
1476 oberon_expr_list(ctx, &num_args, &arguments, 0);
1479 assert(expr -> is_item == 1);
1480 expr = oberon_make_call_func(ctx, (oberon_item_t *) expr, num_args, arguments);
1482 oberon_assert_token(ctx, RPAREN);
1485 return expr;
1488 static void
1489 oberon_opt_proc_parens(oberon_context_t * ctx, oberon_expr_t * expr)
1491 assert(expr -> is_item);
1493 int num_args = 0;
1494 oberon_expr_t * arguments = NULL;
1496 if(ctx -> token == LPAREN)
1498 oberon_assert_token(ctx, LPAREN);
1500 if(ISEXPR(ctx -> token))
1502 oberon_expr_list(ctx, &num_args, &arguments, 0);
1505 oberon_assert_token(ctx, RPAREN);
1508 /* Вызов происходит даже без скобок */
1509 oberon_make_call_proc(ctx, (oberon_item_t *) expr, num_args, arguments);
1512 static oberon_type_t *
1513 oberon_get_type_of_int_value(oberon_context_t * ctx, int64_t i)
1515 if(i >= -128 && i <= 127)
1517 return ctx -> byte_type;
1519 else if(i >= -32768 && i <= 32767)
1521 return ctx -> shortint_type;
1523 else if(i >= -2147483648 && i <= 2147483647)
1525 return ctx -> int_type;
1527 else
1529 return ctx -> longint_type;
1533 static oberon_expr_t *
1534 oberon_factor(oberon_context_t * ctx)
1536 oberon_expr_t * expr;
1537 oberon_type_t * result;
1539 switch(ctx -> token)
1541 case IDENT:
1542 expr = oberon_designator(ctx);
1543 expr = oberon_opt_func_parens(ctx, expr);
1544 break;
1545 case INTEGER:
1546 result = oberon_get_type_of_int_value(ctx, ctx -> integer);
1547 expr = oberon_new_item(MODE_INTEGER, result, true);
1548 expr -> item.integer = ctx -> integer;
1549 oberon_assert_token(ctx, INTEGER);
1550 break;
1551 case CHAR:
1552 result = ctx -> char_type;
1553 expr = oberon_new_item(MODE_CHAR, result, true);
1554 expr -> item.integer = ctx -> integer;
1555 oberon_assert_token(ctx, CHAR);
1556 break;
1557 case STRING:
1558 result = ctx -> string_type;
1559 expr = oberon_new_item(MODE_STRING, result, true);
1560 expr -> item.string = ctx -> string;
1561 oberon_assert_token(ctx, STRING);
1562 break;
1563 case REAL:
1564 result = (ctx -> longmode) ? (ctx -> longreal_type) : (ctx -> real_type);
1565 expr = oberon_new_item(MODE_REAL, result, 1);
1566 expr -> item.real = ctx -> real;
1567 oberon_assert_token(ctx, REAL);
1568 break;
1569 case TRUE:
1570 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type, true);
1571 expr -> item.boolean = true;
1572 oberon_assert_token(ctx, TRUE);
1573 break;
1574 case FALSE:
1575 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type, true);
1576 expr -> item.boolean = false;
1577 oberon_assert_token(ctx, FALSE);
1578 break;
1579 case LPAREN:
1580 oberon_assert_token(ctx, LPAREN);
1581 expr = oberon_expr(ctx);
1582 oberon_assert_token(ctx, RPAREN);
1583 break;
1584 case NOT:
1585 oberon_assert_token(ctx, NOT);
1586 expr = oberon_factor(ctx);
1587 expr = oberon_make_unary_op(ctx, NOT, expr);
1588 break;
1589 case NIL:
1590 oberon_assert_token(ctx, NIL);
1591 expr = oberon_new_item(MODE_NIL, ctx -> void_ptr_type, true);
1592 break;
1593 default:
1594 oberon_error(ctx, "invalid expression");
1597 return expr;
1600 #define ITMAKESBOOLEAN(x) \
1601 (((x) >= EQUAL && (x) <= GEQ) || ((x) == OR) || ((x) == AND))
1603 #define ITUSEONLYINTEGER(x) \
1604 ((x) >= LESS && (x) <= GEQ)
1606 #define ITUSEONLYBOOLEAN(x) \
1607 (((x) == OR) || ((x) == AND))
1609 static void
1610 oberon_autocast_to_real(oberon_context_t * ctx, oberon_expr_t ** e)
1612 oberon_expr_t * expr = *e;
1613 if(expr -> result -> class == OBERON_TYPE_INTEGER)
1615 if(expr -> result -> size <= ctx -> real_type -> size)
1617 *e = oberon_cast_expr(ctx, expr, ctx -> real_type);
1619 else
1621 *e = oberon_cast_expr(ctx, expr, ctx -> longreal_type);
1624 else if(expr -> result -> class != OBERON_TYPE_REAL)
1626 oberon_error(ctx, "required numeric type");
1630 static oberon_expr_t *
1631 oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
1633 oberon_expr_t * expr;
1634 oberon_type_t * result;
1636 if(ITMAKESBOOLEAN(token))
1638 if(ITUSEONLYINTEGER(token))
1640 if(a -> result -> class == OBERON_TYPE_INTEGER
1641 || b -> result -> class == OBERON_TYPE_INTEGER
1642 || a -> result -> class == OBERON_TYPE_REAL
1643 || b -> result -> class == OBERON_TYPE_REAL)
1645 oberon_error(ctx, "used only with numeric types");
1648 else if(ITUSEONLYBOOLEAN(token))
1650 if(a -> result -> class != OBERON_TYPE_BOOLEAN
1651 || b -> result -> class != OBERON_TYPE_BOOLEAN)
1653 oberon_error(ctx, "used only with boolean type");
1657 oberon_autocast_binary_op(ctx, &a, &b);
1658 result = ctx -> bool_type;
1660 if(token == EQUAL)
1662 expr = oberon_new_operator(OP_EQ, result, a, b);
1664 else if(token == NEQ)
1666 expr = oberon_new_operator(OP_NEQ, result, a, b);
1668 else if(token == LESS)
1670 expr = oberon_new_operator(OP_LSS, result, a, b);
1672 else if(token == LEQ)
1674 expr = oberon_new_operator(OP_LEQ, result, a, b);
1676 else if(token == GREAT)
1678 expr = oberon_new_operator(OP_GRT, result, a, b);
1680 else if(token == GEQ)
1682 expr = oberon_new_operator(OP_GEQ, result, a, b);
1684 else if(token == OR)
1686 expr = oberon_new_operator(OP_LOGIC_OR, result, a, b);
1688 else if(token == AND)
1690 expr = oberon_new_operator(OP_LOGIC_AND, result, a, b);
1692 else
1694 oberon_error(ctx, "oberon_make_bin_op: bool wat");
1697 else if(token == SLASH)
1699 oberon_autocast_to_real(ctx, &a);
1700 oberon_autocast_to_real(ctx, &b);
1701 oberon_autocast_binary_op(ctx, &a, &b);
1702 expr = oberon_new_operator(OP_DIV, a -> result, a, b);
1704 else if(token == DIV)
1706 if(a -> result -> class != OBERON_TYPE_INTEGER
1707 || b -> result -> class != OBERON_TYPE_INTEGER)
1709 oberon_error(ctx, "operator DIV requires integer type");
1712 oberon_autocast_binary_op(ctx, &a, &b);
1713 expr = oberon_new_operator(OP_DIV, a -> result, a, b);
1715 else
1717 oberon_autocast_binary_op(ctx, &a, &b);
1719 if(token == PLUS)
1721 expr = oberon_new_operator(OP_ADD, a -> result, a, b);
1723 else if(token == MINUS)
1725 expr = oberon_new_operator(OP_SUB, a -> result, a, b);
1727 else if(token == STAR)
1729 expr = oberon_new_operator(OP_MUL, a -> result, a, b);
1731 else if(token == MOD)
1733 expr = oberon_new_operator(OP_MOD, a -> result, a, b);
1735 else
1737 oberon_error(ctx, "oberon_make_bin_op: bin wat");
1741 return expr;
1744 #define ISMULOP(x) \
1745 ((x) >= STAR && (x) <= AND)
1747 static oberon_expr_t *
1748 oberon_term_expr(oberon_context_t * ctx)
1750 oberon_expr_t * expr;
1752 expr = oberon_factor(ctx);
1753 while(ISMULOP(ctx -> token))
1755 int token = ctx -> token;
1756 oberon_read_token(ctx);
1758 oberon_expr_t * inter = oberon_factor(ctx);
1759 expr = oberon_make_bin_op(ctx, token, expr, inter);
1762 return expr;
1765 #define ISADDOP(x) \
1766 ((x) >= PLUS && (x) <= OR)
1768 static oberon_expr_t *
1769 oberon_simple_expr(oberon_context_t * ctx)
1771 oberon_expr_t * expr;
1773 int minus = 0;
1774 if(ctx -> token == PLUS)
1776 minus = 0;
1777 oberon_assert_token(ctx, PLUS);
1779 else if(ctx -> token == MINUS)
1781 minus = 1;
1782 oberon_assert_token(ctx, MINUS);
1785 expr = oberon_term_expr(ctx);
1787 if(minus)
1789 expr = oberon_make_unary_op(ctx, MINUS, expr);
1792 while(ISADDOP(ctx -> token))
1794 int token = ctx -> token;
1795 oberon_read_token(ctx);
1797 oberon_expr_t * inter = oberon_term_expr(ctx);
1798 expr = oberon_make_bin_op(ctx, token, expr, inter);
1801 return expr;
1804 #define ISRELATION(x) \
1805 ((x) >= EQUAL && (x) <= IS)
1807 static oberon_expr_t *
1808 oberon_expr(oberon_context_t * ctx)
1810 oberon_expr_t * expr;
1812 expr = oberon_simple_expr(ctx);
1813 while(ISRELATION(ctx -> token))
1815 int token = ctx -> token;
1816 oberon_read_token(ctx);
1818 oberon_expr_t * inter = oberon_simple_expr(ctx);
1819 expr = oberon_make_bin_op(ctx, token, expr, inter);
1822 return expr;
1825 static oberon_item_t *
1826 oberon_const_expr(oberon_context_t * ctx)
1828 oberon_expr_t * expr;
1829 expr = oberon_expr(ctx);
1831 if(expr -> is_item == 0)
1833 oberon_error(ctx, "const expression are required");
1836 return (oberon_item_t *) expr;
1839 // =======================================================================
1840 // PARSER
1841 // =======================================================================
1843 static void oberon_decl_seq(oberon_context_t * ctx);
1844 static void oberon_statement_seq(oberon_context_t * ctx);
1845 static void oberon_initialize_decl(oberon_context_t * ctx);
1847 static void
1848 oberon_expect_token(oberon_context_t * ctx, int token)
1850 if(ctx -> token != token)
1852 oberon_error(ctx, "unexpected token %i (%i)", ctx -> token, token);
1856 static void
1857 oberon_assert_token(oberon_context_t * ctx, int token)
1859 oberon_expect_token(ctx, token);
1860 oberon_read_token(ctx);
1863 static char *
1864 oberon_assert_ident(oberon_context_t * ctx)
1866 oberon_expect_token(ctx, IDENT);
1867 char * ident = ctx -> string;
1868 oberon_read_token(ctx);
1869 return ident;
1872 static void
1873 oberon_def(oberon_context_t * ctx, int * export, int * read_only)
1875 switch(ctx -> token)
1877 case STAR:
1878 oberon_assert_token(ctx, STAR);
1879 *export = 1;
1880 *read_only = 0;
1881 break;
1882 case MINUS:
1883 oberon_assert_token(ctx, MINUS);
1884 *export = 1;
1885 *read_only = 1;
1886 break;
1887 default:
1888 *export = 0;
1889 *read_only = 0;
1890 break;
1894 static oberon_object_t *
1895 oberon_ident_def(oberon_context_t * ctx, int class, bool check_upscope)
1897 char * name;
1898 int export;
1899 int read_only;
1900 oberon_object_t * x;
1902 name = oberon_assert_ident(ctx);
1903 oberon_def(ctx, &export, &read_only);
1905 x = oberon_define_object(ctx -> decl, name, class, export, read_only, check_upscope);
1906 return x;
1909 static void
1910 oberon_ident_list(oberon_context_t * ctx, int class, bool check_upscope, int * num, oberon_object_t ** list)
1912 *num = 1;
1913 *list = oberon_ident_def(ctx, class, check_upscope);
1914 while(ctx -> token == COMMA)
1916 oberon_assert_token(ctx, COMMA);
1917 oberon_ident_def(ctx, class, check_upscope);
1918 *num += 1;
1922 static void
1923 oberon_var_decl(oberon_context_t * ctx)
1925 int num;
1926 oberon_object_t * list;
1927 oberon_type_t * type;
1928 type = oberon_new_type_ptr(OBERON_TYPE_VOID);
1930 oberon_ident_list(ctx, OBERON_CLASS_VAR, false, &num, &list);
1931 oberon_assert_token(ctx, COLON);
1932 oberon_type(ctx, &type);
1934 oberon_object_t * var = list;
1935 for(int i = 0; i < num; i++)
1937 var -> type = type;
1938 var = var -> next;
1942 static oberon_object_t *
1943 oberon_fp_section(oberon_context_t * ctx, int * num_decl)
1945 int class = OBERON_CLASS_PARAM;
1946 if(ctx -> token == VAR)
1948 oberon_read_token(ctx);
1949 class = OBERON_CLASS_VAR_PARAM;
1952 int num;
1953 oberon_object_t * list;
1954 oberon_ident_list(ctx, class, false, &num, &list);
1956 oberon_assert_token(ctx, COLON);
1958 oberon_type_t * type;
1959 type = oberon_new_type_ptr(OBERON_TYPE_VOID);
1960 oberon_type(ctx, &type);
1962 oberon_object_t * param = list;
1963 for(int i = 0; i < num; i++)
1965 param -> type = type;
1966 param = param -> next;
1969 *num_decl += num;
1970 return list;
1973 #define ISFPSECTION \
1974 ((ctx -> token == VAR) || (ctx -> token == IDENT))
1976 static void
1977 oberon_formal_pars(oberon_context_t * ctx, oberon_type_t * signature)
1979 oberon_assert_token(ctx, LPAREN);
1981 if(ISFPSECTION)
1983 signature -> decl = oberon_fp_section(ctx, &signature -> num_decl);
1984 while(ctx -> token == SEMICOLON)
1986 oberon_assert_token(ctx, SEMICOLON);
1987 oberon_fp_section(ctx, &signature -> num_decl);
1991 oberon_assert_token(ctx, RPAREN);
1993 if(ctx -> token == COLON)
1995 oberon_assert_token(ctx, COLON);
1997 oberon_object_t * typeobj;
1998 typeobj = oberon_qualident(ctx, NULL, 1);
1999 if(typeobj -> class != OBERON_CLASS_TYPE)
2001 oberon_error(ctx, "function result is not type");
2003 signature -> base = typeobj -> type;
2007 static void
2008 oberon_opt_formal_pars(oberon_context_t * ctx, oberon_type_t ** type)
2010 oberon_type_t * signature;
2011 signature = *type;
2012 signature -> class = OBERON_TYPE_PROCEDURE;
2013 signature -> num_decl = 0;
2014 signature -> base = ctx -> void_type;
2015 signature -> decl = NULL;
2017 if(ctx -> token == LPAREN)
2019 oberon_formal_pars(ctx, signature);
2023 static void
2024 oberon_compare_signatures(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b)
2026 if(a -> num_decl != b -> num_decl)
2028 oberon_error(ctx, "number parameters not matched");
2031 int num_param = a -> num_decl;
2032 oberon_object_t * param_a = a -> decl;
2033 oberon_object_t * param_b = b -> decl;
2034 for(int i = 0; i < num_param; i++)
2036 if(strcmp(param_a -> name, param_b -> name) != 0)
2038 oberon_error(ctx, "param %i name not matched", i + 1);
2041 if(param_a -> type != param_b -> type)
2043 oberon_error(ctx, "param %i type not matched", i + 1);
2046 param_a = param_a -> next;
2047 param_b = param_b -> next;
2051 static void
2052 oberon_make_return(oberon_context_t * ctx, oberon_expr_t * expr)
2054 oberon_object_t * proc = ctx -> decl -> parent;
2055 oberon_type_t * result_type = proc -> type -> base;
2057 if(result_type -> class == OBERON_TYPE_VOID)
2059 if(expr != NULL)
2061 oberon_error(ctx, "procedure has no result type");
2064 else
2066 if(expr == NULL)
2068 oberon_error(ctx, "procedure requires expression on result");
2071 expr = oberon_autocast_to(ctx, expr, result_type);
2074 proc -> has_return = 1;
2076 oberon_generate_return(ctx, expr);
2079 static void
2080 oberon_proc_decl_body(oberon_context_t * ctx, oberon_object_t * proc)
2082 oberon_assert_token(ctx, SEMICOLON);
2084 ctx -> decl = proc -> scope;
2086 oberon_decl_seq(ctx);
2088 oberon_generate_begin_proc(ctx, proc);
2090 if(ctx -> token == BEGIN)
2092 oberon_assert_token(ctx, BEGIN);
2093 oberon_statement_seq(ctx);
2096 oberon_assert_token(ctx, END);
2097 char * name = oberon_assert_ident(ctx);
2098 if(strcmp(name, proc -> name) != 0)
2100 oberon_error(ctx, "procedure name not matched");
2103 if(proc -> type -> base -> class == OBERON_TYPE_VOID
2104 && proc -> has_return == 0)
2106 oberon_make_return(ctx, NULL);
2109 if(proc -> has_return == 0)
2111 oberon_error(ctx, "procedure requires return");
2114 oberon_generate_end_proc(ctx);
2115 oberon_close_scope(ctx -> decl);
2118 static void
2119 oberon_proc_decl(oberon_context_t * ctx)
2121 oberon_assert_token(ctx, PROCEDURE);
2123 int forward = 0;
2124 if(ctx -> token == UPARROW)
2126 oberon_assert_token(ctx, UPARROW);
2127 forward = 1;
2130 char * name;
2131 int export;
2132 int read_only;
2133 name = oberon_assert_ident(ctx);
2134 oberon_def(ctx, &export, &read_only);
2136 oberon_scope_t * proc_scope;
2137 proc_scope = oberon_open_scope(ctx);
2138 ctx -> decl -> local = 1;
2140 oberon_type_t * signature;
2141 signature = oberon_new_type_ptr(OBERON_TYPE_VOID);
2142 oberon_opt_formal_pars(ctx, &signature);
2144 oberon_initialize_decl(ctx);
2145 oberon_generator_init_type(ctx, signature);
2146 oberon_close_scope(ctx -> decl);
2148 oberon_object_t * proc;
2149 proc = oberon_find_object(ctx -> decl, name, 0);
2150 if(proc != NULL)
2152 if(proc -> class != OBERON_CLASS_PROC)
2154 oberon_error(ctx, "mult definition");
2157 if(forward == 0)
2159 if(proc -> linked)
2161 oberon_error(ctx, "mult procedure definition");
2165 if(proc -> export != export || proc -> read_only != read_only)
2167 oberon_error(ctx, "export type not matched");
2170 oberon_compare_signatures(ctx, proc -> type, signature);
2172 else
2174 proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, export, read_only, false);
2175 proc -> type = signature;
2176 proc -> scope = proc_scope;
2177 oberon_generator_init_proc(ctx, proc);
2180 proc -> scope -> parent = proc;
2182 if(forward == 0)
2184 proc -> linked = 1;
2185 oberon_proc_decl_body(ctx, proc);
2189 static void
2190 oberon_const_decl(oberon_context_t * ctx)
2192 oberon_item_t * value;
2193 oberon_object_t * constant;
2195 constant = oberon_ident_def(ctx, OBERON_CLASS_CONST, false);
2196 oberon_assert_token(ctx, EQUAL);
2197 value = oberon_const_expr(ctx);
2198 constant -> value = value;
2201 static void
2202 oberon_make_array_type(oberon_context_t * ctx, oberon_expr_t * size, oberon_type_t * base, oberon_type_t ** type)
2204 if(size -> is_item == 0)
2206 oberon_error(ctx, "requires constant");
2209 if(size -> item.mode != MODE_INTEGER)
2211 oberon_error(ctx, "requires integer constant");
2214 oberon_type_t * arr;
2215 arr = *type;
2216 arr -> class = OBERON_TYPE_ARRAY;
2217 arr -> size = size -> item.integer;
2218 arr -> base = base;
2221 static void
2222 oberon_qualident_type(oberon_context_t * ctx, oberon_type_t ** type)
2224 char * name;
2225 oberon_object_t * to;
2227 to = oberon_qualident(ctx, &name, 0);
2229 //name = oberon_assert_ident(ctx);
2230 //to = oberon_find_object(ctx -> decl, name, 0);
2232 if(to != NULL)
2234 if(to -> class != OBERON_CLASS_TYPE)
2236 oberon_error(ctx, "not a type");
2239 else
2241 to = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, false, false, false);
2242 to -> type = oberon_new_type_ptr(OBERON_TYPE_VOID);
2245 *type = to -> type;
2248 static void oberon_opt_formal_pars(oberon_context_t * ctx, oberon_type_t ** type);
2250 /*
2251 * Правило граматики "type". Указатель type должен указывать на существующий объект!
2252 */
2254 static void
2255 oberon_make_multiarray(oberon_context_t * ctx, oberon_expr_t * sizes, oberon_type_t * base, oberon_type_t ** type)
2257 if(sizes == NULL)
2259 *type = base;
2260 return;
2263 oberon_type_t * dim;
2264 dim = oberon_new_type_ptr(OBERON_TYPE_VOID);
2266 oberon_make_multiarray(ctx, sizes -> next, base, &dim);
2268 oberon_make_array_type(ctx, sizes, dim, type);
2271 static void
2272 oberon_make_open_array(oberon_context_t * ctx, oberon_type_t * base, oberon_type_t * type)
2274 type -> class = OBERON_TYPE_ARRAY;
2275 type -> size = 0;
2276 type -> base = base;
2279 static void
2280 oberon_field_list(oberon_context_t * ctx, oberon_type_t * rec, oberon_scope_t * modscope)
2282 if(ctx -> token == IDENT)
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_FIELD, true, &num, &list);
2290 oberon_assert_token(ctx, COLON);
2292 oberon_scope_t * current = ctx -> decl;
2293 ctx -> decl = modscope;
2294 oberon_type(ctx, &type);
2295 ctx -> decl = current;
2297 oberon_object_t * field = list;
2298 for(int i = 0; i < num; i++)
2300 field -> type = type;
2301 field = field -> next;
2304 rec -> num_decl += num;
2308 static void
2309 oberon_type_record_body(oberon_context_t * ctx, oberon_type_t * rec)
2311 oberon_scope_t * modscope = ctx -> mod -> decl;
2312 oberon_scope_t * oldscope = ctx -> decl;
2313 ctx -> decl = modscope;
2315 if(ctx -> token == LPAREN)
2317 oberon_assert_token(ctx, LPAREN);
2319 oberon_object_t * typeobj;
2320 typeobj = oberon_qualident(ctx, NULL, true);
2322 if(typeobj -> class != OBERON_CLASS_TYPE)
2324 oberon_error(ctx, "base must be type");
2327 oberon_type_t * base = typeobj -> type;
2328 if(base -> class == OBERON_TYPE_POINTER)
2330 base = base -> base;
2333 if(base -> class != OBERON_TYPE_RECORD)
2335 oberon_error(ctx, "base must be record type");
2338 rec -> base = base;
2339 ctx -> decl = base -> scope;
2341 oberon_assert_token(ctx, RPAREN);
2343 else
2345 ctx -> decl = NULL;
2348 oberon_scope_t * this_scope;
2349 this_scope = oberon_open_scope(ctx);
2350 this_scope -> local = true;
2351 this_scope -> parent = NULL;
2352 this_scope -> parent_type = rec;
2354 oberon_field_list(ctx, rec, modscope);
2355 while(ctx -> token == SEMICOLON)
2357 oberon_assert_token(ctx, SEMICOLON);
2358 oberon_field_list(ctx, rec, modscope);
2361 rec -> scope = this_scope;
2362 rec -> decl = this_scope -> list -> next;
2363 ctx -> decl = oldscope;
2366 static void
2367 oberon_type(oberon_context_t * ctx, oberon_type_t ** type)
2369 if(ctx -> token == IDENT)
2371 oberon_qualident_type(ctx, type);
2373 else if(ctx -> token == ARRAY)
2375 oberon_assert_token(ctx, ARRAY);
2377 int num_sizes = 0;
2378 oberon_expr_t * sizes;
2380 if(ISEXPR(ctx -> token))
2382 oberon_expr_list(ctx, &num_sizes, &sizes, 1);
2385 oberon_assert_token(ctx, OF);
2387 oberon_type_t * base;
2388 base = oberon_new_type_ptr(OBERON_TYPE_VOID);
2389 oberon_type(ctx, &base);
2391 if(num_sizes == 0)
2393 oberon_make_open_array(ctx, base, *type);
2395 else
2397 oberon_make_multiarray(ctx, sizes, base, type);
2400 else if(ctx -> token == RECORD)
2402 oberon_type_t * rec;
2403 rec = *type;
2404 rec -> class = OBERON_TYPE_RECORD;
2405 rec -> module = ctx -> mod;
2407 oberon_assert_token(ctx, RECORD);
2408 oberon_type_record_body(ctx, rec);
2409 oberon_assert_token(ctx, END);
2411 *type = rec;
2413 else if(ctx -> token == POINTER)
2415 oberon_assert_token(ctx, POINTER);
2416 oberon_assert_token(ctx, TO);
2418 oberon_type_t * base;
2419 base = oberon_new_type_ptr(OBERON_TYPE_VOID);
2420 oberon_type(ctx, &base);
2422 oberon_type_t * ptr;
2423 ptr = *type;
2424 ptr -> class = OBERON_TYPE_POINTER;
2425 ptr -> base = base;
2427 else if(ctx -> token == PROCEDURE)
2429 oberon_open_scope(ctx);
2430 oberon_assert_token(ctx, PROCEDURE);
2431 oberon_opt_formal_pars(ctx, type);
2432 oberon_close_scope(ctx -> decl);
2434 else
2436 oberon_error(ctx, "invalid type declaration");
2440 static void
2441 oberon_type_decl(oberon_context_t * ctx)
2443 char * name;
2444 oberon_object_t * newtype;
2445 oberon_type_t * type;
2446 int export;
2447 int read_only;
2449 name = oberon_assert_ident(ctx);
2450 oberon_def(ctx, &export, &read_only);
2452 newtype = oberon_find_object(ctx -> decl, name, 0);
2453 if(newtype == NULL)
2455 newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE, export, read_only, false);
2456 newtype -> type = oberon_new_type_ptr(OBERON_TYPE_VOID);
2457 assert(newtype -> type);
2459 else
2461 if(newtype -> class != OBERON_CLASS_TYPE)
2463 oberon_error(ctx, "mult definition");
2466 if(newtype -> linked)
2468 oberon_error(ctx, "mult definition - already linked");
2471 newtype -> export = export;
2472 newtype -> read_only = read_only;
2475 oberon_assert_token(ctx, EQUAL);
2477 type = newtype -> type;
2478 oberon_type(ctx, &type);
2480 if(type -> class == OBERON_TYPE_VOID)
2482 oberon_error(ctx, "recursive alias declaration");
2485 newtype -> type = type;
2486 newtype -> linked = 1;
2489 static void oberon_prevent_recursive_object(oberon_context_t * ctx, oberon_object_t * x);
2490 static void oberon_prevent_recursive_type(oberon_context_t * ctx, oberon_type_t * type);
2492 static void
2493 oberon_prevent_recursive_pointer(oberon_context_t * ctx, oberon_type_t * type)
2495 if(type -> class != OBERON_TYPE_POINTER
2496 && type -> class != OBERON_TYPE_ARRAY)
2498 return;
2501 if(type -> recursive)
2503 oberon_error(ctx, "recursive pointer declaration");
2506 if(type -> class == OBERON_TYPE_POINTER
2507 && type -> base -> class == OBERON_TYPE_POINTER)
2509 oberon_error(ctx, "attempt to make pointer to pointer");
2512 type -> recursive = 1;
2514 oberon_prevent_recursive_pointer(ctx, type -> base);
2516 type -> recursive = 0;
2519 static void
2520 oberon_prevent_recursive_record(oberon_context_t * ctx, oberon_type_t * type)
2522 if(type -> class != OBERON_TYPE_RECORD)
2524 return;
2527 if(type -> recursive)
2529 oberon_error(ctx, "recursive record declaration");
2532 type -> recursive = 1;
2534 int num_fields = type -> num_decl;
2535 oberon_object_t * field = type -> decl;
2536 for(int i = 0; i < num_fields; i++)
2538 oberon_prevent_recursive_object(ctx, field);
2539 field = field -> next;
2542 type -> recursive = 0;
2544 static void
2545 oberon_prevent_recursive_procedure(oberon_context_t * ctx, oberon_type_t * type)
2547 if(type -> class != OBERON_TYPE_PROCEDURE)
2549 return;
2552 if(type -> recursive)
2554 oberon_error(ctx, "recursive procedure declaration");
2557 type -> recursive = 1;
2559 int num_fields = type -> num_decl;
2560 oberon_object_t * field = type -> decl;
2561 for(int i = 0; i < num_fields; i++)
2563 oberon_prevent_recursive_object(ctx, field);
2564 field = field -> next;
2567 type -> recursive = 0;
2570 static void
2571 oberon_prevent_recursive_array(oberon_context_t * ctx, oberon_type_t * type)
2573 if(type -> class != OBERON_TYPE_ARRAY)
2575 return;
2578 if(type -> recursive)
2580 oberon_error(ctx, "recursive array declaration");
2583 type -> recursive = 1;
2585 oberon_prevent_recursive_type(ctx, type -> base);
2587 type -> recursive = 0;
2590 static void
2591 oberon_prevent_recursive_type(oberon_context_t * ctx, oberon_type_t * type)
2593 if(type -> class == OBERON_TYPE_POINTER)
2595 oberon_prevent_recursive_pointer(ctx, type);
2597 else if(type -> class == OBERON_TYPE_RECORD)
2599 oberon_prevent_recursive_record(ctx, type);
2601 else if(type -> class == OBERON_TYPE_ARRAY)
2603 oberon_prevent_recursive_array(ctx, type);
2605 else if(type -> class == OBERON_TYPE_PROCEDURE)
2607 oberon_prevent_recursive_procedure(ctx, type);
2611 static void
2612 oberon_prevent_recursive_object(oberon_context_t * ctx, oberon_object_t * x)
2614 switch(x -> class)
2616 case OBERON_CLASS_VAR:
2617 case OBERON_CLASS_TYPE:
2618 case OBERON_CLASS_PARAM:
2619 case OBERON_CLASS_VAR_PARAM:
2620 case OBERON_CLASS_FIELD:
2621 oberon_prevent_recursive_type(ctx, x -> type);
2622 break;
2623 case OBERON_CLASS_CONST:
2624 case OBERON_CLASS_PROC:
2625 case OBERON_CLASS_MODULE:
2626 break;
2627 default:
2628 oberon_error(ctx, "oberon_prevent_recursive_object: wat");
2629 break;
2633 static void
2634 oberon_prevent_recursive_decl(oberon_context_t * ctx)
2636 oberon_object_t * x = ctx -> decl -> list -> next;
2638 while(x)
2640 oberon_prevent_recursive_object(ctx, x);
2641 x = x -> next;
2645 static void oberon_initialize_object(oberon_context_t * ctx, oberon_object_t * x);
2646 static void oberon_initialize_type(oberon_context_t * ctx, oberon_type_t * type);
2648 static void
2649 oberon_initialize_record_fields(oberon_context_t * ctx, oberon_type_t * type)
2651 if(type -> class != OBERON_TYPE_RECORD)
2653 return;
2656 int num_fields = type -> num_decl;
2657 oberon_object_t * field = type -> decl;
2658 for(int i = 0; i < num_fields; i++)
2660 if(field -> type -> class == OBERON_TYPE_POINTER)
2662 oberon_initialize_type(ctx, field -> type);
2665 oberon_initialize_object(ctx, field);
2666 field = field -> next;
2669 oberon_generator_init_record(ctx, type);
2672 static void
2673 oberon_initialize_type(oberon_context_t * ctx, oberon_type_t * type)
2675 if(type -> class == OBERON_TYPE_VOID)
2677 oberon_error(ctx, "undeclarated type");
2680 if(type -> initialized)
2682 return;
2685 type -> initialized = 1;
2687 if(type -> class == OBERON_TYPE_POINTER)
2689 oberon_initialize_type(ctx, type -> base);
2690 oberon_generator_init_type(ctx, type);
2692 else if(type -> class == OBERON_TYPE_ARRAY)
2694 if(type -> size != 0)
2696 if(type -> base -> class == OBERON_TYPE_ARRAY)
2698 if(type -> base -> size == 0)
2700 oberon_error(ctx, "open array not allowed as array element");
2705 oberon_initialize_type(ctx, type -> base);
2706 oberon_generator_init_type(ctx, type);
2708 else if(type -> class == OBERON_TYPE_RECORD)
2710 oberon_generator_init_type(ctx, type);
2711 oberon_initialize_record_fields(ctx, type);
2713 else if(type -> class == OBERON_TYPE_PROCEDURE)
2715 int num_fields = type -> num_decl;
2716 oberon_object_t * field = type -> decl;
2717 for(int i = 0; i < num_fields; i++)
2719 oberon_initialize_object(ctx, field);
2720 field = field -> next;
2721 }
2723 oberon_generator_init_type(ctx, type);
2725 else
2727 oberon_generator_init_type(ctx, type);
2731 static void
2732 oberon_initialize_object(oberon_context_t * ctx, oberon_object_t * x)
2734 if(x -> initialized)
2736 return;
2739 x -> initialized = 1;
2741 switch(x -> class)
2743 case OBERON_CLASS_TYPE:
2744 oberon_initialize_type(ctx, x -> type);
2745 break;
2746 case OBERON_CLASS_VAR:
2747 case OBERON_CLASS_FIELD:
2748 if(x -> type -> class == OBERON_TYPE_ARRAY)
2750 if(x -> type -> size == 0)
2752 oberon_error(ctx, "open array not allowed as variable or field");
2755 oberon_initialize_type(ctx, x -> type);
2756 oberon_generator_init_var(ctx, x);
2757 break;
2758 case OBERON_CLASS_PARAM:
2759 case OBERON_CLASS_VAR_PARAM:
2760 oberon_initialize_type(ctx, x -> type);
2761 oberon_generator_init_var(ctx, x);
2762 break;
2763 case OBERON_CLASS_CONST:
2764 case OBERON_CLASS_PROC:
2765 case OBERON_CLASS_MODULE:
2766 break;
2767 default:
2768 oberon_error(ctx, "oberon_initialize_object: wat");
2769 break;
2773 static void
2774 oberon_initialize_decl(oberon_context_t * ctx)
2776 oberon_object_t * x = ctx -> decl -> list;
2778 while(x -> next)
2780 oberon_initialize_object(ctx, x -> next);
2781 x = x -> next;
2782 }
2785 static void
2786 oberon_prevent_undeclarated_procedures(oberon_context_t * ctx)
2788 oberon_object_t * x = ctx -> decl -> list;
2790 while(x -> next)
2792 if(x -> next -> class == OBERON_CLASS_PROC)
2794 if(x -> next -> linked == 0)
2796 oberon_error(ctx, "unresolved forward declaration");
2799 x = x -> next;
2800 }
2803 static void
2804 oberon_decl_seq(oberon_context_t * ctx)
2806 if(ctx -> token == CONST)
2808 oberon_assert_token(ctx, CONST);
2809 while(ctx -> token == IDENT)
2811 oberon_const_decl(ctx);
2812 oberon_assert_token(ctx, SEMICOLON);
2816 if(ctx -> token == TYPE)
2818 oberon_assert_token(ctx, TYPE);
2819 while(ctx -> token == IDENT)
2821 oberon_type_decl(ctx);
2822 oberon_assert_token(ctx, SEMICOLON);
2826 if(ctx -> token == VAR)
2828 oberon_assert_token(ctx, VAR);
2829 while(ctx -> token == IDENT)
2831 oberon_var_decl(ctx);
2832 oberon_assert_token(ctx, SEMICOLON);
2836 oberon_prevent_recursive_decl(ctx);
2837 oberon_initialize_decl(ctx);
2839 while(ctx -> token == PROCEDURE)
2841 oberon_proc_decl(ctx);
2842 oberon_assert_token(ctx, SEMICOLON);
2845 oberon_prevent_undeclarated_procedures(ctx);
2848 static void
2849 oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
2851 if(dst -> read_only)
2853 oberon_error(ctx, "read-only destination");
2856 src = oberon_autocast_to(ctx, src, dst -> result);
2857 oberon_generate_assign(ctx, src, dst);
2860 static void
2861 oberon_statement(oberon_context_t * ctx)
2863 oberon_expr_t * item1;
2864 oberon_expr_t * item2;
2866 if(ctx -> token == IDENT)
2868 item1 = oberon_designator(ctx);
2869 if(ctx -> token == ASSIGN)
2871 oberon_assert_token(ctx, ASSIGN);
2872 item2 = oberon_expr(ctx);
2873 oberon_assign(ctx, item2, item1);
2875 else
2877 oberon_opt_proc_parens(ctx, item1);
2880 else if(ctx -> token == RETURN)
2882 oberon_assert_token(ctx, RETURN);
2883 if(ISEXPR(ctx -> token))
2885 oberon_expr_t * expr;
2886 expr = oberon_expr(ctx);
2887 oberon_make_return(ctx, expr);
2889 else
2891 oberon_make_return(ctx, NULL);
2896 static void
2897 oberon_statement_seq(oberon_context_t * ctx)
2899 oberon_statement(ctx);
2900 while(ctx -> token == SEMICOLON)
2902 oberon_assert_token(ctx, SEMICOLON);
2903 oberon_statement(ctx);
2907 static void
2908 oberon_import_module(oberon_context_t * ctx, char * alias, char * name)
2910 oberon_module_t * m = ctx -> module_list;
2911 while(m && strcmp(m -> name, name) != 0)
2913 m = m -> next;
2916 if(m == NULL)
2918 const char * code;
2919 code = ctx -> import_module(name);
2920 if(code == NULL)
2922 oberon_error(ctx, "no such module");
2925 m = oberon_compile_module(ctx, code);
2926 assert(m);
2929 if(m -> ready == 0)
2931 oberon_error(ctx, "cyclic module import");
2934 oberon_object_t * ident;
2935 ident = oberon_define_object(ctx -> decl, alias, OBERON_CLASS_MODULE, false, false, false);
2936 ident -> module = m;
2939 static void
2940 oberon_import_decl(oberon_context_t * ctx)
2942 char * alias;
2943 char * name;
2945 alias = name = oberon_assert_ident(ctx);
2946 if(ctx -> token == ASSIGN)
2948 oberon_assert_token(ctx, ASSIGN);
2949 name = oberon_assert_ident(ctx);
2952 oberon_import_module(ctx, alias, name);
2955 static void
2956 oberon_import_list(oberon_context_t * ctx)
2958 oberon_assert_token(ctx, IMPORT);
2960 oberon_import_decl(ctx);
2961 while(ctx -> token == COMMA)
2963 oberon_assert_token(ctx, COMMA);
2964 oberon_import_decl(ctx);
2967 oberon_assert_token(ctx, SEMICOLON);
2970 static void
2971 oberon_parse_module(oberon_context_t * ctx)
2973 char * name1;
2974 char * name2;
2975 oberon_read_token(ctx);
2977 oberon_assert_token(ctx, MODULE);
2978 name1 = oberon_assert_ident(ctx);
2979 oberon_assert_token(ctx, SEMICOLON);
2980 ctx -> mod -> name = name1;
2982 oberon_generator_init_module(ctx, ctx -> mod);
2984 if(ctx -> token == IMPORT)
2986 oberon_import_list(ctx);
2989 oberon_decl_seq(ctx);
2991 oberon_generate_begin_module(ctx);
2992 if(ctx -> token == BEGIN)
2994 oberon_assert_token(ctx, BEGIN);
2995 oberon_statement_seq(ctx);
2997 oberon_generate_end_module(ctx);
2999 oberon_assert_token(ctx, END);
3000 name2 = oberon_assert_ident(ctx);
3001 oberon_assert_token(ctx, DOT);
3003 if(strcmp(name1, name2) != 0)
3005 oberon_error(ctx, "module name not matched");
3008 oberon_generator_fini_module(ctx -> mod);
3011 // =======================================================================
3012 // LIBRARY
3013 // =======================================================================
3015 static void
3016 register_default_types(oberon_context_t * ctx)
3018 ctx -> void_type = oberon_new_type_ptr(OBERON_TYPE_VOID);
3019 oberon_generator_init_type(ctx, ctx -> void_type);
3021 ctx -> void_ptr_type = oberon_new_type_ptr(OBERON_TYPE_POINTER);
3022 ctx -> void_ptr_type -> base = ctx -> void_type;
3023 oberon_generator_init_type(ctx, ctx -> void_ptr_type);
3025 ctx -> string_type = oberon_new_type_string(1);
3026 oberon_generator_init_type(ctx, ctx -> string_type);
3028 ctx -> bool_type = oberon_new_type_boolean();
3029 oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type, 1);
3031 ctx -> byte_type = oberon_new_type_integer(1);
3032 oberon_define_type(ctx -> world_scope, "BYTE", ctx -> byte_type, 1);
3034 ctx -> shortint_type = oberon_new_type_integer(2);
3035 oberon_define_type(ctx -> world_scope, "SHORTINT", ctx -> shortint_type, 1);
3037 ctx -> int_type = oberon_new_type_integer(4);
3038 oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type, 1);
3040 ctx -> longint_type = oberon_new_type_integer(8);
3041 oberon_define_type(ctx -> world_scope, "LONGINT", ctx -> longint_type, 1);
3043 ctx -> real_type = oberon_new_type_real(4);
3044 oberon_define_type(ctx -> world_scope, "REAL", ctx -> real_type, 1);
3046 ctx -> longreal_type = oberon_new_type_real(8);
3047 oberon_define_type(ctx -> world_scope, "LONGREAL", ctx -> longreal_type, 1);
3049 ctx -> char_type = oberon_new_type_char(1);
3050 oberon_define_type(ctx -> world_scope, "CHAR", ctx -> char_type, 1);
3053 static void
3054 oberon_new_intrinsic(oberon_context_t * ctx, char * name, GenerateFuncCallback f, GenerateProcCallback p)
3056 oberon_object_t * proc;
3057 proc = oberon_define_object(ctx -> decl, name, OBERON_CLASS_PROC, true, false, false);
3058 proc -> type = oberon_new_type_ptr(OBERON_TYPE_PROCEDURE);
3059 proc -> type -> sysproc = true;
3060 proc -> type -> genfunc = f;
3061 proc -> type -> genproc = p;
3064 static oberon_expr_t *
3065 oberon_make_abs_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
3067 if(num_args < 1)
3069 oberon_error(ctx, "too few arguments");
3072 if(num_args > 1)
3074 oberon_error(ctx, "too mach arguments");
3077 oberon_expr_t * arg;
3078 arg = list_args;
3080 oberon_type_t * result_type;
3081 result_type = arg -> result;
3083 if(result_type -> class != OBERON_TYPE_INTEGER)
3085 oberon_error(ctx, "ABS accepts only integers");
3089 oberon_expr_t * expr;
3090 expr = oberon_new_operator(OP_ABS, result_type, arg, NULL);
3091 return expr;
3094 static void
3095 oberon_make_new_call(oberon_context_t * ctx, int num_args, oberon_expr_t * list_args)
3097 if(num_args < 1)
3099 oberon_error(ctx, "too few arguments");
3102 oberon_expr_t * dst;
3103 dst = list_args;
3105 oberon_type_t * type;
3106 type = dst -> result;
3108 if(type -> class != OBERON_TYPE_POINTER)
3110 oberon_error(ctx, "not a pointer");
3113 type = type -> base;
3115 oberon_expr_t * src;
3116 src = oberon_new_item(MODE_NEW, dst -> result, 0);
3117 src -> item.num_args = 0;
3118 src -> item.args = NULL;
3120 int max_args = 1;
3121 if(type -> class == OBERON_TYPE_ARRAY)
3123 if(type -> size == 0)
3125 oberon_type_t * x = type;
3126 while(x -> class == OBERON_TYPE_ARRAY)
3128 if(x -> size == 0)
3130 max_args += 1;
3132 x = x -> base;
3136 if(num_args < max_args)
3138 oberon_error(ctx, "too few arguments");
3141 if(num_args > max_args)
3143 oberon_error(ctx, "too mach arguments");
3146 int num_sizes = max_args - 1;
3147 oberon_expr_t * size_list = list_args -> next;
3149 oberon_expr_t * arg = size_list;
3150 for(int i = 0; i < max_args - 1; i++)
3152 if(arg -> result -> class != OBERON_TYPE_INTEGER)
3154 oberon_error(ctx, "size must be integer");
3156 arg = arg -> next;
3159 src -> item.num_args = num_sizes;
3160 src -> item.args = size_list;
3162 else if(type -> class != OBERON_TYPE_RECORD)
3164 oberon_error(ctx, "oberon_make_new_call: wat");
3167 if(num_args > max_args)
3169 oberon_error(ctx, "too mach arguments");
3172 oberon_assign(ctx, src, dst);
3175 oberon_context_t *
3176 oberon_create_context(ModuleImportCallback import_module)
3178 oberon_context_t * ctx = calloc(1, sizeof *ctx);
3180 oberon_scope_t * world_scope;
3181 world_scope = oberon_open_scope(ctx);
3182 ctx -> world_scope = world_scope;
3184 ctx -> import_module = import_module;
3186 oberon_generator_init_context(ctx);
3188 register_default_types(ctx);
3189 oberon_new_intrinsic(ctx, "ABS", oberon_make_abs_call, NULL);
3190 oberon_new_intrinsic(ctx, "NEW", NULL, oberon_make_new_call);
3192 return ctx;
3195 void
3196 oberon_destroy_context(oberon_context_t * ctx)
3198 oberon_generator_destroy_context(ctx);
3199 free(ctx);
3202 oberon_module_t *
3203 oberon_compile_module(oberon_context_t * ctx, const char * newcode)
3205 const char * code = ctx -> code;
3206 int code_index = ctx -> code_index;
3207 char c = ctx -> c;
3208 int token = ctx -> token;
3209 char * string = ctx -> string;
3210 int integer = ctx -> integer;
3211 int real = ctx -> real;
3212 bool longmode = ctx -> longmode;
3213 oberon_scope_t * decl = ctx -> decl;
3214 oberon_module_t * mod = ctx -> mod;
3216 oberon_scope_t * module_scope;
3217 module_scope = oberon_open_scope(ctx);
3219 oberon_module_t * module;
3220 module = calloc(1, sizeof *module);
3221 module -> decl = module_scope;
3222 module -> next = ctx -> module_list;
3224 ctx -> mod = module;
3225 ctx -> module_list = module;
3227 oberon_init_scaner(ctx, newcode);
3228 oberon_parse_module(ctx);
3230 module -> ready = 1;
3232 ctx -> code = code;
3233 ctx -> code_index = code_index;
3234 ctx -> c = c;
3235 ctx -> token = token;
3236 ctx -> string = string;
3237 ctx -> integer = integer;
3238 ctx -> real = real;
3239 ctx -> longmode = longmode;
3240 ctx -> decl = decl;
3241 ctx -> mod = mod;
3243 return module;