DEADSOFTWARE

98928fbe7c4e1629b2519b0f505e54fb921ef63b
[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>
7 #include "oberon.h"
8 #include "generator.h"
10 enum {
11 EOF_ = 0,
12 IDENT,
13 MODULE,
14 SEMICOLON,
15 END,
16 DOT,
17 VAR,
18 COLON,
19 BEGIN,
20 ASSIGN,
21 INTEGER,
22 TRUE,
23 FALSE,
24 LPAREN,
25 RPAREN,
26 EQUAL,
27 NEQ,
28 LESS,
29 LEQ,
30 GREAT,
31 GEQ,
32 PLUS,
33 MINUS,
34 OR,
35 STAR,
36 SLASH,
37 DIV,
38 MOD,
39 AND,
40 NOT,
41 PROCEDURE
42 };
44 // =======================================================================
45 // UTILS
46 // =======================================================================
48 void
49 oberon_error(oberon_context_t * ctx, const char * fmt, ...)
50 {
51 va_list ptr;
52 va_start(ptr, fmt);
53 fprintf(stderr, "error: ");
54 vfprintf(stderr, fmt, ptr);
55 fprintf(stderr, "\n");
56 fprintf(stderr, " code_index = %i\n", ctx -> code_index);
57 fprintf(stderr, " c = %c\n", ctx -> c);
58 fprintf(stderr, " token = %i\n", ctx -> token);
59 va_end(ptr);
60 exit(1);
61 }
63 // =======================================================================
64 // TABLE
65 // =======================================================================
67 static oberon_scope_t *
68 oberon_open_scope(oberon_context_t * ctx)
69 {
70 oberon_scope_t * scope = malloc(sizeof *scope);
71 memset(scope, 0, sizeof *scope);
73 oberon_object_t * list = malloc(sizeof *list);
74 memset(list, 0, sizeof *list);
76 scope -> ctx = ctx;
77 scope -> list = list;
78 scope -> up = ctx -> decl;
80 ctx -> decl = scope;
81 return scope;
82 }
84 static void
85 oberon_close_scope(oberon_scope_t * scope)
86 {
87 oberon_context_t * ctx = scope -> ctx;
88 ctx -> decl = scope -> up;
89 }
91 static oberon_object_t *
92 oberon_define_object(oberon_scope_t * scope, char * name, int class)
93 {
94 oberon_object_t * x = scope -> list;
95 while(x -> next && strcmp(x -> next -> name, name) != 0)
96 {
97 x = x -> next;
98 }
100 if(x -> next)
102 oberon_error(scope -> ctx, "already defined");
105 oberon_object_t * newvar = malloc(sizeof *newvar);
106 memset(newvar, 0, sizeof *newvar);
107 newvar -> name = name;
108 newvar -> class = class;
110 x -> next = newvar;
112 return newvar;
115 static oberon_object_t *
116 oberon_find_object_in_list(oberon_object_t * list, char * name)
118 oberon_object_t * x = list;
119 while(x -> next && strcmp(x -> next -> name, name) != 0)
121 x = x -> next;
123 return x -> next;
126 static oberon_object_t *
127 oberon_find_object(oberon_scope_t * scope, char * name)
129 oberon_object_t * result = NULL;
131 oberon_scope_t * s = scope;
132 while(result == NULL && s != NULL)
134 result = oberon_find_object_in_list(s -> list, name);
135 s = s -> up;
138 if(result == NULL)
140 oberon_error(scope -> ctx, "undefined ident %s", name);
143 return result;
146 static void
147 oberon_define_type(oberon_scope_t * scope, char * name, oberon_type_t * type)
149 oberon_object_t * id;
150 id = oberon_define_object(scope, name, OBERON_CLASS_TYPE);
151 id -> type = type;
152 oberon_generator_init_type(scope -> ctx, type);
155 static oberon_type_t *
156 oberon_find_type(oberon_scope_t * scope, char * name)
158 oberon_object_t * x = oberon_find_object(scope, name);
159 if(x -> class != OBERON_CLASS_TYPE)
161 oberon_error(scope -> ctx, "%s not a type", name);
164 return x -> type;
167 static void
168 oberon_define_var(oberon_scope_t * scope, char * name, oberon_type_t * type)
170 oberon_object_t * var;
171 var = oberon_define_object(scope, name, OBERON_CLASS_VAR);
172 var -> type = type;
173 oberon_generator_init_var(scope -> ctx, var);
176 /*
177 static oberon_object_t *
178 oberon_find_var(oberon_scope_t * scope, char * name)
180 oberon_object_t * x = oberon_find_object(scope, name);
182 if(x -> class != OBERON_CLASS_VAR)
184 oberon_error(scope -> ctx, "%s not a var", name);
187 return x;
189 */
191 static oberon_object_t *
192 oberon_define_proc(oberon_scope_t * scope, char * name)
194 oberon_object_t * proc;
195 proc = oberon_define_object(scope, name, OBERON_CLASS_PROC);
196 oberon_generator_init_proc(scope -> ctx, proc);
197 return proc;
200 // =======================================================================
201 // SCANER
202 // =======================================================================
204 static void
205 oberon_get_char(oberon_context_t * ctx)
207 ctx -> code_index += 1;
208 ctx -> c = ctx -> code[ctx -> code_index];
211 static void
212 oberon_init_scaner(oberon_context_t * ctx, const char * code)
214 ctx -> code = code;
215 ctx -> code_index = 0;
216 ctx -> c = ctx -> code[ctx -> code_index];
219 static void
220 oberon_read_ident(oberon_context_t * ctx)
222 int len = 0;
223 int i = ctx -> code_index;
225 int c = ctx -> code[i];
226 while(isalnum(c))
228 i += 1;
229 len += 1;
230 c = ctx -> code[i];
233 char * ident = malloc(len + 1);
234 memcpy(ident, &ctx->code[ctx->code_index], len);
235 ident[len] = 0;
237 ctx -> code_index = i;
238 ctx -> c = ctx -> code[i];
239 ctx -> string = ident;
240 ctx -> token = IDENT;
242 if(strcmp(ident, "MODULE") == 0)
244 ctx -> token = MODULE;
246 else if(strcmp(ident, "END") == 0)
248 ctx -> token = END;
250 else if(strcmp(ident, "VAR") == 0)
252 ctx -> token = VAR;
254 else if(strcmp(ident, "BEGIN") == 0)
256 ctx -> token = BEGIN;
258 else if(strcmp(ident, "TRUE") == 0)
260 ctx -> token = TRUE;
262 else if(strcmp(ident, "FALSE") == 0)
264 ctx -> token = FALSE;
266 else if(strcmp(ident, "OR") == 0)
268 ctx -> token = OR;
270 else if(strcmp(ident, "DIV") == 0)
272 ctx -> token = DIV;
274 else if(strcmp(ident, "MOD") == 0)
276 ctx -> token = MOD;
278 else if(strcmp(ident, "PROCEDURE") == 0)
280 ctx -> token = PROCEDURE;
284 static void
285 oberon_read_integer(oberon_context_t * ctx)
287 int len = 0;
288 int i = ctx -> code_index;
290 int c = ctx -> code[i];
291 while(isdigit(c))
293 i += 1;
294 len += 1;
295 c = ctx -> code[i];
298 char * ident = malloc(len + 2);
299 memcpy(ident, &ctx->code[ctx->code_index], len);
300 ident[len + 1] = 0;
302 ctx -> code_index = i;
303 ctx -> c = ctx -> code[i];
304 ctx -> string = ident;
305 ctx -> integer = atoi(ident);
306 ctx -> token = INTEGER;
309 static void
310 oberon_skip_space(oberon_context_t * ctx)
312 while(isspace(ctx -> c))
314 oberon_get_char(ctx);
318 static void
319 oberon_read_symbol(oberon_context_t * ctx)
321 int c = ctx -> c;
322 switch(c)
324 case 0:
325 ctx -> token = EOF_;
326 break;
327 case ';':
328 ctx -> token = SEMICOLON;
329 oberon_get_char(ctx);
330 break;
331 case ':':
332 ctx -> token = COLON;
333 oberon_get_char(ctx);
334 if(ctx -> c == '=')
336 ctx -> token = ASSIGN;
337 oberon_get_char(ctx);
339 break;
340 case '.':
341 ctx -> token = DOT;
342 oberon_get_char(ctx);
343 break;
344 case '(':
345 ctx -> token = LPAREN;
346 oberon_get_char(ctx);
347 break;
348 case ')':
349 ctx -> token = RPAREN;
350 oberon_get_char(ctx);
351 break;
352 case '=':
353 ctx -> token = EQUAL;
354 oberon_get_char(ctx);
355 break;
356 case '#':
357 ctx -> token = NEQ;
358 oberon_get_char(ctx);
359 break;
360 case '<':
361 ctx -> token = LESS;
362 oberon_get_char(ctx);
363 if(ctx -> c == '=')
365 ctx -> token = LEQ;
366 oberon_get_char(ctx);
368 break;
369 case '>':
370 ctx -> token = GREAT;
371 oberon_get_char(ctx);
372 if(ctx -> c == '=')
374 ctx -> token = GEQ;
375 oberon_get_char(ctx);
377 break;
378 case '+':
379 ctx -> token = PLUS;
380 oberon_get_char(ctx);
381 break;
382 case '-':
383 ctx -> token = MINUS;
384 oberon_get_char(ctx);
385 break;
386 case '*':
387 ctx -> token = STAR;
388 oberon_get_char(ctx);
389 break;
390 case '/':
391 ctx -> token = SLASH;
392 oberon_get_char(ctx);
393 break;
394 case '&':
395 ctx -> token = AND;
396 oberon_get_char(ctx);
397 break;
398 case '~':
399 ctx -> token = NOT;
400 oberon_get_char(ctx);
401 break;
402 default:
403 oberon_error(ctx, "invalid char");
404 break;
408 static void
409 oberon_read_token(oberon_context_t * ctx)
411 oberon_skip_space(ctx);
413 int c = ctx -> c;
414 if(isalpha(c))
416 oberon_read_ident(ctx);
418 else if(isdigit(c))
420 oberon_read_integer(ctx);
422 else
424 oberon_read_symbol(ctx);
428 // =======================================================================
429 // EXPRESSION
430 // =======================================================================
432 static void oberon_expect_token(oberon_context_t * ctx, int token);
433 static oberon_expr_t * oberon_expr(oberon_context_t * ctx);
434 static void oberon_assert_token(oberon_context_t * ctx, int token);
435 static char * oberon_assert_ident(oberon_context_t * ctx);
437 static oberon_expr_t *
438 oberon_new_operator(int op, oberon_type_t * result, oberon_expr_t * left, oberon_expr_t * right)
440 oberon_oper_t * operator;
441 operator = malloc(sizeof *operator);
442 memset(operator, 0, sizeof *operator);
444 operator -> is_item = 0;
445 operator -> result = result;
446 operator -> op = op;
447 operator -> left = left;
448 operator -> right = right;
450 return (oberon_expr_t *) operator;
453 static oberon_expr_t *
454 oberon_new_item(int mode, oberon_type_t * result)
456 oberon_item_t * item;
457 item = malloc(sizeof *item);
458 memset(item, 0, sizeof *item);
460 item -> is_item = 1;
461 item -> result = result;
462 item -> mode = mode;
464 return (oberon_expr_t *)item;
467 static oberon_expr_t *
468 oberon_make_unary_op(oberon_context_t * ctx, int token, oberon_expr_t * a)
470 oberon_expr_t * expr;
471 oberon_type_t * result;
473 result = a -> result;
475 if(token == MINUS)
477 if(result -> class != OBERON_TYPE_INTEGER)
479 oberon_error(ctx, "incompatible operator type");
482 expr = oberon_new_operator(OP_UNARY_MINUS, result, a, NULL);
484 else if(token == NOT)
486 if(result -> class != OBERON_TYPE_BOOLEAN)
488 oberon_error(ctx, "incompatible operator type");
491 expr = oberon_new_operator(OP_LOGIC_NOT, result, a, NULL);
493 else
495 oberon_error(ctx, "oberon_make_unary_op: wat");
498 return expr;
501 static oberon_expr_t *
502 oberon_factor(oberon_context_t * ctx)
504 char * name;
505 oberon_object_t * var;
506 oberon_expr_t * expr;
508 switch(ctx -> token)
510 case IDENT:
511 name = oberon_assert_ident(ctx);
512 var = oberon_find_object(ctx -> decl, name);
513 if(var -> class == OBERON_CLASS_VAR)
515 expr = oberon_new_item(MODE_VAR, var -> type);
517 else if(var -> class == OBERON_CLASS_PROC)
519 expr = oberon_new_item(MODE_CALL, var -> type);
521 else
523 oberon_error(ctx, "invalid designator");
526 expr -> item.var = var;
527 if(ctx -> token == LPAREN)
529 oberon_assert_token(ctx, LPAREN);
530 expr -> item.mode = MODE_CALL;
531 oberon_assert_token(ctx, RPAREN);
533 break;
534 case INTEGER:
535 expr = oberon_new_item(MODE_INTEGER, ctx -> int_type);
536 expr -> item.integer = ctx -> integer;
537 oberon_assert_token(ctx, INTEGER);
538 break;
539 case TRUE:
540 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
541 expr -> item.boolean = 1;
542 oberon_assert_token(ctx, TRUE);
543 break;
544 case FALSE:
545 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
546 expr -> item.boolean = 0;
547 oberon_assert_token(ctx, FALSE);
548 break;
549 case LPAREN:
550 oberon_assert_token(ctx, LPAREN);
551 expr = oberon_expr(ctx);
552 oberon_assert_token(ctx, RPAREN);
553 break;
554 case NOT:
555 oberon_assert_token(ctx, NOT);
556 expr = oberon_factor(ctx);
557 expr = oberon_make_unary_op(ctx, NOT, expr);
558 break;
559 default:
560 oberon_error(ctx, "invalid expression");
563 return expr;
566 /*
567 * oberon_autocast_binary_op автоматически переобразовывеат тип по след. правилам:
568 * 1. Классы обоих типов должны быть одинаковы
569 * 2. В качестве результата должен быть выбран больший тип.
570 * 3. Если размер результат не должен быть меньше чем базовый int
571 */
573 static void
574 oberon_autocast_binary_op(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b, oberon_type_t ** result)
576 if((a -> class) != (b -> class))
578 oberon_error(ctx, "incompatible types");
581 if((a -> size) > (b -> size))
583 *result = a;
585 else
587 *result = b;
590 if(((*result) -> class) == OBERON_TYPE_INTEGER)
592 if(((*result) -> size) < (ctx -> int_type -> size))
594 *result = ctx -> int_type;
598 /* TODO: cast types */
601 #define ITMAKESBOOLEAN(x) \
602 (((x) >= EQUAL && (x) <= GEQ) || ((x) == OR) || ((x) == AND))
604 #define ITUSEONLYINTEGER(x) \
605 ((x) >= LESS && (x) <= GEQ)
607 #define ITUSEONLYBOOLEAN(x) \
608 (((x) == OR) || ((x) == AND))
610 static oberon_expr_t *
611 oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
613 oberon_expr_t * expr;
614 oberon_type_t * result;
616 oberon_autocast_binary_op(ctx, a -> result, b -> result, &result);
618 if(ITMAKESBOOLEAN(token))
620 if(ITUSEONLYINTEGER(token))
622 if(a -> result -> class != OBERON_TYPE_INTEGER
623 && b -> result -> class != OBERON_TYPE_INTEGER)
625 oberon_error(ctx, "used only with integer types");
628 else if(ITUSEONLYBOOLEAN(token))
630 if(a -> result -> class != OBERON_TYPE_BOOLEAN
631 && b -> result -> class != OBERON_TYPE_BOOLEAN)
633 oberon_error(ctx, "used only with boolean type");
637 if(token == EQUAL)
639 expr = oberon_new_operator(OP_EQ, result, a, b);
641 else if(token == NEQ)
643 expr = oberon_new_operator(OP_NEQ, result, a, b);
645 else if(token == LESS)
647 expr = oberon_new_operator(OP_LSS, result, a, b);
649 else if(token == LEQ)
651 expr = oberon_new_operator(OP_LEQ, result, a, b);
653 else if(token == GREAT)
655 expr = oberon_new_operator(OP_GRT, result, a, b);
657 else if(token == GEQ)
659 expr = oberon_new_operator(OP_GEQ, result, a, b);
661 else if(token == OR)
663 expr = oberon_new_operator(OP_LOGIC_OR, result, a, b);
665 else if(token == AND)
667 expr = oberon_new_operator(OP_LOGIC_AND, result, a, b);
669 else
671 oberon_error(ctx, "oberon_make_bin_op: bool wat");
674 else
676 if(token == PLUS)
678 expr = oberon_new_operator(OP_ADD, result, a, b);
680 else if(token == MINUS)
682 expr = oberon_new_operator(OP_SUB, result, a, b);
684 else if(token == STAR)
686 expr = oberon_new_operator(OP_MUL, result, a, b);
688 else if(token == SLASH)
690 expr = oberon_new_operator(OP_DIV, result, a, b);
692 else if(token == DIV)
694 expr = oberon_new_operator(OP_DIV, result, a, b);
696 else if(token == MOD)
698 expr = oberon_new_operator(OP_MOD, result, a, b);
700 else
702 oberon_error(ctx, "oberon_make_bin_op: bin wat");
706 return expr;
709 #define ISMULOP(x) \
710 ((x) >= STAR && (x) <= AND)
712 static oberon_expr_t *
713 oberon_term_expr(oberon_context_t * ctx)
715 oberon_expr_t * expr;
717 expr = oberon_factor(ctx);
718 while(ISMULOP(ctx -> token))
720 int token = ctx -> token;
721 oberon_read_token(ctx);
723 oberon_expr_t * inter = oberon_factor(ctx);
724 expr = oberon_make_bin_op(ctx, token, expr, inter);
727 return expr;
730 #define ISADDOP(x) \
731 ((x) >= PLUS && (x) <= OR)
733 static oberon_expr_t *
734 oberon_simple_expr(oberon_context_t * ctx)
736 oberon_expr_t * expr;
738 int minus = 0;
739 if(ctx -> token == PLUS)
741 minus = 0;
742 oberon_assert_token(ctx, PLUS);
744 else if(ctx -> token == MINUS)
746 minus = 1;
747 oberon_assert_token(ctx, MINUS);
750 expr = oberon_term_expr(ctx);
751 while(ISADDOP(ctx -> token))
753 int token = ctx -> token;
754 oberon_read_token(ctx);
756 oberon_expr_t * inter = oberon_term_expr(ctx);
757 expr = oberon_make_bin_op(ctx, token, expr, inter);
760 if(minus)
762 expr = oberon_make_unary_op(ctx, MINUS, expr);
765 return expr;
768 #define ISRELATION(x) \
769 ((x) >= EQUAL && (x) <= GEQ)
771 static oberon_expr_t *
772 oberon_expr(oberon_context_t * ctx)
774 oberon_expr_t * expr;
776 expr = oberon_simple_expr(ctx);
777 while(ISRELATION(ctx -> token))
779 int token = ctx -> token;
780 oberon_read_token(ctx);
782 oberon_expr_t * inter = oberon_simple_expr(ctx);
783 expr = oberon_make_bin_op(ctx, token, expr, inter);
786 return expr;
789 // =======================================================================
790 // PARSER
791 // =======================================================================
793 static void oberon_statement_seq(oberon_context_t * ctx);
795 static void
796 oberon_expect_token(oberon_context_t * ctx, int token)
798 if(ctx -> token != token)
800 oberon_error(ctx, "unexpected token %i (%i)", ctx -> token, token);
804 static void
805 oberon_assert_token(oberon_context_t * ctx, int token)
807 oberon_expect_token(ctx, token);
808 oberon_read_token(ctx);
811 static char *
812 oberon_assert_ident(oberon_context_t * ctx)
814 oberon_expect_token(ctx, IDENT);
815 char * ident = ctx -> string;
816 oberon_read_token(ctx);
817 return ident;
820 static oberon_type_t *
821 oberon_type(oberon_context_t * ctx)
823 char * name = oberon_assert_ident(ctx);
824 oberon_type_t * type = oberon_find_type(ctx -> decl, name);
825 return type;
828 static void
829 oberon_var_decl(oberon_context_t * ctx)
831 char * name = oberon_assert_ident(ctx);
832 oberon_assert_token(ctx, COLON);
833 oberon_type_t * type = oberon_type(ctx);
834 oberon_define_var(ctx -> decl, name, type);
837 static void
838 oberon_make_procedure_begin(oberon_context_t * ctx, char * name)
840 oberon_object_t * proc;
841 proc = oberon_define_proc(ctx -> decl, name);
843 oberon_open_scope(ctx);
845 oberon_generate_begin_proc(ctx, proc);
848 static void
849 oberon_make_procedure_end(oberon_context_t * ctx)
851 oberon_generate_end_proc(ctx);
853 oberon_close_scope(ctx -> decl);
856 static void
857 oberon_proc_decl(oberon_context_t * ctx)
859 oberon_assert_token(ctx, PROCEDURE);
861 char * name;
862 name = oberon_assert_ident(ctx);
864 oberon_assert_token(ctx, SEMICOLON);
866 oberon_make_procedure_begin(ctx, name);
867 if(ctx -> token == BEGIN)
869 oberon_assert_token(ctx, BEGIN);
870 oberon_statement_seq(ctx);
872 oberon_make_procedure_end(ctx);
874 oberon_assert_token(ctx, END);
875 char * name2 = oberon_assert_ident(ctx);
877 if(strcmp(name2, name) != 0)
879 oberon_error(ctx, "procedure name not matched");
883 static void
884 oberon_decl_seq(oberon_context_t * ctx)
886 if(ctx -> token == VAR)
888 oberon_assert_token(ctx, VAR);
889 while(ctx -> token == IDENT)
891 oberon_var_decl(ctx);
892 oberon_assert_token(ctx, SEMICOLON);
896 if(ctx -> token == PROCEDURE)
898 oberon_proc_decl(ctx);
899 oberon_assert_token(ctx, SEMICOLON);
903 static void
904 oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
906 if(src -> result -> class != dst -> result -> class)
908 oberon_error(ctx, "incompatible assignment types");
911 if(dst -> result -> class == OBERON_TYPE_INTEGER)
913 if((dst -> result -> size) < (src -> result -> size))
915 oberon_error(ctx, "incompatible assignment type size");
919 oberon_generate_assign(ctx, src, dst);
922 static void
923 oberon_make_call(oberon_context_t * ctx, oberon_expr_t * desig)
925 if(desig -> is_item == 0)
927 oberon_error(ctx, "expected item");
930 if(desig -> item.mode != MODE_CALL)
932 oberon_error(ctx, "expected mode CALL");
935 if(desig -> item.var -> class != OBERON_CLASS_PROC)
937 oberon_error(ctx, "only procedures can be called");
940 // TODO check arguments
942 oberon_generate_call_proc(ctx, desig);
945 static void
946 oberon_statement(oberon_context_t * ctx)
948 oberon_expr_t * item1;
949 oberon_expr_t * item2;
951 if(ctx -> token == IDENT)
953 item1 = oberon_expr(ctx);
954 if(ctx -> token == ASSIGN)
956 oberon_assert_token(ctx, ASSIGN);
957 item2 = oberon_expr(ctx);
958 oberon_assign(ctx, item2, item1);
960 else
962 oberon_make_call(ctx, item1);
967 static void
968 oberon_statement_seq(oberon_context_t * ctx)
970 oberon_statement(ctx);
971 while(ctx -> token == SEMICOLON)
973 oberon_assert_token(ctx, SEMICOLON);
974 oberon_statement(ctx);
978 static void
979 oberon_parse_module(oberon_context_t * ctx)
981 char *name1, *name2;
982 oberon_read_token(ctx);
984 oberon_assert_token(ctx, MODULE);
985 name1 = oberon_assert_ident(ctx);
986 oberon_assert_token(ctx, SEMICOLON);
987 ctx -> mod -> name = name1;
989 oberon_decl_seq(ctx);
991 if(ctx -> token == BEGIN)
993 oberon_assert_token(ctx, BEGIN);
994 oberon_generate_begin_module(ctx);
995 oberon_statement_seq(ctx);
996 oberon_generate_end_module(ctx);
999 oberon_assert_token(ctx, END);
1000 name2 = oberon_assert_ident(ctx);
1001 oberon_assert_token(ctx, DOT);
1003 if(strcmp(name1, name2) != 0)
1005 oberon_error(ctx, "module name not matched");
1009 // =======================================================================
1010 // LIBRARY
1011 // =======================================================================
1013 static oberon_type_t *
1014 oberon_new_type_ptr(int class)
1016 oberon_type_t * x = malloc(sizeof *x);
1017 memset(x, 0, sizeof *x);
1018 x -> class = class;
1019 return x;
1022 static oberon_type_t *
1023 oberon_new_type_integer(int size)
1025 oberon_type_t * x;
1026 x = oberon_new_type_ptr(OBERON_TYPE_INTEGER);
1027 x -> size = size;
1028 return x;
1031 static oberon_type_t *
1032 oberon_new_type_boolean(int size)
1034 oberon_type_t * x;
1035 x = oberon_new_type_ptr(OBERON_TYPE_BOOLEAN);
1036 x -> size = size;
1037 return x;
1040 static void
1041 register_default_types(oberon_context_t * ctx)
1043 ctx -> int_type = oberon_new_type_integer(sizeof(int));
1044 ctx -> bool_type = oberon_new_type_boolean(sizeof(int));
1046 oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type);
1047 oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type);
1050 oberon_context_t *
1051 oberon_create_context()
1053 oberon_context_t * ctx = malloc(sizeof *ctx);
1054 memset(ctx, 0, sizeof *ctx);
1056 oberon_scope_t * world_scope;
1057 world_scope = oberon_open_scope(ctx);
1058 ctx -> world_scope = world_scope;
1060 oberon_generator_init_context(ctx);
1062 register_default_types(ctx);
1064 return ctx;
1067 void
1068 oberon_destroy_context(oberon_context_t * ctx)
1070 oberon_generator_destroy_context(ctx);
1071 free(ctx);
1074 oberon_module_t *
1075 oberon_compile_module(oberon_context_t * ctx, const char * code)
1077 oberon_module_t * mod = malloc(sizeof *mod);
1078 memset(mod, 0, sizeof *mod);
1079 ctx -> mod = mod;
1081 oberon_scope_t * module_scope;
1082 module_scope = oberon_open_scope(ctx);
1083 mod -> decl = module_scope;
1085 oberon_init_scaner(ctx, code);
1086 oberon_parse_module(ctx);
1088 oberon_generate_code(ctx);
1090 ctx -> mod = NULL;
1091 return mod;