DEADSOFTWARE

Добавлены области видимости и вызовы процедур
[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 desinator");
525 expr -> item.var = var;
526 break;
527 case INTEGER:
528 expr = oberon_new_item(MODE_INTEGER, ctx -> int_type);
529 expr -> item.integer = ctx -> integer;
530 oberon_assert_token(ctx, INTEGER);
531 break;
532 case TRUE:
533 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
534 expr -> item.boolean = 1;
535 oberon_assert_token(ctx, TRUE);
536 break;
537 case FALSE:
538 expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type);
539 expr -> item.boolean = 0;
540 oberon_assert_token(ctx, FALSE);
541 break;
542 case LPAREN:
543 oberon_assert_token(ctx, LPAREN);
544 expr = oberon_expr(ctx);
545 oberon_assert_token(ctx, RPAREN);
546 break;
547 case NOT:
548 oberon_assert_token(ctx, NOT);
549 expr = oberon_factor(ctx);
550 expr = oberon_make_unary_op(ctx, NOT, expr);
551 break;
552 default:
553 oberon_error(ctx, "invalid expression");
556 return expr;
559 /*
560 * oberon_autocast_binary_op автоматически переобразовывеат тип по след. правилам:
561 * 1. Классы обоих типов должны быть одинаковы
562 * 2. В качестве результата должен быть выбран больший тип.
563 * 3. Если размер результат не должен быть меньше чем базовый int
564 */
566 static void
567 oberon_autocast_binary_op(oberon_context_t * ctx, oberon_type_t * a, oberon_type_t * b, oberon_type_t ** result)
569 if((a -> class) != (b -> class))
571 oberon_error(ctx, "incompatible types");
574 if((a -> size) > (b -> size))
576 *result = a;
578 else
580 *result = b;
583 if(((*result) -> class) == OBERON_TYPE_INTEGER)
585 if(((*result) -> size) < (ctx -> int_type -> size))
587 *result = ctx -> int_type;
591 /* TODO: cast types */
594 #define ITMAKESBOOLEAN(x) \
595 (((x) >= EQUAL && (x) <= GEQ) || ((x) == OR) || ((x) == AND))
597 #define ITUSEONLYINTEGER(x) \
598 ((x) >= LESS && (x) <= GEQ)
600 #define ITUSEONLYBOOLEAN(x) \
601 (((x) == OR) || ((x) == AND))
603 static oberon_expr_t *
604 oberon_make_bin_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b)
606 oberon_expr_t * expr;
607 oberon_type_t * result;
609 oberon_autocast_binary_op(ctx, a -> result, b -> result, &result);
611 if(ITMAKESBOOLEAN(token))
613 if(ITUSEONLYINTEGER(token))
615 if(a -> result -> class != OBERON_TYPE_INTEGER
616 && b -> result -> class != OBERON_TYPE_INTEGER)
618 oberon_error(ctx, "used only with integer types");
621 else if(ITUSEONLYBOOLEAN(token))
623 if(a -> result -> class != OBERON_TYPE_BOOLEAN
624 && b -> result -> class != OBERON_TYPE_BOOLEAN)
626 oberon_error(ctx, "used only with boolean type");
630 if(token == EQUAL)
632 expr = oberon_new_operator(OP_EQ, result, a, b);
634 else if(token == NEQ)
636 expr = oberon_new_operator(OP_NEQ, result, a, b);
638 else if(token == LESS)
640 expr = oberon_new_operator(OP_LSS, result, a, b);
642 else if(token == LEQ)
644 expr = oberon_new_operator(OP_LEQ, result, a, b);
646 else if(token == GREAT)
648 expr = oberon_new_operator(OP_GRT, result, a, b);
650 else if(token == GEQ)
652 expr = oberon_new_operator(OP_GEQ, result, a, b);
654 else if(token == OR)
656 expr = oberon_new_operator(OP_LOGIC_OR, result, a, b);
658 else if(token == AND)
660 expr = oberon_new_operator(OP_LOGIC_AND, result, a, b);
662 else
664 oberon_error(ctx, "oberon_make_bin_op: bool wat");
667 else
669 if(token == PLUS)
671 expr = oberon_new_operator(OP_ADD, result, a, b);
673 else if(token == MINUS)
675 expr = oberon_new_operator(OP_SUB, result, a, b);
677 else if(token == STAR)
679 expr = oberon_new_operator(OP_MUL, result, a, b);
681 else if(token == SLASH)
683 expr = oberon_new_operator(OP_DIV, result, a, b);
685 else if(token == DIV)
687 expr = oberon_new_operator(OP_DIV, result, a, b);
689 else if(token == MOD)
691 expr = oberon_new_operator(OP_MOD, result, a, b);
693 else
695 oberon_error(ctx, "oberon_make_bin_op: bin wat");
699 return expr;
702 #define ISMULOP(x) \
703 ((x) >= STAR && (x) <= AND)
705 static oberon_expr_t *
706 oberon_term_expr(oberon_context_t * ctx)
708 oberon_expr_t * expr;
710 expr = oberon_factor(ctx);
711 while(ISMULOP(ctx -> token))
713 int token = ctx -> token;
714 oberon_read_token(ctx);
716 oberon_expr_t * inter = oberon_factor(ctx);
717 expr = oberon_make_bin_op(ctx, token, expr, inter);
720 return expr;
723 #define ISADDOP(x) \
724 ((x) >= PLUS && (x) <= OR)
726 static oberon_expr_t *
727 oberon_simple_expr(oberon_context_t * ctx)
729 oberon_expr_t * expr;
731 int minus = 0;
732 if(ctx -> token == PLUS)
734 minus = 0;
735 oberon_assert_token(ctx, PLUS);
737 else if(ctx -> token == MINUS)
739 minus = 1;
740 oberon_assert_token(ctx, MINUS);
743 expr = oberon_term_expr(ctx);
744 while(ISADDOP(ctx -> token))
746 int token = ctx -> token;
747 oberon_read_token(ctx);
749 oberon_expr_t * inter = oberon_term_expr(ctx);
750 expr = oberon_make_bin_op(ctx, token, expr, inter);
753 if(minus)
755 expr = oberon_make_unary_op(ctx, MINUS, expr);
758 return expr;
761 #define ISRELATION(x) \
762 ((x) >= EQUAL && (x) <= GEQ)
764 static oberon_expr_t *
765 oberon_expr(oberon_context_t * ctx)
767 oberon_expr_t * expr;
769 expr = oberon_simple_expr(ctx);
770 while(ISRELATION(ctx -> token))
772 int token = ctx -> token;
773 oberon_read_token(ctx);
775 oberon_expr_t * inter = oberon_simple_expr(ctx);
776 expr = oberon_make_bin_op(ctx, token, expr, inter);
779 return expr;
782 // =======================================================================
783 // PARSER
784 // =======================================================================
786 static void oberon_statement_seq(oberon_context_t * ctx);
788 static void
789 oberon_expect_token(oberon_context_t * ctx, int token)
791 if(ctx -> token != token)
793 oberon_error(ctx, "unexpected token %i (%i)", ctx -> token, token);
797 static void
798 oberon_assert_token(oberon_context_t * ctx, int token)
800 oberon_expect_token(ctx, token);
801 oberon_read_token(ctx);
804 static char *
805 oberon_assert_ident(oberon_context_t * ctx)
807 oberon_expect_token(ctx, IDENT);
808 char * ident = ctx -> string;
809 oberon_read_token(ctx);
810 return ident;
813 static oberon_type_t *
814 oberon_type(oberon_context_t * ctx)
816 char * name = oberon_assert_ident(ctx);
817 oberon_type_t * type = oberon_find_type(ctx -> decl, name);
818 return type;
821 static void
822 oberon_var_decl(oberon_context_t * ctx)
824 char * name = oberon_assert_ident(ctx);
825 oberon_assert_token(ctx, COLON);
826 oberon_type_t * type = oberon_type(ctx);
827 oberon_define_var(ctx -> decl, name, type);
830 static void
831 oberon_make_procedure_begin(oberon_context_t * ctx, char * name)
833 oberon_object_t * proc;
834 proc = oberon_define_proc(ctx -> decl, name);
836 oberon_open_scope(ctx);
838 oberon_generate_begin_proc(ctx, proc);
841 static void
842 oberon_make_procedure_end(oberon_context_t * ctx)
844 oberon_generate_end_proc(ctx);
846 oberon_close_scope(ctx -> decl);
849 static void
850 oberon_proc_decl(oberon_context_t * ctx)
852 oberon_assert_token(ctx, PROCEDURE);
854 char * name;
855 name = oberon_assert_ident(ctx);
857 oberon_assert_token(ctx, SEMICOLON);
859 oberon_make_procedure_begin(ctx, name);
860 if(ctx -> token == BEGIN)
862 oberon_assert_token(ctx, BEGIN);
863 oberon_statement_seq(ctx);
865 oberon_make_procedure_end(ctx);
867 oberon_assert_token(ctx, END);
868 char * name2 = oberon_assert_ident(ctx);
870 if(strcmp(name2, name) != 0)
872 oberon_error(ctx, "procedure name not matched");
876 static void
877 oberon_decl_seq(oberon_context_t * ctx)
879 if(ctx -> token == VAR)
881 oberon_assert_token(ctx, VAR);
882 while(ctx -> token == IDENT)
884 oberon_var_decl(ctx);
885 oberon_assert_token(ctx, SEMICOLON);
889 if(ctx -> token == PROCEDURE)
891 oberon_proc_decl(ctx);
892 oberon_assert_token(ctx, SEMICOLON);
896 static void
897 oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
899 if(src -> result -> class != dst -> result -> class)
901 oberon_error(ctx, "incompatible assignment types");
904 if(dst -> result -> class == OBERON_TYPE_INTEGER)
906 if((dst -> result -> size) < (src -> result -> size))
908 oberon_error(ctx, "incompatible assignment type size");
912 oberon_generate_assign(ctx, src, dst);
915 static void
916 oberon_make_call(oberon_context_t * ctx, oberon_expr_t * desig)
918 if(desig -> is_item == 0)
920 oberon_error(ctx, "expected item");
923 if(desig -> item.mode != MODE_CALL)
925 oberon_error(ctx, "expected mode CALL");
928 if(desig -> item.var -> class != OBERON_CLASS_PROC)
930 oberon_error(ctx, "only procedures can be called");
933 // TODO check arguments
935 oberon_generate_call_proc(ctx, desig);
938 static void
939 oberon_statement(oberon_context_t * ctx)
941 oberon_expr_t * item1;
942 oberon_expr_t * item2;
944 if(ctx -> token == IDENT)
946 item1 = oberon_expr(ctx);
947 if(ctx -> token == ASSIGN)
949 oberon_assert_token(ctx, ASSIGN);
950 item2 = oberon_expr(ctx);
951 oberon_assign(ctx, item2, item1);
953 else
955 oberon_make_call(ctx, item1);
960 static void
961 oberon_statement_seq(oberon_context_t * ctx)
963 oberon_statement(ctx);
964 while(ctx -> token == SEMICOLON)
966 oberon_assert_token(ctx, SEMICOLON);
967 oberon_statement(ctx);
971 static void
972 oberon_parse_module(oberon_context_t * ctx)
974 char *name1, *name2;
975 oberon_read_token(ctx);
977 oberon_assert_token(ctx, MODULE);
978 name1 = oberon_assert_ident(ctx);
979 oberon_assert_token(ctx, SEMICOLON);
980 ctx -> mod -> name = name1;
982 oberon_decl_seq(ctx);
984 if(ctx -> token == BEGIN)
986 oberon_assert_token(ctx, BEGIN);
987 oberon_generate_begin_module(ctx);
988 oberon_statement_seq(ctx);
989 oberon_generate_end_module(ctx);
992 oberon_assert_token(ctx, END);
993 name2 = oberon_assert_ident(ctx);
994 oberon_assert_token(ctx, DOT);
996 if(strcmp(name1, name2) != 0)
998 oberon_error(ctx, "module name not matched");
1002 // =======================================================================
1003 // LIBRARY
1004 // =======================================================================
1006 static oberon_type_t *
1007 oberon_new_type_ptr(int class)
1009 oberon_type_t * x = malloc(sizeof *x);
1010 memset(x, 0, sizeof *x);
1011 x -> class = class;
1012 return x;
1015 static oberon_type_t *
1016 oberon_new_type_integer(int size)
1018 oberon_type_t * x;
1019 x = oberon_new_type_ptr(OBERON_TYPE_INTEGER);
1020 x -> size = size;
1021 return x;
1024 static oberon_type_t *
1025 oberon_new_type_boolean(int size)
1027 oberon_type_t * x;
1028 x = oberon_new_type_ptr(OBERON_TYPE_BOOLEAN);
1029 x -> size = size;
1030 return x;
1033 static void
1034 register_default_types(oberon_context_t * ctx)
1036 ctx -> int_type = oberon_new_type_integer(sizeof(int));
1037 ctx -> bool_type = oberon_new_type_boolean(sizeof(int));
1039 oberon_define_type(ctx -> world_scope, "INTEGER", ctx -> int_type);
1040 oberon_define_type(ctx -> world_scope, "BOOLEAN", ctx -> bool_type);
1043 oberon_context_t *
1044 oberon_create_context()
1046 oberon_context_t * ctx = malloc(sizeof *ctx);
1047 memset(ctx, 0, sizeof *ctx);
1049 oberon_scope_t * world_scope;
1050 world_scope = oberon_open_scope(ctx);
1051 ctx -> world_scope = world_scope;
1053 oberon_generator_init_context(ctx);
1055 register_default_types(ctx);
1057 return ctx;
1060 void
1061 oberon_destroy_context(oberon_context_t * ctx)
1063 oberon_generator_destroy_context(ctx);
1064 free(ctx);
1067 oberon_module_t *
1068 oberon_compile_module(oberon_context_t * ctx, const char * code)
1070 oberon_module_t * mod = malloc(sizeof *mod);
1071 memset(mod, 0, sizeof *mod);
1072 ctx -> mod = mod;
1074 oberon_scope_t * module_scope;
1075 module_scope = oberon_open_scope(ctx);
1076 mod -> decl = module_scope;
1078 oberon_init_scaner(ctx, code);
1079 oberon_parse_module(ctx);
1081 oberon_generate_code(ctx);
1083 ctx -> mod = NULL;
1084 return mod;