DEADSOFTWARE

94bc1696a8f54f281e8868cfa02d7a51f1800cb0
[dsw-obn.git] / generator.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 <gc.h>
10 #include "oberon.h"
11 #include "generator.h"
13 // =======================================================================
14 // INTERNAL FUNCTIONS
15 // =======================================================================
17 static void *
18 __OBERON_ALLOC__ (size_t bytes)
19 {
20 void * p = GC_MALLOC(bytes);
21 memset(p, 0, bytes);
22 return p;
23 }
25 // =======================================================================
26 // ALLOC
27 // =======================================================================
29 static void
30 oberon_generator_open_block(gen_context_t * gen_context, gcc_jit_block * gcc_block)
31 {
32 gen_block_t * block = malloc(sizeof *block);
33 memset(block, 0, sizeof *block);
35 block -> gcc_block = gcc_block;
36 block -> up = gen_context -> block;
38 gen_context -> block = block;
39 }
41 static void
42 oberon_generator_close_block(gen_context_t * gen_context)
43 {
44 gen_context -> block = gen_context -> block -> up;
45 }
47 void
48 oberon_generator_init_context(oberon_context_t * ctx)
49 {
50 gen_context_t * gen_context = malloc(sizeof *gen_context);
51 memset(gen_context, 0, sizeof *gen_context);
53 gcc_jit_context * gcc_context;
54 gcc_context = gcc_jit_context_acquire();
56 ctx -> gen_context = gen_context;
57 gen_context -> gcc_context = gcc_context;
59 gcc_jit_type * void_ptr_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID_PTR);
60 gcc_jit_type * size_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_SIZE_T);
61 gcc_jit_type * alloc_ptr_type = gcc_jit_context_new_function_ptr_type(
62 gcc_context, NULL, void_ptr_type, 1, &size_type, 0
63 );
64 gen_context -> gcc_alloc = gcc_jit_context_new_global(
65 gcc_context, NULL, GCC_JIT_GLOBAL_EXPORTED, alloc_ptr_type, "__OBERON_ALLOC__"
66 );
67 }
69 void
70 oberon_generator_destroy_context(oberon_context_t * ctx)
71 {
72 gen_context_t * gen_context = ctx -> gen_context;
73 gcc_jit_context * gcc_context = gen_context -> gcc_context;
75 gcc_jit_context_release(gcc_context);
76 }
78 void
79 oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type)
80 {
81 gen_type_t * gen_type = malloc(sizeof *gen_type);
82 memset(gen_type, 0, sizeof *gen_type);
83 type -> gen_type = gen_type;
85 gen_context_t * gen_context = ctx -> gen_context;
86 gcc_jit_context * gcc_context = gen_context -> gcc_context;
88 gcc_jit_type * gcc_type = NULL;
89 gcc_jit_struct * gcc_struct = NULL;
90 if(type -> class == OBERON_TYPE_VOID)
91 {
92 gcc_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID);
93 }
94 else if(type -> class == OBERON_TYPE_INTEGER)
95 {
96 gcc_type = gcc_jit_context_get_int_type(gcc_context, type -> size, 1);
97 }
98 else if(type -> class == OBERON_TYPE_BOOLEAN)
99 {
100 gcc_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_BOOL);
102 else if(type -> class == OBERON_TYPE_ARRAY)
104 gen_type_t * gen_base = type -> base -> gen_type;
105 gcc_jit_type * gcc_base = gen_base -> gcc_type;
106 gcc_type = gcc_jit_context_new_array_type(gcc_context, NULL, gcc_base, type -> size);
108 else if(type -> class == OBERON_TYPE_RECORD)
110 char name[32];
111 snprintf(name, 32, "RECORD%u", gen_context -> record_count);
112 gen_context -> record_count += 1;
114 gcc_struct = gcc_jit_context_new_opaque_struct(gcc_context, NULL, name);
115 gcc_type = gcc_jit_struct_as_type(gcc_struct);
117 else if(type -> class == OBERON_TYPE_POINTER)
119 gen_type_t * gen_base = type -> base -> gen_type;
120 gcc_jit_type * gcc_base = gen_base -> gcc_type;
121 gcc_type = gcc_jit_type_get_pointer(gcc_base);
123 else if(type -> class == OBERON_TYPE_PROCEDURE)
125 int num_params = type -> num_decl;
126 gcc_jit_type * params[num_params];
127 oberon_object_t * o = type -> decl;
128 for(int i = 0; i < num_params; i++)
130 gen_type_t * gen_type = o -> type -> gen_type;
131 params[i] = gen_type -> gcc_type;
132 o = o -> next;
135 gen_type_t * base = type -> base -> gen_type;
136 gcc_jit_type * result_type = base -> gcc_type;
138 gcc_type = gcc_jit_context_new_function_ptr_type(
139 gcc_context, NULL, result_type, num_params, params, 0
140 );
142 else
144 oberon_error(ctx, "oberon_generator_init_type: invalid type class %i", type -> class);
147 assert(gcc_type);
148 gen_type -> gcc_type = gcc_type;
149 gen_type -> gcc_struct = gcc_struct;
152 void
153 oberon_generator_init_record(oberon_context_t * ctx, oberon_type_t * type)
155 assert(type -> class == OBERON_TYPE_RECORD);
157 gen_type_t * gen_type = type -> gen_type;
158 gcc_jit_struct * gcc_struct = gen_type -> gcc_struct;
160 // TODO type exstension
162 int num_fields = type -> num_decl;
163 gcc_jit_field * fields[num_fields];
164 oberon_object_t * o = type -> decl;
165 for(int i = 0; i < num_fields; i++)
167 assert(o -> class == OBERON_CLASS_FIELD);
168 gen_var_t * var = o -> gen_var;
169 fields[i] = var -> gcc_field;
170 o = o -> next;
173 gcc_jit_struct_set_fields (gcc_struct, NULL, num_fields, fields);
175 //gcc_struct = gcc_jit_context_new_struct_type(gcc_context, NULL, "", num_fields, fields);
178 static void
179 oberon_generator_get_full_name(char * name, int max_len, oberon_object_t * x)
181 if(!x)
183 name[0] = 0;
184 return;
187 int add_module_prefix;
188 switch(x -> class)
190 case OBERON_CLASS_FIELD:
191 case OBERON_CLASS_PARAM:
192 case OBERON_CLASS_VAR_PARAM:
193 /* В локальных областях префиксы излишни */
194 add_module_prefix = 0;
195 break;
196 default:
197 add_module_prefix = 1;
198 break;
201 char parent[256];
202 oberon_generator_get_full_name(parent, 256, x -> parent);
204 if(strlen(parent) > 0)
206 snprintf(name, max_len, "%s_%s", parent, x -> name);
208 else if(add_module_prefix)
210 snprintf(name, max_len, "%s_%s", x -> module -> name, x -> name);
212 else
214 snprintf(name, max_len, "%s", x -> name);
218 void
219 oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var)
221 gen_context_t * gen_context = ctx -> gen_context;
222 gen_type_t * gen_type = var -> type -> gen_type;
224 gen_var_t * gen_var = malloc(sizeof *gen_var);
225 memset(gen_var, 0, sizeof *gen_var);
226 var -> gen_var = gen_var;
228 gcc_jit_context * gcc_context = gen_context -> gcc_context;
229 gcc_jit_type * gcc_type = gen_type -> gcc_type;
231 char name[256];
232 oberon_generator_get_full_name(name, 256, var);
234 gcc_jit_lvalue * gcc_lvalue = NULL;
235 gcc_jit_param * gcc_param = NULL;
236 gcc_jit_field * gcc_field = NULL;
237 if(var -> class == OBERON_CLASS_VAR)
239 if(var -> local)
241 gen_proc_t * gen_func = var -> parent -> gen_proc;
242 gcc_jit_function * func = gen_func -> gcc_func;
244 gcc_lvalue = gcc_jit_function_new_local(func, NULL, gcc_type, name);
246 else
248 gcc_lvalue = gcc_jit_context_new_global(
249 gcc_context, NULL, GCC_JIT_GLOBAL_EXPORTED, gcc_type, name
250 );
253 else if(var -> class == OBERON_CLASS_PARAM)
255 gcc_param = gcc_jit_context_new_param(gcc_context, NULL, gcc_type, name);
256 gcc_lvalue = gcc_jit_param_as_lvalue(gcc_param);
258 else if(var -> class == OBERON_CLASS_VAR_PARAM)
260 gcc_type = gcc_jit_type_get_pointer(gcc_type);
261 gcc_param = gcc_jit_context_new_param(gcc_context, NULL, gcc_type, name);
262 gcc_lvalue = gcc_jit_param_as_lvalue(gcc_param);
264 else if(var -> class == OBERON_CLASS_FIELD)
266 gcc_field = gcc_jit_context_new_field(gcc_context, NULL, gcc_type, name);
268 else
270 oberon_error(ctx, "oberon_generator_init_var: invalid class %i", var -> class);
273 gen_var -> gcc_lvalue = gcc_lvalue;
274 gen_var -> gcc_param = gcc_param;
275 gen_var -> gcc_field = gcc_field;
278 void
279 oberon_generator_init_proc(oberon_context_t * ctx, oberon_object_t * proc)
281 if(proc -> local)
283 oberon_error(ctx, "generator: local procedures not supported");
286 gen_context_t * gen_context = ctx -> gen_context;
287 gcc_jit_context * gcc_context = gen_context -> gcc_context;
289 gen_proc_t * gen_proc = malloc(sizeof *gen_proc);
290 memset(gen_proc, 0, sizeof *gen_proc);
291 proc -> gen_proc = gen_proc;
293 char name[256];
294 oberon_generator_get_full_name(name, 256, proc);
296 gen_type_t * gen_result_type = proc -> type -> base -> gen_type;
297 gcc_jit_type * result_type = gen_result_type -> gcc_type;
299 /* Строим список параметров */
300 int num_param = proc -> type -> num_decl;
301 oberon_object_t * o = proc -> type -> decl;
302 gcc_jit_param * params[num_param];
303 for(int i = 0; i < num_param; i++)
305 gen_var_t * param_var = o -> gen_var;
306 params[i] = param_var -> gcc_param;
307 o = o -> next;
310 gcc_jit_function * gcc_func;
311 gcc_func = gcc_jit_context_new_function(
312 gcc_context, NULL, GCC_JIT_FUNCTION_EXPORTED, result_type, name, num_param, params, 0
313 );
315 gen_proc -> gcc_func = gcc_func;
318 // =======================================================================
319 // GENERATOR
320 // =======================================================================
322 static gcc_jit_rvalue * rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item);
323 static gcc_jit_rvalue * rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr);
325 static int
326 oberon_generator_get_type_size(oberon_type_t * type)
328 printf("TODO: oberon_generator_get_type_size\n");
329 return 128;
332 void
333 oberon_generate_begin_module(oberon_context_t * ctx)
335 gen_context_t * gen_context = ctx -> gen_context;
336 gcc_jit_context * gcc_context = gen_context -> gcc_context;
338 char name[256];
339 snprintf(name, 256, "%s_BEGIN", ctx -> mod -> name);
341 gcc_jit_type * void_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID);
342 gcc_jit_function * func = gcc_jit_context_new_function(
343 gcc_context, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, name, 0, NULL, 0
344 );
345 gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL);
347 oberon_generator_open_block(gen_context, gcc_block);
350 void
351 oberon_generate_end_module(oberon_context_t * ctx)
353 gen_context_t * gen_context = ctx -> gen_context;
354 gcc_jit_block * gcc_block = gen_context -> block -> gcc_block;
356 gcc_jit_block_end_with_void_return(gcc_block, NULL);
358 oberon_generator_close_block(gen_context);
361 void
362 oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc)
364 gen_context_t * gen_context = ctx -> gen_context;
365 gen_proc_t * gen_proc = proc -> gen_proc;
367 gcc_jit_function * func = gen_proc -> gcc_func;
368 gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL);
370 oberon_generator_open_block(gen_context, gcc_block);
373 void
374 oberon_generate_call_proc(oberon_context_t * ctx, oberon_expr_t * desig)
376 gen_context_t * gen_context = ctx -> gen_context;
377 gen_block_t * gen_block = gen_context -> block;
378 gcc_jit_block * block = gen_block -> gcc_block;
380 gcc_jit_rvalue * return_value;
381 return_value = rvalue_from_expr(ctx, desig);
382 gcc_jit_block_add_eval(block, NULL, return_value);
385 void
386 oberon_generate_end_proc(oberon_context_t * ctx)
388 gen_context_t * gen_context = ctx -> gen_context;
389 oberon_generator_close_block(gen_context);
392 void
393 oberon_generate_return(oberon_context_t * ctx, oberon_expr_t * expr)
395 gen_context_t * gen_context = ctx -> gen_context;
396 gen_block_t * gen_block = gen_context -> block;
397 gcc_jit_block * gcc_block = gen_block -> gcc_block;
399 if(expr == NULL)
401 gcc_jit_block_end_with_void_return(gcc_block, NULL);
403 else
405 gcc_jit_rvalue * r = rvalue_from_expr(ctx, expr);
406 gcc_jit_block_end_with_return(gcc_block, NULL, r);
410 static gcc_jit_lvalue *
411 lvalue_from_item(oberon_context_t * ctx, oberon_item_t * item)
413 gen_context_t * gen_context = ctx -> gen_context;
414 gcc_jit_context * gcc_context = gen_context -> gcc_context;
416 gcc_jit_lvalue * left;
418 if(item -> mode == MODE_VAR)
420 if(item -> var -> class == OBERON_CLASS_PROC)
422 oberon_error(ctx, "casting static procedure to pointer not supported by generator");
425 gen_var_t * gen_var = item -> var -> gen_var;
426 left = gen_var -> gcc_lvalue;
427 if(item -> var -> class == OBERON_CLASS_VAR_PARAM)
429 gcc_jit_rvalue * r = gcc_jit_lvalue_as_rvalue(left);
430 left = gcc_jit_rvalue_dereference(r, NULL);
433 else if(item -> mode == MODE_INDEX)
435 assert(item -> num_args == 1);
436 gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
437 gcc_jit_rvalue * index = rvalue_from_expr(ctx, item -> args);
438 left = gcc_jit_context_new_array_access(gcc_context, NULL, parent, index);
440 else if(item -> mode == MODE_FIELD)
442 printf("lvalue_from_item: %s\n", item -> var -> name);
443 gen_var_t * gen_var = item -> var -> gen_var;
444 gcc_jit_field * gcc_field = gen_var -> gcc_field;
446 gcc_jit_lvalue * parent = lvalue_from_item(ctx, item -> parent);
447 left = gcc_jit_lvalue_access_field(parent, NULL, gcc_field);
449 else if(item -> mode == MODE_DEREF)
451 gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
452 left = gcc_jit_rvalue_dereference(parent, NULL);
454 else
456 oberon_error(ctx, "lvalue_from_item: invalid mode %i", item -> mode);
459 return left;
462 static gcc_jit_lvalue *
463 lvalue_from_expr(oberon_context_t *ctx, oberon_expr_t * expr)
465 gcc_jit_lvalue * left;
466 oberon_item_t * item;
468 if(expr -> is_item)
470 item = (oberon_item_t *) expr;
471 left = lvalue_from_item(ctx, item);
473 else
475 oberon_error(ctx, "invalid lvalue expression");
478 return left;
481 static gcc_jit_rvalue *
482 rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item)
484 gen_context_t * gen_context = ctx -> gen_context;
485 gcc_jit_context * gcc_context = gen_context -> gcc_context;
487 gcc_jit_rvalue * right;
488 if(item -> mode == MODE_VAR)
490 gcc_jit_lvalue * left = lvalue_from_item(ctx, item);
491 right = gcc_jit_lvalue_as_rvalue(left);
493 else if(item -> mode == MODE_INTEGER)
495 gcc_jit_type * int_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_INT);
496 right = gcc_jit_context_new_rvalue_from_int(gcc_context, int_type, item -> integer);
498 else if(item -> mode == MODE_BOOLEAN)
500 gcc_jit_type * bool_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_BOOL);
501 if(item -> boolean)
503 right = gcc_jit_context_one(gcc_context, bool_type);
505 else
507 right = gcc_jit_context_zero(gcc_context, bool_type);
510 else if(item -> mode == MODE_CALL)
512 oberon_type_t * signature = item -> var -> type;
513 gen_proc_t * gen_proc = item -> var -> gen_proc;
515 int num_args = item -> num_args;
516 gcc_jit_rvalue *args[num_args];
518 oberon_expr_t * expr = item -> args;
519 oberon_object_t * arg_param = signature -> decl;
520 for(int i = 0; i < num_args; i++)
522 if(arg_param -> class == OBERON_CLASS_VAR_PARAM)
524 gcc_jit_lvalue * left = lvalue_from_expr(ctx, expr);
525 args[i] = gcc_jit_lvalue_get_address(left, NULL);
527 else
529 args[i] = rvalue_from_expr(ctx, expr);
531 expr = expr -> next;
532 arg_param = arg_param -> next;
535 gcc_jit_rvalue * fnptr;
536 gcc_jit_function * func;
537 switch(item -> var -> class)
539 case OBERON_CLASS_PROC:
540 func = gen_proc -> gcc_func;
541 right = gcc_jit_context_new_call(
542 gcc_context, NULL, func, num_args, args
543 );
544 break;
545 case OBERON_CLASS_VAR:
546 case OBERON_CLASS_VAR_PARAM:
547 case OBERON_CLASS_PARAM:
548 fnptr = gcc_jit_lvalue_as_rvalue(item -> var -> gen_var -> gcc_lvalue);
549 right = gcc_jit_context_new_call_through_ptr(
550 gcc_context, NULL, fnptr, num_args, args
551 );
552 break;
553 default:
554 assert(0);
555 break;
558 else if(item -> mode == MODE_INDEX)
560 gcc_jit_lvalue * left = lvalue_from_item(ctx, item);
561 right = gcc_jit_lvalue_as_rvalue(left);
563 else if(item -> mode == MODE_FIELD)
565 gen_var_t * gen_var = item -> var -> gen_var;
566 gcc_jit_field * gcc_field = gen_var -> gcc_field;
568 gcc_jit_rvalue * parent = rvalue_from_item(ctx, item -> parent);
569 right = gcc_jit_rvalue_access_field(parent, NULL, gcc_field);
571 else if(item -> mode == MODE_DEREF)
573 gcc_jit_lvalue * left = lvalue_from_item(ctx, item);
574 right = gcc_jit_lvalue_as_rvalue(left);
576 else if(item -> mode == MODE_NIL)
578 gcc_jit_type * type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID_PTR);
579 right = gcc_jit_context_null(gcc_context, type);
581 else if(item -> mode == MODE_NEWARR)
583 int type_size = oberon_generator_get_type_size(item -> type);
584 int array_size = type_size;
586 int num = item -> num_args;
587 oberon_expr_t * arg = item -> args;
588 for(int i = 0; i < num; i++)
590 array_size *= arg -> item.integer;
591 arg = arg -> next;
594 gcc_jit_type * size_type;
595 size_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_SIZE_T);
597 gcc_jit_rvalue * fnarg;
598 fnarg = gcc_jit_context_new_rvalue_from_int(gcc_context, size_type, array_size);
600 gcc_jit_type * result_type = item -> result -> gen_type -> gcc_type;
601 gcc_jit_rvalue * gcc_alloc = gcc_jit_lvalue_as_rvalue(gen_context -> gcc_alloc);
602 right = gcc_jit_context_new_call_through_ptr(gcc_context, NULL, gcc_alloc, 1, &fnarg);
603 right = gcc_jit_context_new_cast(gcc_context, NULL, right, result_type);
605 else
607 oberon_error(ctx, "rvalue_from_item: invalid mode %i", item -> mode);
610 return right;
613 struct {
614 int type; // 0 - unary, 1 - binary, 2 - comp
615 union {
616 enum gcc_jit_unary_op unary_op;
617 enum gcc_jit_binary_op binary_op;
618 enum gcc_jit_comparison comp_op;
619 };
620 } op_table[] = {
621 { 0, .unary_op = GCC_JIT_UNARY_OP_MINUS },
622 { 0, .unary_op = GCC_JIT_UNARY_OP_BITWISE_NEGATE },
623 { 0, .unary_op = GCC_JIT_UNARY_OP_LOGICAL_NEGATE },
624 { 0, .unary_op = GCC_JIT_UNARY_OP_ABS },
626 { 1, .binary_op = GCC_JIT_BINARY_OP_PLUS },
627 { 1, .binary_op = GCC_JIT_BINARY_OP_MINUS },
628 { 1, .binary_op = GCC_JIT_BINARY_OP_MULT },
629 { 1, .binary_op = GCC_JIT_BINARY_OP_DIVIDE },
630 { 1, .binary_op = GCC_JIT_BINARY_OP_MODULO },
631 { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_AND },
632 { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_XOR },
633 { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_OR },
634 { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_AND },
635 { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_OR },
637 { 2, .comp_op = GCC_JIT_COMPARISON_EQ },
638 { 2, .comp_op = GCC_JIT_COMPARISON_NE },
639 { 2, .comp_op = GCC_JIT_COMPARISON_LT },
640 { 2, .comp_op = GCC_JIT_COMPARISON_LE },
641 { 2, .comp_op = GCC_JIT_COMPARISON_GT },
642 { 2, .comp_op = GCC_JIT_COMPARISON_GE }
643 };
645 static gcc_jit_rvalue *
646 rvalue_from_operator(oberon_context_t * ctx, oberon_oper_t * operator)
648 gcc_jit_rvalue * right;
650 gen_context_t * gen_context = ctx -> gen_context;
651 gen_type_t * gen_type = operator -> result -> gen_type;
652 gcc_jit_context * gcc_context = gen_context -> gcc_context;
653 gcc_jit_type * result_type = gen_type -> gcc_type;
655 int expr_type = op_table[operator -> op].type;
656 if(expr_type == 0)
658 enum gcc_jit_unary_op op = op_table[operator -> op].unary_op;
659 gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left);
660 right = gcc_jit_context_new_unary_op(gcc_context, NULL, op, result_type, l);
662 else if(expr_type == 1)
664 enum gcc_jit_unary_op op = op_table[operator -> op].binary_op;
665 gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left);
666 gcc_jit_rvalue * r = rvalue_from_expr(ctx, operator -> right);
667 right = gcc_jit_context_new_binary_op(gcc_context, NULL, op, result_type, l, r);
669 else if(expr_type == 2)
671 enum gcc_jit_comparison op = op_table[operator -> op].comp_op;
672 gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left);
673 gcc_jit_rvalue * r = rvalue_from_expr(ctx, operator -> right);
674 right = gcc_jit_context_new_comparison(gcc_context, NULL, op, l, r);
676 else
678 oberon_error(ctx, "rvalue_from_operator: wat");
681 return right;
684 static gcc_jit_rvalue *
685 rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr)
687 gcc_jit_rvalue * right;
689 if(expr -> is_item)
691 oberon_item_t * item = (oberon_item_t *) expr;
692 right = rvalue_from_item(ctx, item);
694 else
696 oberon_oper_t * operator = (oberon_oper_t *) expr;
697 right = rvalue_from_operator(ctx, operator);
700 return right;
703 void
704 oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst)
706 gcc_jit_lvalue * left;
707 left = lvalue_from_expr(ctx, dst);
709 gcc_jit_rvalue * right;
710 right = rvalue_from_expr(ctx, src);
712 if(src -> is_item)
714 if(src -> item.mode == MODE_NIL)
716 gen_context_t * gen_context = ctx -> gen_context;
717 gcc_jit_context * gcc_context = gen_context -> gcc_context;
718 gen_type_t * gen_type = dst -> result -> gen_type;
719 gcc_jit_type * cast_to_type = gen_type -> gcc_type;
720 right = gcc_jit_context_new_cast(gcc_context, NULL, right, cast_to_type);
724 printf("oberon_generate_assign: class %i := class %i\n", dst -> result -> class, src -> result -> class);
726 gen_context_t * gen_context = ctx -> gen_context;
727 gen_block_t * gen_block = gen_context -> block;
728 gcc_jit_block * gcc_block = gen_block -> gcc_block;
729 gcc_jit_block_add_assignment(gcc_block, NULL, left, right);
732 void
733 oberon_generate_code(oberon_context_t * ctx)
735 gen_context_t * gen_context = ctx -> gen_context;
736 gcc_jit_context * gcc_context = gen_context -> gcc_context;
738 gcc_jit_result * gcc_result;
739 gcc_result = gcc_jit_context_compile(gcc_context);
741 gen_context -> gcc_result = gcc_result;
743 typedef void * (*TOberonAlloc)(size_t);
744 TOberonAlloc * fn_alloc_ptr = gcc_jit_result_get_global(gcc_result, "__OBERON_ALLOC__");
745 *fn_alloc_ptr = __OBERON_ALLOC__;
747 // ctx -> mod -> begin = gcc_jit_result_get_code(gcc_result, "BEGIN");
750 void
751 oberon_generator_dump(oberon_context_t * ctx, char * path)
753 gen_context_t * gen_context = ctx -> gen_context;
754 gcc_jit_context * gcc_context = gen_context -> gcc_context;
755 gcc_jit_context_dump_to_file(gcc_context, path, 0);
758 void *
759 oberon_generator_get_procedure(oberon_context_t * ctx, const char * name)
761 gen_context_t * gen_context = ctx -> gen_context;
762 gcc_jit_result * gcc_result = gen_context -> gcc_result;
764 return gcc_jit_result_get_code(gcc_result, name);
767 void *
768 oberon_generator_get_var(oberon_context_t * ctx, const char * name)
770 gen_context_t * gen_context = ctx -> gen_context;
771 gcc_jit_result * gcc_result = gen_context -> gcc_result;
773 return gcc_jit_result_get_global(gcc_result, name);