DEADSOFTWARE

7ca600e205a26e377f25bea0de64ff7ad0c758cf
[dsw-obn.git] / 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>
8 #include "oberon.h"
9 #include "generator.h"
11 enum {
12 EOF_ = 0,
13 IDENT,
14 MODULE,
15 SEMICOLON,
16 END,
17 DOT,
18 VAR,
19 COLON,
20 BEGIN,
21 ASSIGN,
22 INTEGER,
23 TRUE,
24 FALSE,
25 LPAREN,
26 RPAREN,
27 EQUAL,
28 NEQ,
29 LESS,
30 LEQ,
31 GREAT,
32 GEQ,
33 PLUS,
34 MINUS,
35 OR,
36 STAR,
37 SLASH,
38 DIV,
39 MOD,
40 AND,
41 NOT,
42 PROCEDURE,
43 COMMA,
44 RETURN,
45 CONST,
46 TYPE,
47 ARRAY,
48 OF,
49 LBRACE,
50 RBRACE,
51 RECORD,
52 POINTER,
53 TO
54 };
56 // =======================================================================
57 // UTILS
58 // =======================================================================
60 void
61 oberon_error(oberon_context_t * ctx, const char * fmt, ...)
62 {
63 va_list ptr;
64 va_start(ptr, fmt);
65 fprintf(stderr, "error: ");
66 vfprintf(stderr, fmt, ptr);
67 fprintf(stderr, "\n");
68 fprintf(stderr, " code_index = %i\n", ctx -> code_index);
69 fprintf(stderr, " c = %c\n", ctx -> c);
70 fprintf(stderr, " token = %i\n", ctx -> token);
71 va_end(ptr);
72 exit(1);
73 }
75 static oberon_type_t *
76 oberon_new_type_ptr(int class)
77 {
78 oberon_type_t * x = malloc(sizeof *x);
79 memset(x, 0, sizeof *x);
80 x -> class = class;
81 return x;
82 }
84 static oberon_type_t *
85 oberon_new_type_integer(int size)
86 {
87 oberon_type_t * x;
88 x = oberon_new_type_ptr(OBERON_TYPE_INTEGER);
89 x -> size = size;
90 return x;
91 }
93 static oberon_type_t *
94 oberon_new_type_boolean(int size)
95 {
96 oberon_type_t * x;
97 x = oberon_new_type_ptr(OBERON_TYPE_BOOLEAN);
98 x -> size = size;
99 return x;
102 // =======================================================================
103 // TABLE
104 // =======================================================================
106 static oberon_scope_t *
107 oberon_open_scope(oberon_context_t * ctx)
109 oberon_scope_t * scope = malloc(sizeof *scope);
110 memset(scope, 0, sizeof *scope);
112 oberon_object_t * list = malloc(sizeof *list);
113 memset(list, 0, sizeof *list);
115 scope -> ctx = ctx;
116 scope -> list = list;
117 scope -> up = ctx -> decl;
119 ctx -> decl = scope;
120 return scope;
123 static void
124 oberon_close_scope(oberon_scope_t * scope)
126 oberon_context_t * ctx = scope -> ctx;
127 ctx -> decl = scope -> up;
130 static oberon_object_t *
131 oberon_define_object(oberon_scope_t * scope, char * name, int class)
133 oberon_object_t * x = scope -> list;
134 while(x -> next && strcmp(x -> next -> name, name) != 0)
136 x = x -> next;
139 if(x -> next)
141 oberon_error(scope -> ctx, "already defined");
144 oberon_object_t * newvar = malloc(sizeof *newvar);
145 memset(newvar, 0, sizeof *newvar);
146 newvar -> name = name;
147 newvar -> class = class;
149 x -> next = newvar;
151 return newvar;
154 static void
155 oberon_define_field(oberon_context_t * ctx, oberon_type_t * rec, char * name, oberon_type_t * type)
157 oberon_object_t * x = rec -> decl;
158 while(x -> next && strcmp(x -> next -> name, name) != 0)
160 x = x -> next;
163 if(x -> next)
165 oberon_error(ctx, "multiple definition");
168 oberon_object_t * field = malloc(sizeof *field);
169 memset(field, 0, sizeof *field);
170 field -> name = name;
171 field -> class = OBERON_CLASS_FIELD;
172 field -> type = type;
174 rec -> num_decl += 1;
175 oberon_generator_init_var(ctx, field);
177 x -> next = field;
180 static oberon_object_t *
181 oberon_find_object_in_list(oberon_object_t * list, char * name)
183 oberon_object_t * x = list;
184 while(x -> next && strcmp(x -> next -> name, name) != 0)
186 x = x -> next;
188 return x -> next;
191 static oberon_object_t *
192 oberon_find_object(oberon_scope_t * scope, char * name)
194 oberon_object_t * result = NULL;
196 oberon_scope_t * s = scope;
197 while(result == NULL && s != NULL)
199 result = oberon_find_object_in_list(s -> list, name);
200 s = s -> up;
203 if(result == NULL)
205 oberon_error(scope -> ctx, "undefined ident %s", name);
208 return result;
211 static oberon_object_t *
212 oberon_find_field(oberon_context_t * ctx, oberon_type_t * rec, char * name)
214 oberon_object_t * x = rec -> decl;
215 for(int i = 0; i < rec -> num_decl; i++)
217 if(strcmp(x -> name, name) == 0)
219 return x;
221 x = x -> next;
224 oberon_error(ctx, "field not defined");
226 return NULL;
229 static oberon_object_t *
230 oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type)
232 oberon_object_t * id;
233 id = oberon_define_object(scope, name, OBERON_CLASS_TYPE);
234 id -> type = type;
235 oberon_generator_init_type(scope -> ctx, type);
236 return id;
239 static oberon_type_t *
240 oberon_find_type(oberon_scope_t * scope, char * name)
242 oberon_object_t * x = oberon_find_object(scope, name);
243 if(x -> class != OBERON_CLASS_TYPE)
245 oberon_error(scope -> ctx, "%s not a type", name);
248 return x -> type;
251 static oberon_object_t *
252 oberon_define_var(oberon_scope_t * scope, int class, char * name, oberon_type_t * type)
254 oberon_object_t * var;
255 var = oberon_define_object(scope, name, class);
256 var -> type = type;
257 oberon_generator_init_var(scope -> ctx, var);
258 return var;
261 /*
262 static oberon_object_t *
263 oberon_find_var(oberon_scope_t * scope, char * name)
265 oberon_object_t * x = oberon_find_object(scope, name);
267 if(x -> class != OBERON_CLASS_VAR)
269 oberon_error(scope -> ctx, "%s not a var", name);
272 return x;
274 */
276 static oberon_object_t *
277 oberon_define_proc(oberon_scope_t * scope, char * name, oberon_type_t * signature)
279 oberon_object_t * proc;
280 proc = oberon_define_object(scope, name, OBERON_CLASS_PROC);
281 proc -> type = signature;
282 oberon_generator_init_proc(scope -> ctx, proc);
283 return proc;
286 // =======================================================================
287 // SCANER
288 // =======================================================================
290 static void
291 oberon_get_char(oberon_context_t * ctx)
293 ctx -> code_index += 1;
294 ctx -> c = ctx -> code[ctx -> code_index];
297 static void
298 oberon_init_scaner(oberon_context_t * ctx, const char * code)
300 ctx -> code = code;
301 ctx -> code_index = 0;
302 ctx -> c = ctx -> code[ctx -> code_index];
305 static void
306 oberon_read_ident(oberon_context_t * ctx)
308 int len = 0;
309 int i = ctx -> code_index;
311 int c = ctx -> code[i];
312 while(isalnum(c))
314 i += 1;
315 len += 1;
316 c = ctx -> code[i];
319 char * ident = malloc(len + 1);
320 memcpy(ident, &ctx->code[ctx->code_index], len);
321 ident[len] = 0;
323 ctx -> code_index = i;
324 ctx -> c = ctx -> code[i];
325 ctx -> string = ident;
326 ctx -> token = IDENT;
328 if(strcmp(ident, "MODULE") == 0)
330 ctx -> token = MODULE;
332 else if(strcmp(ident, "END") == 0)
334 ctx -> token = END;
336 else if(strcmp(ident, "VAR") == 0)
338 ctx -> token = VAR;
340 else if(strcmp(ident, "BEGIN") == 0)
342 ctx -> token = BEGIN;
344 else if(strcmp(ident, "TRUE") == 0)
346 ctx -> token = TRUE;
348 else if(strcmp(ident, "FALSE") == 0)
350 ctx -> token = FALSE;
352 else if(strcmp(ident, "OR") == 0)
354 ctx -> token = OR;
356 else if(strcmp(ident, "DIV") == 0)
358 ctx -> token = DIV;
360 else if(strcmp(ident, "MOD") == 0)
362 ctx -> token = MOD;
364 else if(strcmp(ident, "PROCEDURE") == 0)
366 ctx -> token = PROCEDURE;
368 else if(strcmp(ident, "RETURN") == 0)
370 ctx -> token = RETURN;
372 else if(strcmp(ident, "CONST") == 0)
374 ctx -> token = CONST;
376 else if(strcmp(ident, "TYPE") == 0)
378 ctx -> token = TYPE;
380 else if(strcmp(ident, "ARRAY") == 0)
382 ctx -> token = ARRAY;
384 else if(strcmp(ident, "OF") == 0)
386 ctx -> token = OF;
388 else if(strcmp(ident, "RECORD") == 0)
390 ctx -> token = RECORD;
392 else if(strcmp(ident, "POINTER") == 0)
394 ctx -> token = POINTER;
396 else if(strcmp(ident, "TO") == 0)
398 ctx -> token = TO;
402 static void
403 oberon_read_integer(oberon_context_t * ctx)
405 int len = 0;
406 int i = ctx -> code_index;
408 int c = ctx -> code[i];
409 while(isdigit(c))
411 i += 1;
412 len += 1;
413 c = ctx -> code[i];
416 char * ident = malloc(len + 2);
417 memcpy(ident, &ctx->code[ctx->code_index], len);
418 ident[len + 1] = 0;
420 ctx -> code_index = i;
421 ctx -> c = ctx -> code[i];
422 ctx -> string = ident;
423 ctx -> integer = atoi(ident);
424 ctx -> token = INTEGER;
427 static void
428 oberon_skip_space(oberon_context_t * ctx)
430 while(isspace(ctx -> c))
432 oberon_get_char(ctx);
436 static void
437 oberon_read_symbol(oberon_context_t * ctx)
439 int c = ctx -> c;
440 switch(c)
442 case 0:
443 ctx -> token = EOF_;
444 break;
445 case ';':
446 ctx -> token = SEMICOLON;
447 oberon_get_char(ctx);
448 break;
449 case ':':
450 ctx -> token = COLON;
451 oberon_get_char(ctx);
452 if(ctx -> c == '=')
454 ctx -> token = ASSIGN;
455 oberon_get_char(ctx);
457 break;
458 case '.':
459 ctx -> token = DOT;
460 oberon_get_char(ctx);
461 break;
462 case '(':
463 ctx -> token = LPAREN;
464 oberon_get_char(ctx);
465 break;
466 case ')':
467 ctx -> token = RPAREN;
468 oberon_get_char(ctx);
469 break;
470 case '=':
471 ctx -> token = EQUAL;
472 oberon_get_char(ctx);
473 break;
474 case '#':
475 ctx -> token = NEQ;
476 oberon_get_char(ctx);
477 break;
478 case '<':
479 ctx -> token = LESS;
480 oberon_get_char(ctx);
481 if(ctx -> c == '=')
483 ctx -> token = LEQ;
484 oberon_get_char(ctx);
486 break;
487 case '>':
488 ctx -> token = GREAT;
489 oberon_get_char(ctx);
490 if(ctx -> c == '=')
492 ctx -> token = GEQ;
493 oberon_get_char(ctx);
495 break;
496 case '+':
497 ctx -> token = PLUS;
498 oberon_get_char(ctx);
499 break;
500 case '-':
501 ctx -> token = MINUS;
502 oberon_get_char(ctx);
503 break;
504 case '*':
505 ctx -> token = STAR;
506 oberon_get_char(ctx);
507 break;
508 case '/':
509 ctx -> token = SLASH;
510 oberon_get_char(ctx);
511 break;
512 case '&':
513 ctx -> token = AND;
514 oberon_get_char(ctx);
515 break;
516 case '~':
517 ctx -> token = NOT;
518 oberon_get_char(ctx);
519 break;
520 case ',':
521 ctx -> token = COMMA;
522 oberon_get_char(ctx);
523 break;
524 case '[':
525 ctx -> token = LBRACE;
526 oberon_get_char(ctx);
527 break;
528 case ']':
529 ctx -> token = RBRACE;
530 oberon_get_char(ctx);
531 break;
532 default:
533 oberon_error(ctx, "invalid char");
534 break;
538 static void
539 oberon_read_token(oberon_context_t * ctx)
541 oberon_skip_space(ctx);
543 int c = ctx -> c;
544 if(isalpha(c))
546 oberon_read_ident(ctx);
548 else if(isdigit(c))
550 oberon_read_integer(ctx);
552 else
554 oberon_read_symbol(ctx);
558 // =======================================================================
559 // EXPRESSION
560 // =======================================================================
562 static void oberon_expect_token(oberon_context_t * ctx, int token);
563 static oberon_expr_t * oberon_expr(oberon_context_t * ctx);
564 static void oberon_assert_token(oberon_context_t * ctx, int token);
565 static char * oberon_assert_ident(oberon_context_t * ctx);
566 static oberon_type_t * oberon_type(oberon_context_t * ctx);
568 static oberon_expr_t *
569 oberon_new_operator(int op, oberon_type_t * result, oberon_expr_t * left, oberon_expr_t * right)
571 oberon_oper_t * operator;
572 operator = malloc(sizeof *operator);
573 memset(operator, 0, sizeof *operator);
575 operator -> is_item = 0;
576 operator -> result = result;
577 operator -> op = op;
578 operator -> left = left;
579 operator -> right = right;
581 return (oberon_expr_t *) operator;
584 static oberon_expr_t *
585 oberon_new_item(int mode, oberon_type_t * result)
587 oberon_item_t * item;
588 item = malloc(sizeof *item);
589 memset(item, 0, sizeof *item);
591 item -> is_item = 1;
592 item -> result = result;
593 item -> mode = mode;
595 return (oberon_expr_t *)item;
598 static oberon_expr_t *
599 oberon_make_unary_op(oberon_context_t * ctx, int token, oberon_expr_t * a)
601 oberon_expr_t * expr;
602 oberon_type_t * result;
604 result = a -> result;
606 if(token == MINUS)
608 if(result -> class != OBERON_TYPE_INTEGER)
610 oberon_error(ctx, "incompatible operator type");
613 expr = oberon_new_operator(OP_UNARY_MINUS, result, a, NULL);
615 else if(token == NOT)
617 if(result -> class != OBERON_TYPE_BOOLEAN)
619 oberon_error(ctx, "incompatible operator type");
622 expr = oberon_new_operator(OP_LOGIC_NOT, result, a, NULL);
624 else
626 oberon_error(ctx, "oberon_make_unary_op: wat");
629 return expr;
632 static void
633 oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first)
635 oberon_expr_t * last;
637 *num_expr = 1;
638 *first = last = oberon_expr(ctx);
639 while(ctx -> token == COMMA)
641 oberon_assert_token(ctx, COMMA);
642 oberon_expr_t * current;
643 current = oberon_expr(ctx);
644 last -> next = current;
645 last = current;
646 *num_expr += 1;
650 static oberon_expr_t *
651 oberon_autocast_to(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * pref)
653 if(pref -> class != expr -> result -> class)
655 oberon_error(ctx, "incompatible types");
659 if(pref -> class == OBERON_TYPE_INTEGER)
661 if(expr -> result -> class > pref -> class)
663 oberon_error(ctx, "incompatible size");
666 else if(pref -> class == OBERON_TYPE_RECORD)
668 if(expr -> result != pref)
670 printf("oberon_autocast_to: rec %p != %p\n", expr -> result, pref);
671 oberon_error(ctx, "incompatible record types");
675 // TODO cast
677 return expr;
680 static void
681 oberon_autocast_call(oberon_context_t * ctx, oberon_expr_t * desig)
683 if(desig -> is_item == 0)
685 oberon_error(ctx, "expected item");
688 if(desig -> item.mode != MODE_CALL)
690 oberon_error(ctx, "expected mode CALL");
693 if(desig -> item.var -> class != OBERON_CLASS_PROC)
695 oberon_error(ctx, "only procedures can be called");
698 oberon_type_t * fn = desig -> item.var -> type;
699 int num_args = desig -> item.num_args;
700 int num_decl = fn -> num_decl;
702 if(num_args < num_decl)
704 oberon_error(ctx, "too few arguments");
706 else if(num_args > num_decl)
708 oberon_error(ctx, "too many arguments");
711 oberon_expr_t * arg = desig -> item.args;
712 oberon_object_t * param = fn -> decl;
713 for(int i = 0; i < num_args; i++)
715 oberon_autocast_to(ctx, arg, param -> type);
716 arg = arg -> next;
717 param = param -> next;
721 #define ISEXPR(x) \
722 (((x) == PLUS) \
723 || ((x) == MINUS) \
724 || ((x) == IDENT) \
725 || ((x) == INTEGER) \
726 || ((x) == LPAREN) \
727 || ((x) == NOT) \
728 || ((x) == TRUE) \
729 || ((x) == FALSE))
731 #define ISSELECTOR(x) \
732 (((x) == LBRACE) \
733 || ((x) == DOT))
735 static oberon_expr_t *
736 oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, int num_indexes, oberon_expr_t * indexes)
738 assert(desig -> is_item == 1);
740 if(desig -> item.mode != MODE_VAR)
742 oberon_error(ctx, "not MODE_VAR");
745 int class = desig -> item.var -> class;
746 switch(class)
748 case OBERON_CLASS_VAR:
749 case OBERON_CLASS_VAR_PARAM:
750 case OBERON_CLASS_PARAM:
751 break;
752 default:
753 oberon_error(ctx, "not variable");
754 break;
757 oberon_type_t * type = desig -> item.var -> type;
758 if(type -> class != OBERON_TYPE_ARRAY)
760 oberon_error(ctx, "not array");
763 int dim = desig -> item.var -> type -> dim;
764 if(num_indexes != dim)
766 oberon_error(ctx, "dimesions not matched");
769 oberon_type_t * base = desig -> item.var -> type -> base;
771 oberon_expr_t * selector;
772 selector = oberon_new_item(MODE_INDEX, base);
773 selector -> item.parent = (oberon_item_t *) desig;
774 selector -> item.num_args = num_indexes;
775 selector -> item.args = indexes;
777 return selector;
780 static oberon_expr_t *
781 oberon_make_record_selector(oberon_context_t * ctx, oberon_expr_t * expr, char * name)
783 assert(expr -> is_item == 1);
785 int class = expr -> result -> class;
786 if(class != OBERON_TYPE_RECORD)
788 oberon_error(ctx, "not record");
791 oberon_type_t * rec = expr -> result;
793 oberon_object_t * field;
794 field = oberon_find_field(ctx, rec, name);
796 oberon_expr_t * selector;
797 selector = oberon_new_item(MODE_FIELD, field -> type);
798 selector -> item.var = field;
799 selector -> item.parent = (oberon_item_t *) expr;
801 return selector;
804 static oberon_expr_t *
805 oberon_designator(oberon_context_t * ctx)
807 char * name;
808 oberon_object_t * var;
809 oberon_expr_t * expr;
811 name = oberon_assert_ident(ctx);
812 var = oberon_find_object(ctx -> decl, name);
814 switch(var -> class)
816 case OBERON_CLASS_CONST:
817 // TODO copy value
818 expr = (oberon_expr_t *) var -> value;
819 break;
820 case OBERON_CLASS_VAR:
821 case OBERON_CLASS_VAR_PARAM:
822 case OBERON_CLASS_PARAM:
823 expr = oberon_new_item(MODE_VAR, var -> type);
824 break;
825 case OBERON_CLASS_PROC:
826 expr = oberon_new_item(MODE_CALL, var -> type);
827 break;
828 default:
829 oberon_error(ctx, "invalid designator");
830 break;
832 expr -> item.var = var;
834 while(ISSELECTOR(ctx -> token))
836 switch(ctx -> token)
838 case DOT:
839 oberon_assert_token(ctx, DOT);
840 name = oberon_assert_ident(ctx);
841 expr = oberon_make_record_selector(ctx, expr, name);
842 break;
843 case LBRACE:
844 oberon_assert_token(ctx, LBRACE);
845 int num_indexes = 0;
846 oberon_expr_t * indexes = NULL;
847 oberon_expr_list(ctx, &num_indexes, &indexes);
848 oberon_assert_token(ctx, RBRACE);
849 expr = oberon_make_array_selector(ctx, expr, num_indexes, indexes);
850 break;
851 default:
852 oberon_error(ctx, "oberon_designator: wat");
853 break;
856 return expr;
859 static oberon_expr_t *
860 oberon_opt_proc_parens(oberon_context_t * ctx, oberon_expr_t * expr)
862 assert(expr -> is_item == 1);
864 if(ctx -> token == LPAREN)
866 if(expr -> result -> class != OBERON_TYPE_PROCEDURE)
868 oberon_error(ctx, "not a procedure");
871 oberon_assert_token(ctx, LPAREN);
873 int num_args = 0;
874 oberon_expr_t * arguments = NULL;
876 if(ISEXPR(ctx -> token))
878 oberon_expr_list(ctx, &num_args, &arguments);
881 expr -> result = expr -> item.var -> type -> base;
882 expr -> item.mode = MODE_CALL;
883 expr -> item.num_args = num_args;
884 expr -> item.args = arguments;
885 oberon_assert_token(ctx, RPAREN);
887 oberon_autocast_call(ctx, expr);
890 return expr;
893 static oberon_expr_t *
894 oberon_factor(oberon_context_t * ctx)
896 oberon_expr_t * expr;
898 switch(ctx -> token)
900 case IDENT:
901 expr = oberon_designator(ctx);
902 expr = oberon_opt_proc_parens(ctx, expr);
903 break;
904 case INTEGER:
905 expr = oberon_new_item(MODE_INTEGER, ctx -> int_type);
906 expr -> item.integer = ctx -> integer;
907 oberon_assert_token(ctx, INTEGER);
908 break;
909 case TRUE:
910 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
911 expr -> item.boolean = 1;
912 oberon_assert_token(ctx, TRUE);
913 break;
914 case FALSE:
915 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
916 expr -> item.boolean = 0;
917 oberon_assert_token(ctx, FALSE);
918 break;
919 case LPAREN:
920 oberon_assert_token(ctx, LPAREN);
921 expr = oberon_expr(ctx);
922 oberon_assert_token(ctx, RPAREN);
923 break;
924 case NOT:
925 oberon_assert_token(ctx, NOT);
926 expr = oberon_factor(ctx);
927 expr = oberon_make_unary_op(ctx, NOT, expr);
928 break;
929 default:
930 oberon_error(ctx, "invalid expression");
933 return expr;
936 /*
937 * oberon_autocast_binary_op автоматически переобразовывеат тип по след. правилам:
938 * 1. Классы обоих типов должны быть одинаковы
939 * 2. В качестве результата должен быть выбран больший тип.
940 * 3. Если размер результат не должен быть меньше чем базовый int
941 */
943 static void
944 oberon_autocast_binary_op(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b, oberon_type_t ** result)
946 if((a -> class) != (b -> class))
948 oberon_error(ctx, "incompatible types");
951 if((a -> size) > (b -> size))
953 *result = a;
955 else
957 *result = b;
960 if(((*result) -> class) == OBERON_TYPE_INTEGER)
962 if(((*result) -> size) < (ctx -> int_type -> size))
964 *result = ctx -> int_type;
968 /* TODO: cast types */
971 #define ITMAKESBOOLEAN(x) \
972 (((x) >= EQUAL && (x) <= GEQ) || ((x) == OR) || ((x) == AND))
974 #define ITUSEONLYINTEGER(x) \
975 ((x) >= LESS && (x) <= GEQ)
977 #define ITUSEONLYBOOLEAN(x) \
978 (((x) == OR) || ((x) == AND))
980 static oberon_expr_t *
981 oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
983 oberon_expr_t * expr;
984 oberon_type_t * result;
986 if(ITMAKESBOOLEAN(token))
988 if(ITUSEONLYINTEGER(token))
990 if(a -> result -> class != OBERON_TYPE_INTEGER
991 || b -> result -> class != OBERON_TYPE_INTEGER)
993 oberon_error(ctx, "used only with integer types");
996 else if(ITUSEONLYBOOLEAN(token))
998 if(a -> result -> class != OBERON_TYPE_BOOLEAN
999 || b -> result -> class != OBERON_TYPE_BOOLEAN)
1001 oberon_error(ctx, "used only with boolean type");
1005 result = ctx -> bool_type;
1007 if(token == EQUAL)
1009 expr = oberon_new_operator(OP_EQ, result, a, b);
1011 else if(token == NEQ)
1013 expr = oberon_new_operator(OP_NEQ, result, a, b);
1015 else if(token == LESS)
1017 expr = oberon_new_operator(OP_LSS, result, a, b);
1019 else if(token == LEQ)
1021 expr = oberon_new_operator(OP_LEQ, result, a, b);
1023 else if(token == GREAT)
1025 expr = oberon_new_operator(OP_GRT, result, a, b);
1027 else if(token == GEQ)
1029 expr = oberon_new_operator(OP_GEQ, result, a, b);
1031 else if(token == OR)
1033 expr = oberon_new_operator(OP_LOGIC_OR, result, a, b);
1035 else if(token == AND)
1037 expr = oberon_new_operator(OP_LOGIC_AND, result, a, b);
1039 else
1041 oberon_error(ctx, "oberon_make_bin_op: bool wat");
1044 else
1046 oberon_autocast_binary_op(ctx, a -> result, b -> result, &result);
1048 if(token == PLUS)
1050 expr = oberon_new_operator(OP_ADD, result, a, b);
1052 else if(token == MINUS)
1054 expr = oberon_new_operator(OP_SUB, result, a, b);
1056 else if(token == STAR)
1058 expr = oberon_new_operator(OP_MUL, result, a, b);
1060 else if(token == SLASH)
1062 expr = oberon_new_operator(OP_DIV, result, a, b);
1064 else if(token == DIV)
1066 expr = oberon_new_operator(OP_DIV, result, a, b);
1068 else if(token == MOD)
1070 expr = oberon_new_operator(OP_MOD, result, a, b);
1072 else
1074 oberon_error(ctx, "oberon_make_bin_op: bin wat");
1078 return expr;
1081 #define ISMULOP(x) \
1082 ((x) >= STAR && (x) <= AND)
1084 static oberon_expr_t *
1085 oberon_term_expr(oberon_context_t * ctx)
1087 oberon_expr_t * expr;
1089 expr = oberon_factor(ctx);
1090 while(ISMULOP(ctx -> token))
1092 int token = ctx -> token;
1093 oberon_read_token(ctx);
1095 oberon_expr_t * inter = oberon_factor(ctx);
1096 expr = oberon_make_bin_op(ctx, token, expr, inter);
1099 return expr;
1102 #define ISADDOP(x) \
1103 ((x) >= PLUS && (x) <= OR)
1105 static oberon_expr_t *
1106 oberon_simple_expr(oberon_context_t * ctx)
1108 oberon_expr_t * expr;
1110 int minus = 0;
1111 if(ctx -> token == PLUS)
1113 minus = 0;
1114 oberon_assert_token(ctx, PLUS);
1116 else if(ctx -> token == MINUS)
1118 minus = 1;
1119 oberon_assert_token(ctx, MINUS);
1122 expr = oberon_term_expr(ctx);
1123 while(ISADDOP(ctx -> token))
1125 int token = ctx -> token;
1126 oberon_read_token(ctx);
1128 oberon_expr_t * inter = oberon_term_expr(ctx);
1129 expr = oberon_make_bin_op(ctx, token, expr, inter);
1132 if(minus)
1134 expr = oberon_make_unary_op(ctx, MINUS, expr);
1137 return expr;
1140 #define ISRELATION(x) \
1141 ((x) >= EQUAL && (x) <= GEQ)
1143 static oberon_expr_t *
1144 oberon_expr(oberon_context_t * ctx)
1146 oberon_expr_t * expr;
1148 expr = oberon_simple_expr(ctx);
1149 while(ISRELATION(ctx -> token))
1151 int token = ctx -> token;
1152 oberon_read_token(ctx);
1154 oberon_expr_t * inter = oberon_simple_expr(ctx);
1155 expr = oberon_make_bin_op(ctx, token, expr, inter);
1158 return expr;
1161 static oberon_item_t *
1162 oberon_const_expr(oberon_context_t * ctx)
1164 oberon_expr_t * expr;
1165 expr = oberon_expr(ctx);
1167 if(expr -> is_item == 0)
1169 oberon_error(ctx, "const expression are required");
1172 return (oberon_item_t *) expr;
1175 // =======================================================================
1176 // PARSER
1177 // =======================================================================
1179 static void oberon_statement_seq(oberon_context_t * ctx);
1181 static void
1182 oberon_expect_token(oberon_context_t * ctx, int token)
1184 if(ctx -> token != token)
1186 oberon_error(ctx, "unexpected token %i (%i)", ctx -> token, token);
1190 static void
1191 oberon_assert_token(oberon_context_t * ctx, int token)
1193 oberon_expect_token(ctx, token);
1194 oberon_read_token(ctx);
1197 static char *
1198 oberon_assert_ident(oberon_context_t * ctx)
1200 oberon_expect_token(ctx, IDENT);
1201 char * ident = ctx -> string;
1202 oberon_read_token(ctx);
1203 return ident;
1206 static oberon_type_t *
1207 oberon_make_array_type(oberon_context_t * ctx, int dim, oberon_item_t * size, oberon_type_t * base)
1209 assert(dim == 1);
1210 oberon_type_t * newtype;
1212 if(size -> mode != MODE_INTEGER)
1214 oberon_error(ctx, "requires integer constant");
1217 newtype = oberon_new_type_ptr(OBERON_TYPE_ARRAY);
1218 newtype -> dim = dim;
1219 newtype -> size = size -> integer;
1220 newtype -> base = base;
1221 oberon_generator_init_type(ctx, newtype);
1223 return newtype;
1226 static void
1227 oberon_field_list(oberon_context_t * ctx, oberon_type_t * rec)
1229 if(ctx -> token == IDENT)
1231 char * name;
1232 oberon_type_t * type;
1233 name = oberon_assert_ident(ctx);
1234 oberon_assert_token(ctx, COLON);
1235 type = oberon_type(ctx);
1236 oberon_define_field(ctx, rec, name, type);
1240 static oberon_type_t *
1241 oberon_make_pointer(oberon_context_t * ctx, oberon_type_t * type)
1243 if(type -> class == OBERON_TYPE_POINTER)
1245 return type;
1248 if(type -> class == OBERON_TYPE_INTEGER
1249 || type -> class == OBERON_TYPE_BOOLEAN
1250 || type -> class == OBERON_TYPE_PROCEDURE
1251 || type -> class == OBERON_TYPE_VOID)
1253 oberon_error(ctx, "oberon not support pointers to non structure types");
1256 oberon_type_t * newtype;
1257 newtype = oberon_new_type_ptr(OBERON_TYPE_POINTER);
1258 newtype -> base = type;
1260 oberon_generator_init_type(ctx, newtype);
1262 return newtype;
1265 static oberon_type_t * oberon_opt_formal_pars(oberon_context_t * ctx, int class);
1267 static oberon_type_t *
1268 oberon_type(oberon_context_t * ctx)
1270 oberon_type_t * type;
1272 if(ctx -> token == IDENT)
1274 char * name = oberon_assert_ident(ctx);
1275 type = oberon_find_type(ctx -> decl, name);
1277 else if(ctx -> token == ARRAY)
1279 oberon_assert_token(ctx, ARRAY);
1280 oberon_item_t * size = oberon_const_expr(ctx);
1281 oberon_assert_token(ctx, OF);
1282 oberon_type_t * base = oberon_type(ctx);
1283 type = oberon_make_array_type(ctx, 1, size, base);
1285 else if(ctx -> token == RECORD)
1287 type = oberon_new_type_ptr(OBERON_TYPE_RECORD);
1288 oberon_object_t * list = malloc(sizeof *list);
1289 memset(list, 0, sizeof *list);
1290 type -> num_decl = 0;
1291 type -> base = NULL;
1292 type -> decl = list;
1294 oberon_assert_token(ctx, RECORD);
1295 oberon_field_list(ctx, type);
1296 while(ctx -> token == SEMICOLON)
1298 oberon_assert_token(ctx, SEMICOLON);
1299 oberon_field_list(ctx, type);
1301 oberon_assert_token(ctx, END);
1303 type -> decl = type -> decl -> next;
1304 oberon_generator_init_type(ctx, type);
1306 else if(ctx -> token == POINTER)
1308 oberon_assert_token(ctx, POINTER);
1309 oberon_assert_token(ctx, TO);
1310 type = oberon_type(ctx);
1311 type = oberon_make_pointer(ctx, type);
1313 else if(ctx -> token == PROCEDURE)
1315 oberon_assert_token(ctx, PROCEDURE);
1316 type = oberon_opt_formal_pars(ctx, OBERON_TYPE_PROCEDURE);
1318 else
1320 oberon_error(ctx, "invalid type declaration");
1323 return type;
1326 static void
1327 oberon_var_decl(oberon_context_t * ctx)
1329 char * name = oberon_assert_ident(ctx);
1330 oberon_assert_token(ctx, COLON);
1331 oberon_type_t * type = oberon_type(ctx);
1332 oberon_define_var(ctx -> decl, OBERON_CLASS_VAR, name, type);
1335 static oberon_object_t *
1336 oberon_make_param(oberon_context_t * ctx, int token, char * name, oberon_type_t * type)
1338 oberon_object_t * param;
1340 if(token == VAR)
1342 param = oberon_define_var(ctx -> decl, OBERON_CLASS_VAR_PARAM, name, type);
1344 else if(token == IDENT)
1346 param = oberon_define_var(ctx -> decl, OBERON_CLASS_PARAM, name, type);
1348 else
1350 oberon_error(ctx, "oberon_make_param: wat");
1353 return param;
1356 static oberon_object_t *
1357 oberon_fp_section(oberon_context_t * ctx, int * num_decl)
1359 int modifer_token = ctx -> token;
1360 if(ctx -> token == VAR)
1362 oberon_read_token(ctx);
1365 char * name;
1366 name = oberon_assert_ident(ctx);
1368 oberon_assert_token(ctx, COLON);
1370 oberon_type_t * type;
1371 type = oberon_type(ctx);
1373 oberon_object_t * first;
1374 first = oberon_make_param(ctx, modifer_token, name, type);
1376 *num_decl += 1;
1377 return first;
1380 #define ISFPSECTION \
1381 ((ctx -> token == VAR) || (ctx -> token == IDENT))
1383 static oberon_type_t *
1384 oberon_formal_pars(oberon_context_t * ctx)
1386 oberon_type_t * tp;
1387 tp = oberon_new_type_ptr(OBERON_TYPE_PROCEDURE);
1388 tp -> num_decl = 0;
1389 tp -> base = ctx -> void_type;
1390 tp -> decl = NULL;
1392 oberon_assert_token(ctx, LPAREN);
1394 if(ISFPSECTION)
1396 tp -> decl = oberon_fp_section(ctx, &tp -> num_decl);
1397 while(ctx -> token == SEMICOLON)
1399 oberon_assert_token(ctx, SEMICOLON);
1400 oberon_fp_section(ctx, &tp -> num_decl);
1404 oberon_assert_token(ctx, RPAREN);
1406 if(ctx -> token == COLON)
1408 oberon_assert_token(ctx, COLON);
1409 tp -> base = oberon_type(ctx);
1412 oberon_generator_init_type(ctx, tp);
1413 return tp;
1416 static oberon_type_t *
1417 oberon_opt_formal_pars(oberon_context_t * ctx, int class)
1419 oberon_type_t * signature;
1421 if(ctx -> token == LPAREN)
1423 signature = oberon_formal_pars(ctx);
1425 else
1427 signature = oberon_new_type_ptr(class);
1428 signature -> num_decl = 0;
1429 signature -> base = ctx -> void_type;
1430 signature -> decl = NULL;
1431 oberon_generator_init_type(ctx, signature);
1434 return signature;
1437 static void
1438 oberon_make_return(oberon_context_t * ctx, oberon_expr_t * expr)
1440 if(ctx -> result_type -> class == OBERON_TYPE_VOID)
1442 if(expr != NULL)
1444 oberon_error(ctx, "procedure has no result type");
1447 else
1449 if(expr == NULL)
1451 oberon_error(ctx, "procedure requires expression on result");
1454 oberon_autocast_to(ctx, expr, ctx -> result_type);
1457 ctx -> has_return = 1;
1459 oberon_generate_return(ctx, expr);
1462 static void
1463 oberon_proc_decl(oberon_context_t * ctx)
1465 oberon_assert_token(ctx, PROCEDURE);
1467 char * name;
1468 name = oberon_assert_ident(ctx);
1470 oberon_scope_t * this_proc_def_scope = ctx -> decl;
1471 oberon_open_scope(ctx);
1473 oberon_type_t * signature;
1474 signature = oberon_opt_formal_pars(ctx, OBERON_TYPE_PROCEDURE);
1476 oberon_object_t * proc;
1477 proc = oberon_define_proc(this_proc_def_scope, name, signature);
1479 ctx -> result_type = signature -> base;
1480 ctx -> has_return = 0;
1482 oberon_assert_token(ctx, SEMICOLON);
1484 oberon_generate_begin_proc(ctx, proc);
1486 // TODO declarations
1488 if(ctx -> token == BEGIN)
1490 oberon_assert_token(ctx, BEGIN);
1491 oberon_statement_seq(ctx);
1494 oberon_assert_token(ctx, END);
1495 char * name2 = oberon_assert_ident(ctx);
1496 if(strcmp(name2, name) != 0)
1498 oberon_error(ctx, "procedure name not matched");
1501 if(signature -> base -> class == OBERON_TYPE_VOID)
1503 oberon_make_return(ctx, NULL);
1506 if(ctx -> has_return == 0)
1508 oberon_error(ctx, "procedure requires return");
1510 ctx -> result_type = NULL;
1512 oberon_generate_end_proc(ctx);
1513 oberon_close_scope(ctx -> decl);
1516 static void
1517 oberon_const_decl(oberon_context_t * ctx)
1519 char * name;
1520 oberon_item_t * value;
1521 oberon_object_t * constant;
1523 name = oberon_assert_ident(ctx);
1524 oberon_assert_token(ctx, EQUAL);
1525 value = oberon_const_expr(ctx);
1527 constant = oberon_define_object(ctx -> decl, name, OBERON_CLASS_CONST);
1528 constant -> value = value;
1531 static void
1532 oberon_type_decl(oberon_context_t * ctx)
1534 char * name;
1535 oberon_object_t * newtype;
1536 oberon_type_t * type;
1538 name = oberon_assert_ident(ctx);
1539 oberon_assert_token(ctx, EQUAL);
1540 type = oberon_type(ctx);
1542 newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE);
1543 newtype -> type = type;
1546 static void
1547 oberon_decl_seq(oberon_context_t * ctx)
1549 if(ctx -> token == CONST)
1551 oberon_assert_token(ctx, CONST);
1552 while(ctx -> token == IDENT)
1554 oberon_const_decl(ctx);
1555 oberon_assert_token(ctx, SEMICOLON);
1559 if(ctx -> token == TYPE)
1561 oberon_assert_token(ctx, TYPE);
1562 while(ctx -> token == IDENT)
1564 oberon_type_decl(ctx);
1565 oberon_assert_token(ctx, SEMICOLON);
1569 if(ctx -> token == VAR)
1571 oberon_assert_token(ctx, VAR);
1572 while(ctx -> token == IDENT)
1574 oberon_var_decl(ctx);
1575 oberon_assert_token(ctx, SEMICOLON);
1579 while(ctx -> token == PROCEDURE)
1581 oberon_proc_decl(ctx);
1582 oberon_assert_token(ctx, SEMICOLON);
1586 static void
1587 oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
1589 oberon_autocast_to(ctx, src, dst -> result);
1590 oberon_generate_assign(ctx, src, dst);
1593 static void
1594 oberon_make_call(oberon_context_t * ctx, oberon_expr_t * desig)
1596 oberon_autocast_call(ctx, desig);
1597 oberon_generate_call_proc(ctx, desig);
1600 static void
1601 oberon_statement(oberon_context_t * ctx)
1603 oberon_expr_t * item1;
1604 oberon_expr_t * item2;
1606 if(ctx -> token == IDENT)
1608 item1 = oberon_designator(ctx);
1609 if(ctx -> token == ASSIGN)
1611 oberon_assert_token(ctx, ASSIGN);
1612 item2 = oberon_expr(ctx);
1613 oberon_assign(ctx, item2, item1);
1615 else
1617 item1 = oberon_opt_proc_parens(ctx, item1);
1618 oberon_make_call(ctx, item1);
1621 else if(ctx -> token == RETURN)
1623 oberon_assert_token(ctx, RETURN);
1624 if(ISEXPR(ctx -> token))
1626 oberon_expr_t * expr;
1627 expr = oberon_expr(ctx);
1628 oberon_make_return(ctx, expr);
1630 else
1632 oberon_make_return(ctx, NULL);
1637 static void
1638 oberon_statement_seq(oberon_context_t * ctx)
1640 oberon_statement(ctx);
1641 while(ctx -> token == SEMICOLON)
1643 oberon_assert_token(ctx, SEMICOLON);
1644 oberon_statement(ctx);
1648 static void
1649 oberon_parse_module(oberon_context_t * ctx)
1651 char *name1, *name2;
1652 oberon_read_token(ctx);
1654 oberon_assert_token(ctx, MODULE);
1655 name1 = oberon_assert_ident(ctx);
1656 oberon_assert_token(ctx, SEMICOLON);
1657 ctx -> mod -> name = name1;
1659 oberon_decl_seq(ctx);
1661 if(ctx -> token == BEGIN)
1663 oberon_assert_token(ctx, BEGIN);
1664 oberon_generate_begin_module(ctx);
1665 oberon_statement_seq(ctx);
1666 oberon_generate_end_module(ctx);
1669 oberon_assert_token(ctx, END);
1670 name2 = oberon_assert_ident(ctx);
1671 oberon_assert_token(ctx, DOT);
1673 if(strcmp(name1, name2) != 0)
1675 oberon_error(ctx, "module name not matched");
1679 // =======================================================================
1680 // LIBRARY
1681 // =======================================================================
1683 static void
1684 register_default_types(oberon_context_t * ctx)
1686 ctx -> void_type = oberon_new_type_ptr(OBERON_TYPE_VOID);
1687 oberon_generator_init_type(ctx, ctx -> void_type);
1689 ctx -> int_type = oberon_new_type_integer(sizeof(int));
1690 oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type);
1692 ctx -> bool_type = oberon_new_type_boolean(sizeof(int));
1693 oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type);
1696 oberon_context_t *
1697 oberon_create_context()
1699 oberon_context_t * ctx = malloc(sizeof *ctx);
1700 memset(ctx, 0, sizeof *ctx);
1702 oberon_scope_t * world_scope;
1703 world_scope = oberon_open_scope(ctx);
1704 ctx -> world_scope = world_scope;
1706 oberon_generator_init_context(ctx);
1708 register_default_types(ctx);
1710 return ctx;
1713 void
1714 oberon_destroy_context(oberon_context_t * ctx)
1716 oberon_generator_destroy_context(ctx);
1717 free(ctx);
1720 oberon_module_t *
1721 oberon_compile_module(oberon_context_t * ctx, const char * code)
1723 oberon_module_t * mod = malloc(sizeof *mod);
1724 memset(mod, 0, sizeof *mod);
1725 ctx -> mod = mod;
1727 oberon_scope_t * module_scope;
1728 module_scope = oberon_open_scope(ctx);
1729 mod -> decl = module_scope;
1731 oberon_init_scaner(ctx, code);
1732 oberon_parse_module(ctx);
1734 oberon_generate_code(ctx);
1736 ctx -> mod = NULL;
1737 return mod;