DEADSOFTWARE

65803c0d7eaf5924fdc96b42858b0eb3834c016d
[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 };
53 // =======================================================================
54 // UTILS
55 // =======================================================================
57 void
58 oberon_error(oberon_context_t * ctx, const char * fmt, ...)
59 {
60 va_list ptr;
61 va_start(ptr, fmt);
62 fprintf(stderr, "error: ");
63 vfprintf(stderr, fmt, ptr);
64 fprintf(stderr, "\n");
65 fprintf(stderr, " code_index = %i\n", ctx -> code_index);
66 fprintf(stderr, " c = %c\n", ctx -> c);
67 fprintf(stderr, " token = %i\n", ctx -> token);
68 va_end(ptr);
69 exit(1);
70 }
72 static oberon_type_t *
73 oberon_new_type_ptr(int class)
74 {
75 oberon_type_t * x = malloc(sizeof *x);
76 memset(x, 0, sizeof *x);
77 x -> class = class;
78 return x;
79 }
81 static oberon_type_t *
82 oberon_new_type_integer(int size)
83 {
84 oberon_type_t * x;
85 x = oberon_new_type_ptr(OBERON_TYPE_INTEGER);
86 x -> size = size;
87 return x;
88 }
90 static oberon_type_t *
91 oberon_new_type_boolean(int size)
92 {
93 oberon_type_t * x;
94 x = oberon_new_type_ptr(OBERON_TYPE_BOOLEAN);
95 x -> size = size;
96 return x;
97 }
99 // =======================================================================
100 // TABLE
101 // =======================================================================
103 static oberon_scope_t *
104 oberon_open_scope(oberon_context_t * ctx)
106 oberon_scope_t * scope = malloc(sizeof *scope);
107 memset(scope, 0, sizeof *scope);
109 oberon_object_t * list = malloc(sizeof *list);
110 memset(list, 0, sizeof *list);
112 scope -> ctx = ctx;
113 scope -> list = list;
114 scope -> up = ctx -> decl;
116 ctx -> decl = scope;
117 return scope;
120 static void
121 oberon_close_scope(oberon_scope_t * scope)
123 oberon_context_t * ctx = scope -> ctx;
124 ctx -> decl = scope -> up;
127 static oberon_object_t *
128 oberon_define_object(oberon_scope_t * scope, char * name, int class)
130 oberon_object_t * x = scope -> list;
131 while(x -> next && strcmp(x -> next -> name, name) != 0)
133 x = x -> next;
136 if(x -> next)
138 oberon_error(scope -> ctx, "already defined");
141 oberon_object_t * newvar = malloc(sizeof *newvar);
142 memset(newvar, 0, sizeof *newvar);
143 newvar -> name = name;
144 newvar -> class = class;
146 x -> next = newvar;
148 return newvar;
151 static oberon_object_t *
152 oberon_find_object_in_list(oberon_object_t * list, char * name)
154 oberon_object_t * x = list;
155 while(x -> next && strcmp(x -> next -> name, name) != 0)
157 x = x -> next;
159 return x -> next;
162 static oberon_object_t *
163 oberon_find_object(oberon_scope_t * scope, char * name)
165 oberon_object_t * result = NULL;
167 oberon_scope_t * s = scope;
168 while(result == NULL && s != NULL)
170 result = oberon_find_object_in_list(s -> list, name);
171 s = s -> up;
174 if(result == NULL)
176 oberon_error(scope -> ctx, "undefined ident %s", name);
179 return result;
182 static oberon_object_t *
183 oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type)
185 oberon_object_t * id;
186 id = oberon_define_object(scope, name, OBERON_CLASS_TYPE);
187 id -> type = type;
188 oberon_generator_init_type(scope -> ctx, type);
189 return id;
192 static oberon_type_t *
193 oberon_find_type(oberon_scope_t * scope, char * name)
195 oberon_object_t * x = oberon_find_object(scope, name);
196 if(x -> class != OBERON_CLASS_TYPE)
198 oberon_error(scope -> ctx, "%s not a type", name);
201 return x -> type;
204 static oberon_object_t *
205 oberon_define_var(oberon_scope_t * scope, int class, char * name, oberon_type_t * type)
207 oberon_object_t * var;
208 var = oberon_define_object(scope, name, class);
209 var -> type = type;
210 oberon_generator_init_var(scope -> ctx, var);
211 return var;
214 /*
215 static oberon_object_t *
216 oberon_find_var(oberon_scope_t * scope, char * name)
218 oberon_object_t * x = oberon_find_object(scope, name);
220 if(x -> class != OBERON_CLASS_VAR)
222 oberon_error(scope -> ctx, "%s not a var", name);
225 return x;
227 */
229 static oberon_object_t *
230 oberon_define_proc(oberon_scope_t * scope, char * name, oberon_type_t * signature)
232 oberon_object_t * proc;
233 proc = oberon_define_object(scope, name, OBERON_CLASS_PROC);
234 proc -> type = signature;
235 oberon_generator_init_proc(scope -> ctx, proc);
236 return proc;
239 // =======================================================================
240 // SCANER
241 // =======================================================================
243 static void
244 oberon_get_char(oberon_context_t * ctx)
246 ctx -> code_index += 1;
247 ctx -> c = ctx -> code[ctx -> code_index];
250 static void
251 oberon_init_scaner(oberon_context_t * ctx, const char * code)
253 ctx -> code = code;
254 ctx -> code_index = 0;
255 ctx -> c = ctx -> code[ctx -> code_index];
258 static void
259 oberon_read_ident(oberon_context_t * ctx)
261 int len = 0;
262 int i = ctx -> code_index;
264 int c = ctx -> code[i];
265 while(isalnum(c))
267 i += 1;
268 len += 1;
269 c = ctx -> code[i];
272 char * ident = malloc(len + 1);
273 memcpy(ident, &ctx->code[ctx->code_index], len);
274 ident[len] = 0;
276 ctx -> code_index = i;
277 ctx -> c = ctx -> code[i];
278 ctx -> string = ident;
279 ctx -> token = IDENT;
281 if(strcmp(ident, "MODULE") == 0)
283 ctx -> token = MODULE;
285 else if(strcmp(ident, "END") == 0)
287 ctx -> token = END;
289 else if(strcmp(ident, "VAR") == 0)
291 ctx -> token = VAR;
293 else if(strcmp(ident, "BEGIN") == 0)
295 ctx -> token = BEGIN;
297 else if(strcmp(ident, "TRUE") == 0)
299 ctx -> token = TRUE;
301 else if(strcmp(ident, "FALSE") == 0)
303 ctx -> token = FALSE;
305 else if(strcmp(ident, "OR") == 0)
307 ctx -> token = OR;
309 else if(strcmp(ident, "DIV") == 0)
311 ctx -> token = DIV;
313 else if(strcmp(ident, "MOD") == 0)
315 ctx -> token = MOD;
317 else if(strcmp(ident, "PROCEDURE") == 0)
319 ctx -> token = PROCEDURE;
321 else if(strcmp(ident, "RETURN") == 0)
323 ctx -> token = RETURN;
325 else if(strcmp(ident, "CONST") == 0)
327 ctx -> token = CONST;
329 else if(strcmp(ident, "TYPE") == 0)
331 ctx -> token = TYPE;
333 else if(strcmp(ident, "ARRAY") == 0)
335 ctx -> token = ARRAY;
337 else if(strcmp(ident, "OF") == 0)
339 ctx -> token = OF;
343 static void
344 oberon_read_integer(oberon_context_t * ctx)
346 int len = 0;
347 int i = ctx -> code_index;
349 int c = ctx -> code[i];
350 while(isdigit(c))
352 i += 1;
353 len += 1;
354 c = ctx -> code[i];
357 char * ident = malloc(len + 2);
358 memcpy(ident, &ctx->code[ctx->code_index], len);
359 ident[len + 1] = 0;
361 ctx -> code_index = i;
362 ctx -> c = ctx -> code[i];
363 ctx -> string = ident;
364 ctx -> integer = atoi(ident);
365 ctx -> token = INTEGER;
368 static void
369 oberon_skip_space(oberon_context_t * ctx)
371 while(isspace(ctx -> c))
373 oberon_get_char(ctx);
377 static void
378 oberon_read_symbol(oberon_context_t * ctx)
380 int c = ctx -> c;
381 switch(c)
383 case 0:
384 ctx -> token = EOF_;
385 break;
386 case ';':
387 ctx -> token = SEMICOLON;
388 oberon_get_char(ctx);
389 break;
390 case ':':
391 ctx -> token = COLON;
392 oberon_get_char(ctx);
393 if(ctx -> c == '=')
395 ctx -> token = ASSIGN;
396 oberon_get_char(ctx);
398 break;
399 case '.':
400 ctx -> token = DOT;
401 oberon_get_char(ctx);
402 break;
403 case '(':
404 ctx -> token = LPAREN;
405 oberon_get_char(ctx);
406 break;
407 case ')':
408 ctx -> token = RPAREN;
409 oberon_get_char(ctx);
410 break;
411 case '=':
412 ctx -> token = EQUAL;
413 oberon_get_char(ctx);
414 break;
415 case '#':
416 ctx -> token = NEQ;
417 oberon_get_char(ctx);
418 break;
419 case '<':
420 ctx -> token = LESS;
421 oberon_get_char(ctx);
422 if(ctx -> c == '=')
424 ctx -> token = LEQ;
425 oberon_get_char(ctx);
427 break;
428 case '>':
429 ctx -> token = GREAT;
430 oberon_get_char(ctx);
431 if(ctx -> c == '=')
433 ctx -> token = GEQ;
434 oberon_get_char(ctx);
436 break;
437 case '+':
438 ctx -> token = PLUS;
439 oberon_get_char(ctx);
440 break;
441 case '-':
442 ctx -> token = MINUS;
443 oberon_get_char(ctx);
444 break;
445 case '*':
446 ctx -> token = STAR;
447 oberon_get_char(ctx);
448 break;
449 case '/':
450 ctx -> token = SLASH;
451 oberon_get_char(ctx);
452 break;
453 case '&':
454 ctx -> token = AND;
455 oberon_get_char(ctx);
456 break;
457 case '~':
458 ctx -> token = NOT;
459 oberon_get_char(ctx);
460 break;
461 case ',':
462 ctx -> token = COMMA;
463 oberon_get_char(ctx);
464 break;
465 case '[':
466 ctx -> token = LBRACE;
467 oberon_get_char(ctx);
468 break;
469 case ']':
470 ctx -> token = RBRACE;
471 oberon_get_char(ctx);
472 break;
473 default:
474 oberon_error(ctx, "invalid char");
475 break;
479 static void
480 oberon_read_token(oberon_context_t * ctx)
482 oberon_skip_space(ctx);
484 int c = ctx -> c;
485 if(isalpha(c))
487 oberon_read_ident(ctx);
489 else if(isdigit(c))
491 oberon_read_integer(ctx);
493 else
495 oberon_read_symbol(ctx);
499 // =======================================================================
500 // EXPRESSION
501 // =======================================================================
503 static void oberon_expect_token(oberon_context_t * ctx, int token);
504 static oberon_expr_t * oberon_expr(oberon_context_t * ctx);
505 static void oberon_assert_token(oberon_context_t * ctx, int token);
506 static char * oberon_assert_ident(oberon_context_t * ctx);
507 static oberon_type_t * oberon_type(oberon_context_t * ctx);
509 static oberon_expr_t *
510 oberon_new_operator(int op, oberon_type_t * result, oberon_expr_t * left, oberon_expr_t * right)
512 oberon_oper_t * operator;
513 operator = malloc(sizeof *operator);
514 memset(operator, 0, sizeof *operator);
516 operator -> is_item = 0;
517 operator -> result = result;
518 operator -> op = op;
519 operator -> left = left;
520 operator -> right = right;
522 return (oberon_expr_t *) operator;
525 static oberon_expr_t *
526 oberon_new_item(int mode, oberon_type_t * result)
528 oberon_item_t * item;
529 item = malloc(sizeof *item);
530 memset(item, 0, sizeof *item);
532 item -> is_item = 1;
533 item -> result = result;
534 item -> mode = mode;
536 return (oberon_expr_t *)item;
539 static oberon_expr_t *
540 oberon_make_unary_op(oberon_context_t * ctx, int token, oberon_expr_t * a)
542 oberon_expr_t * expr;
543 oberon_type_t * result;
545 result = a -> result;
547 if(token == MINUS)
549 if(result -> class != OBERON_TYPE_INTEGER)
551 oberon_error(ctx, "incompatible operator type");
554 expr = oberon_new_operator(OP_UNARY_MINUS, result, a, NULL);
556 else if(token == NOT)
558 if(result -> class != OBERON_TYPE_BOOLEAN)
560 oberon_error(ctx, "incompatible operator type");
563 expr = oberon_new_operator(OP_LOGIC_NOT, result, a, NULL);
565 else
567 oberon_error(ctx, "oberon_make_unary_op: wat");
570 return expr;
573 static void
574 oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first)
576 oberon_expr_t * last;
578 *num_expr = 1;
579 *first = last = oberon_expr(ctx);
580 while(ctx -> token == COMMA)
582 oberon_assert_token(ctx, COMMA);
583 oberon_expr_t * current;
584 current = oberon_expr(ctx);
585 last -> next = current;
586 last = current;
587 *num_expr += 1;
591 static oberon_expr_t *
592 oberon_autocast_to(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * pref)
594 if(expr -> result -> class != pref -> class)
596 oberon_error(ctx, "incompatible types");
599 if(pref -> class == OBERON_TYPE_INTEGER)
601 if(expr -> result -> class > pref -> class)
603 oberon_error(ctx, "incompatible size");
607 // TODO cast
609 return expr;
612 static void
613 oberon_autocast_call(oberon_context_t * ctx, oberon_expr_t * desig)
615 if(desig -> is_item == 0)
617 oberon_error(ctx, "expected item");
620 if(desig -> item.mode != MODE_CALL)
622 oberon_error(ctx, "expected mode CALL");
625 if(desig -> item.var -> class != OBERON_CLASS_PROC)
627 oberon_error(ctx, "only procedures can be called");
630 oberon_type_t * fn = desig -> item.var -> type;
631 int num_args = desig -> item.num_args;
632 int num_decl = fn -> num_decl;
634 if(num_args < num_decl)
636 oberon_error(ctx, "too few arguments");
638 else if(num_args > num_decl)
640 oberon_error(ctx, "too many arguments");
643 oberon_expr_t * arg = desig -> item.args;
644 oberon_object_t * param = fn -> decl;
645 for(int i = 0; i < num_args; i++)
647 oberon_autocast_to(ctx, arg, param -> type);
648 arg = arg -> next;
649 param = param -> next;
653 #define ISEXPR(x) \
654 (((x) == PLUS) \
655 || ((x) == MINUS) \
656 || ((x) == IDENT) \
657 || ((x) == INTEGER) \
658 || ((x) == LPAREN) \
659 || ((x) == NOT) \
660 || ((x) == TRUE) \
661 || ((x) == FALSE))
663 static oberon_expr_t *
664 oberon_designator(oberon_context_t * ctx)
666 char * name;
667 oberon_object_t * var;
668 oberon_expr_t * expr;
670 name = oberon_assert_ident(ctx);
671 var = oberon_find_object(ctx -> decl, name);
673 switch(var -> class)
675 case OBERON_CLASS_CONST:
676 // TODO copy value
677 expr = (oberon_expr_t *) var -> value;
678 break;
679 case OBERON_CLASS_VAR:
680 case OBERON_CLASS_VAR_PARAM:
681 case OBERON_CLASS_PARAM:
682 expr = oberon_new_item(MODE_VAR, var -> type);
683 break;
684 case OBERON_CLASS_PROC:
685 expr = oberon_new_item(MODE_CALL, var -> type);
686 break;
687 default:
688 oberon_error(ctx, "invalid designator");
689 break;
692 expr -> item.var = var;
693 return expr;
696 static oberon_expr_t *
697 oberon_opt_proc_parens(oberon_context_t * ctx, oberon_expr_t * expr)
699 assert(expr -> is_item == 1);
700 if(ctx -> token == LPAREN)
702 oberon_assert_token(ctx, LPAREN);
704 int num_args = 0;
705 oberon_expr_t * arguments = NULL;
707 if(ISEXPR(ctx -> token))
709 oberon_expr_list(ctx, &num_args, &arguments);
712 expr -> result = expr -> item.var -> type -> base;
713 expr -> item.mode = MODE_CALL;
714 expr -> item.num_args = num_args;
715 expr -> item.args = arguments;
716 oberon_assert_token(ctx, RPAREN);
718 oberon_autocast_call(ctx, expr);
721 return expr;
724 static oberon_expr_t *
725 oberon_factor(oberon_context_t * ctx)
727 oberon_expr_t * expr;
729 switch(ctx -> token)
731 case IDENT:
732 expr = oberon_designator(ctx);
733 expr = oberon_opt_proc_parens(ctx, expr);
734 break;
735 case INTEGER:
736 expr = oberon_new_item(MODE_INTEGER, ctx -> int_type);
737 expr -> item.integer = ctx -> integer;
738 oberon_assert_token(ctx, INTEGER);
739 break;
740 case TRUE:
741 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
742 expr -> item.boolean = 1;
743 oberon_assert_token(ctx, TRUE);
744 break;
745 case FALSE:
746 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
747 expr -> item.boolean = 0;
748 oberon_assert_token(ctx, FALSE);
749 break;
750 case LPAREN:
751 oberon_assert_token(ctx, LPAREN);
752 expr = oberon_expr(ctx);
753 oberon_assert_token(ctx, RPAREN);
754 break;
755 case NOT:
756 oberon_assert_token(ctx, NOT);
757 expr = oberon_factor(ctx);
758 expr = oberon_make_unary_op(ctx, NOT, expr);
759 break;
760 default:
761 oberon_error(ctx, "invalid expression");
764 return expr;
767 /*
768 * oberon_autocast_binary_op автоматически переобразовывеат тип по след. правилам:
769 * 1. Классы обоих типов должны быть одинаковы
770 * 2. В качестве результата должен быть выбран больший тип.
771 * 3. Если размер результат не должен быть меньше чем базовый int
772 */
774 static void
775 oberon_autocast_binary_op(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b, oberon_type_t ** result)
777 if((a -> class) != (b -> class))
779 oberon_error(ctx, "incompatible types");
782 if((a -> size) > (b -> size))
784 *result = a;
786 else
788 *result = b;
791 if(((*result) -> class) == OBERON_TYPE_INTEGER)
793 if(((*result) -> size) < (ctx -> int_type -> size))
795 *result = ctx -> int_type;
799 /* TODO: cast types */
802 #define ITMAKESBOOLEAN(x) \
803 (((x) >= EQUAL && (x) <= GEQ) || ((x) == OR) || ((x) == AND))
805 #define ITUSEONLYINTEGER(x) \
806 ((x) >= LESS && (x) <= GEQ)
808 #define ITUSEONLYBOOLEAN(x) \
809 (((x) == OR) || ((x) == AND))
811 static oberon_expr_t *
812 oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
814 oberon_expr_t * expr;
815 oberon_type_t * result;
817 if(ITMAKESBOOLEAN(token))
819 if(ITUSEONLYINTEGER(token))
821 if(a -> result -> class != OBERON_TYPE_INTEGER
822 || b -> result -> class != OBERON_TYPE_INTEGER)
824 oberon_error(ctx, "used only with integer types");
827 else if(ITUSEONLYBOOLEAN(token))
829 if(a -> result -> class != OBERON_TYPE_BOOLEAN
830 || b -> result -> class != OBERON_TYPE_BOOLEAN)
832 oberon_error(ctx, "used only with boolean type");
836 result = ctx -> bool_type;
838 if(token == EQUAL)
840 expr = oberon_new_operator(OP_EQ, result, a, b);
842 else if(token == NEQ)
844 expr = oberon_new_operator(OP_NEQ, result, a, b);
846 else if(token == LESS)
848 expr = oberon_new_operator(OP_LSS, result, a, b);
850 else if(token == LEQ)
852 expr = oberon_new_operator(OP_LEQ, result, a, b);
854 else if(token == GREAT)
856 expr = oberon_new_operator(OP_GRT, result, a, b);
858 else if(token == GEQ)
860 expr = oberon_new_operator(OP_GEQ, result, a, b);
862 else if(token == OR)
864 expr = oberon_new_operator(OP_LOGIC_OR, result, a, b);
866 else if(token == AND)
868 expr = oberon_new_operator(OP_LOGIC_AND, result, a, b);
870 else
872 oberon_error(ctx, "oberon_make_bin_op: bool wat");
875 else
877 oberon_autocast_binary_op(ctx, a -> result, b -> result, &result);
879 if(token == PLUS)
881 expr = oberon_new_operator(OP_ADD, result, a, b);
883 else if(token == MINUS)
885 expr = oberon_new_operator(OP_SUB, result, a, b);
887 else if(token == STAR)
889 expr = oberon_new_operator(OP_MUL, result, a, b);
891 else if(token == SLASH)
893 expr = oberon_new_operator(OP_DIV, result, a, b);
895 else if(token == DIV)
897 expr = oberon_new_operator(OP_DIV, result, a, b);
899 else if(token == MOD)
901 expr = oberon_new_operator(OP_MOD, result, a, b);
903 else
905 oberon_error(ctx, "oberon_make_bin_op: bin wat");
909 return expr;
912 #define ISMULOP(x) \
913 ((x) >= STAR && (x) <= AND)
915 static oberon_expr_t *
916 oberon_term_expr(oberon_context_t * ctx)
918 oberon_expr_t * expr;
920 expr = oberon_factor(ctx);
921 while(ISMULOP(ctx -> token))
923 int token = ctx -> token;
924 oberon_read_token(ctx);
926 oberon_expr_t * inter = oberon_factor(ctx);
927 expr = oberon_make_bin_op(ctx, token, expr, inter);
930 return expr;
933 #define ISADDOP(x) \
934 ((x) >= PLUS && (x) <= OR)
936 static oberon_expr_t *
937 oberon_simple_expr(oberon_context_t * ctx)
939 oberon_expr_t * expr;
941 int minus = 0;
942 if(ctx -> token == PLUS)
944 minus = 0;
945 oberon_assert_token(ctx, PLUS);
947 else if(ctx -> token == MINUS)
949 minus = 1;
950 oberon_assert_token(ctx, MINUS);
953 expr = oberon_term_expr(ctx);
954 while(ISADDOP(ctx -> token))
956 int token = ctx -> token;
957 oberon_read_token(ctx);
959 oberon_expr_t * inter = oberon_term_expr(ctx);
960 expr = oberon_make_bin_op(ctx, token, expr, inter);
963 if(minus)
965 expr = oberon_make_unary_op(ctx, MINUS, expr);
968 return expr;
971 #define ISRELATION(x) \
972 ((x) >= EQUAL && (x) <= GEQ)
974 static oberon_expr_t *
975 oberon_expr(oberon_context_t * ctx)
977 oberon_expr_t * expr;
979 expr = oberon_simple_expr(ctx);
980 while(ISRELATION(ctx -> token))
982 int token = ctx -> token;
983 oberon_read_token(ctx);
985 oberon_expr_t * inter = oberon_simple_expr(ctx);
986 expr = oberon_make_bin_op(ctx, token, expr, inter);
989 return expr;
992 static oberon_item_t *
993 oberon_const_expr(oberon_context_t * ctx)
995 oberon_expr_t * expr;
996 expr = oberon_expr(ctx);
998 if(expr -> is_item == 0)
1000 oberon_error(ctx, "const expression are required");
1003 return (oberon_item_t *) expr;
1006 // =======================================================================
1007 // PARSER
1008 // =======================================================================
1010 static void oberon_statement_seq(oberon_context_t * ctx);
1012 static void
1013 oberon_expect_token(oberon_context_t * ctx, int token)
1015 if(ctx -> token != token)
1017 oberon_error(ctx, "unexpected token %i (%i)", ctx -> token, token);
1021 static void
1022 oberon_assert_token(oberon_context_t * ctx, int token)
1024 oberon_expect_token(ctx, token);
1025 oberon_read_token(ctx);
1028 static char *
1029 oberon_assert_ident(oberon_context_t * ctx)
1031 oberon_expect_token(ctx, IDENT);
1032 char * ident = ctx -> string;
1033 oberon_read_token(ctx);
1034 return ident;
1037 static oberon_type_t *
1038 oberon_make_array_type(oberon_context_t * ctx, int dim, oberon_item_t * size, oberon_type_t * base)
1040 assert(dim == 1);
1041 oberon_type_t * newtype;
1043 if(size -> mode != MODE_INTEGER)
1045 oberon_error(ctx, "requires integer constant");
1048 newtype = oberon_new_type_ptr(OBERON_TYPE_ARRAY);
1049 newtype -> dim = dim;
1050 newtype -> size = size -> integer;
1051 newtype -> base = base;
1052 oberon_generator_init_type(ctx, newtype);
1054 return newtype;
1057 static oberon_type_t *
1058 oberon_type(oberon_context_t * ctx)
1060 oberon_type_t * type;
1062 if(ctx -> token == IDENT)
1064 char * name = oberon_assert_ident(ctx);
1065 type = oberon_find_type(ctx -> decl, name);
1067 else if(ctx -> token == ARRAY)
1069 oberon_assert_token(ctx, ARRAY);
1070 oberon_item_t * size = oberon_const_expr(ctx);
1071 oberon_assert_token(ctx, OF);
1072 oberon_type_t * base = oberon_type(ctx);
1073 type = oberon_make_array_type(ctx, 1, size, base);
1075 else
1077 oberon_error(ctx, "invalid type declaration");
1080 return type;
1083 static void
1084 oberon_var_decl(oberon_context_t * ctx)
1086 char * name = oberon_assert_ident(ctx);
1087 oberon_assert_token(ctx, COLON);
1088 oberon_type_t * type = oberon_type(ctx);
1089 oberon_define_var(ctx -> decl, OBERON_CLASS_VAR, name, type);
1092 static oberon_object_t *
1093 oberon_make_param(oberon_context_t * ctx, int token, char * name, oberon_type_t * type)
1095 oberon_object_t * param;
1097 if(token == VAR)
1099 param = oberon_define_var(ctx -> decl, OBERON_CLASS_VAR_PARAM, name, type);
1101 else if(token == IDENT)
1103 param = oberon_define_var(ctx -> decl, OBERON_CLASS_PARAM, name, type);
1105 else
1107 oberon_error(ctx, "oberon_make_param: wat");
1110 return param;
1113 static oberon_object_t *
1114 oberon_fp_section(oberon_context_t * ctx, int * num_decl)
1116 int modifer_token = ctx -> token;
1117 if(ctx -> token == VAR)
1119 oberon_read_token(ctx);
1122 char * name;
1123 name = oberon_assert_ident(ctx);
1125 oberon_assert_token(ctx, COLON);
1127 oberon_type_t * type;
1128 type = oberon_type(ctx);
1130 oberon_object_t * first;
1131 first = oberon_make_param(ctx, modifer_token, name, type);
1133 *num_decl += 1;
1134 return first;
1137 #define ISFPSECTION \
1138 ((ctx -> token == VAR) || (ctx -> token == IDENT))
1140 static oberon_type_t *
1141 oberon_formal_pars(oberon_context_t * ctx)
1143 oberon_type_t * tp;
1144 tp = oberon_new_type_ptr(OBERON_TYPE_PROCEDURE);
1145 tp -> num_decl = 0;
1146 tp -> base = ctx -> void_type;
1147 tp -> decl = NULL;
1149 oberon_assert_token(ctx, LPAREN);
1151 if(ISFPSECTION)
1153 tp -> decl = oberon_fp_section(ctx, &tp -> num_decl);
1154 while(ctx -> token == SEMICOLON)
1156 oberon_assert_token(ctx, SEMICOLON);
1157 oberon_fp_section(ctx, &tp -> num_decl);
1161 oberon_assert_token(ctx, RPAREN);
1163 if(ctx -> token == COLON)
1165 oberon_assert_token(ctx, COLON);
1166 tp -> base = oberon_type(ctx);
1169 oberon_generator_init_type(ctx, tp);
1170 return tp;
1173 static void
1174 oberon_make_return(oberon_context_t * ctx, oberon_expr_t * expr)
1176 if(ctx -> result_type -> class == OBERON_TYPE_VOID)
1178 if(expr != NULL)
1180 oberon_error(ctx, "procedure has no result type");
1183 else
1185 if(expr == NULL)
1187 oberon_error(ctx, "procedure requires expression on result");
1190 oberon_autocast_to(ctx, expr, ctx -> result_type);
1193 ctx -> has_return = 1;
1195 oberon_generate_return(ctx, expr);
1198 static void
1199 oberon_proc_decl(oberon_context_t * ctx)
1201 oberon_assert_token(ctx, PROCEDURE);
1203 char * name;
1204 name = oberon_assert_ident(ctx);
1206 oberon_scope_t * this_proc_def_scope = ctx -> decl;
1207 oberon_open_scope(ctx);
1209 oberon_type_t * signature;
1210 if(ctx -> token == LPAREN)
1212 signature = oberon_formal_pars(ctx);
1214 else
1216 signature = oberon_new_type_ptr(OBERON_TYPE_PROCEDURE);
1217 signature -> num_decl = 0;
1218 signature -> base = ctx -> void_type;
1219 signature -> decl = NULL;
1220 oberon_generator_init_type(ctx, signature);
1223 oberon_object_t * proc;
1224 proc = oberon_define_proc(this_proc_def_scope, name, signature);
1226 ctx -> result_type = signature -> base;
1227 ctx -> has_return = 0;
1229 oberon_assert_token(ctx, SEMICOLON);
1231 oberon_generate_begin_proc(ctx, proc);
1233 // TODO declarations
1235 if(ctx -> token == BEGIN)
1237 oberon_assert_token(ctx, BEGIN);
1238 oberon_statement_seq(ctx);
1241 oberon_assert_token(ctx, END);
1242 char * name2 = oberon_assert_ident(ctx);
1243 if(strcmp(name2, name) != 0)
1245 oberon_error(ctx, "procedure name not matched");
1248 if(signature -> base -> class == OBERON_TYPE_VOID)
1250 oberon_make_return(ctx, NULL);
1253 if(ctx -> has_return == 0)
1255 oberon_error(ctx, "procedure requires return");
1257 ctx -> result_type = NULL;
1259 oberon_generate_end_proc(ctx);
1260 oberon_close_scope(ctx -> decl);
1263 static void
1264 oberon_const_decl(oberon_context_t * ctx)
1266 char * name;
1267 oberon_item_t * value;
1268 oberon_object_t * constant;
1270 name = oberon_assert_ident(ctx);
1271 oberon_assert_token(ctx, EQUAL);
1272 value = oberon_const_expr(ctx);
1274 constant = oberon_define_object(ctx -> decl, name, OBERON_CLASS_CONST);
1275 constant -> value = value;
1278 static void
1279 oberon_type_decl(oberon_context_t * ctx)
1281 char * name;
1282 oberon_object_t * newtype;
1283 oberon_type_t * type;
1285 name = oberon_assert_ident(ctx);
1286 oberon_assert_token(ctx, EQUAL);
1287 type = oberon_type(ctx);
1289 newtype = oberon_define_object(ctx -> decl, name, OBERON_CLASS_TYPE);
1290 newtype -> type = type;
1293 static void
1294 oberon_decl_seq(oberon_context_t * ctx)
1296 if(ctx -> token == CONST)
1298 oberon_assert_token(ctx, CONST);
1299 while(ctx -> token == IDENT)
1301 oberon_const_decl(ctx);
1302 oberon_assert_token(ctx, SEMICOLON);
1306 if(ctx -> token == TYPE)
1308 oberon_assert_token(ctx, TYPE);
1309 while(ctx -> token == IDENT)
1311 oberon_type_decl(ctx);
1312 oberon_assert_token(ctx, SEMICOLON);
1316 if(ctx -> token == VAR)
1318 oberon_assert_token(ctx, VAR);
1319 while(ctx -> token == IDENT)
1321 oberon_var_decl(ctx);
1322 oberon_assert_token(ctx, SEMICOLON);
1326 while(ctx -> token == PROCEDURE)
1328 oberon_proc_decl(ctx);
1329 oberon_assert_token(ctx, SEMICOLON);
1333 static void
1334 oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
1336 oberon_autocast_to(ctx, src, dst -> result);
1337 oberon_generate_assign(ctx, src, dst);
1340 static void
1341 oberon_make_call(oberon_context_t * ctx, oberon_expr_t * desig)
1343 oberon_autocast_call(ctx, desig);
1344 oberon_generate_call_proc(ctx, desig);
1347 static void
1348 oberon_statement(oberon_context_t * ctx)
1350 oberon_expr_t * item1;
1351 oberon_expr_t * item2;
1353 if(ctx -> token == IDENT)
1355 item1 = oberon_designator(ctx);
1356 if(ctx -> token == ASSIGN)
1358 oberon_assert_token(ctx, ASSIGN);
1359 item2 = oberon_expr(ctx);
1360 oberon_assign(ctx, item2, item1);
1362 else
1364 item1 = oberon_opt_proc_parens(ctx, item1);
1365 oberon_make_call(ctx, item1);
1368 else if(ctx -> token == RETURN)
1370 oberon_assert_token(ctx, RETURN);
1371 if(ISEXPR(ctx -> token))
1373 oberon_expr_t * expr;
1374 expr = oberon_expr(ctx);
1375 oberon_make_return(ctx, expr);
1377 else
1379 oberon_make_return(ctx, NULL);
1384 static void
1385 oberon_statement_seq(oberon_context_t * ctx)
1387 oberon_statement(ctx);
1388 while(ctx -> token == SEMICOLON)
1390 oberon_assert_token(ctx, SEMICOLON);
1391 oberon_statement(ctx);
1395 static void
1396 oberon_parse_module(oberon_context_t * ctx)
1398 char *name1, *name2;
1399 oberon_read_token(ctx);
1401 oberon_assert_token(ctx, MODULE);
1402 name1 = oberon_assert_ident(ctx);
1403 oberon_assert_token(ctx, SEMICOLON);
1404 ctx -> mod -> name = name1;
1406 oberon_decl_seq(ctx);
1408 if(ctx -> token == BEGIN)
1410 oberon_assert_token(ctx, BEGIN);
1411 oberon_generate_begin_module(ctx);
1412 oberon_statement_seq(ctx);
1413 oberon_generate_end_module(ctx);
1416 oberon_assert_token(ctx, END);
1417 name2 = oberon_assert_ident(ctx);
1418 oberon_assert_token(ctx, DOT);
1420 if(strcmp(name1, name2) != 0)
1422 oberon_error(ctx, "module name not matched");
1426 // =======================================================================
1427 // LIBRARY
1428 // =======================================================================
1430 static void
1431 register_default_types(oberon_context_t * ctx)
1433 ctx -> void_type = oberon_new_type_ptr(OBERON_TYPE_VOID);
1434 oberon_generator_init_type(ctx, ctx -> void_type);
1436 ctx -> int_type = oberon_new_type_integer(sizeof(int));
1437 oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type);
1439 ctx -> bool_type = oberon_new_type_boolean(sizeof(int));
1440 oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type);
1443 oberon_context_t *
1444 oberon_create_context()
1446 oberon_context_t * ctx = malloc(sizeof *ctx);
1447 memset(ctx, 0, sizeof *ctx);
1449 oberon_scope_t * world_scope;
1450 world_scope = oberon_open_scope(ctx);
1451 ctx -> world_scope = world_scope;
1453 oberon_generator_init_context(ctx);
1455 register_default_types(ctx);
1457 return ctx;
1460 void
1461 oberon_destroy_context(oberon_context_t * ctx)
1463 oberon_generator_destroy_context(ctx);
1464 free(ctx);
1467 oberon_module_t *
1468 oberon_compile_module(oberon_context_t * ctx, const char * code)
1470 oberon_module_t * mod = malloc(sizeof *mod);
1471 memset(mod, 0, sizeof *mod);
1472 ctx -> mod = mod;
1474 oberon_scope_t * module_scope;
1475 module_scope = oberon_open_scope(ctx);
1476 mod -> decl = module_scope;
1478 oberon_init_scaner(ctx, code);
1479 oberon_parse_module(ctx);
1481 oberon_generate_code(ctx);
1483 ctx -> mod = NULL;
1484 return mod;