11 #include "generator.h"
13 // =======================================================================
15 // =======================================================================
18 __OBERON_ALLOC__ (size_t bytes
)
20 void * p
= GC_MALLOC(bytes
);
25 // =======================================================================
27 // =======================================================================
30 oberon_generator_open_block(gen_context_t
* gen_context
, gcc_jit_block
* gcc_block
)
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
;
42 oberon_generator_close_block(gen_context_t
* gen_context
)
44 gen_context
-> block
= gen_context
-> block
-> up
;
48 oberon_generator_init_context(oberon_context_t
* ctx
)
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
64 gen_context
-> gcc_alloc
= gcc_jit_context_new_global(
65 gcc_context
, NULL
, GCC_JIT_GLOBAL_EXPORTED
, alloc_ptr_type
, "__OBERON_ALLOC__"
70 oberon_generator_destroy_context(oberon_context_t
* ctx
)
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
);
79 oberon_generator_init_type(oberon_context_t
* ctx
, oberon_type_t
* type
)
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
)
92 gcc_type
= gcc_jit_context_get_type(gcc_context
, GCC_JIT_TYPE_VOID
);
94 else if(type
-> class == OBERON_TYPE_INTEGER
)
96 gcc_type
= gcc_jit_context_get_int_type(gcc_context
, type
-> size
, 1);
98 else if(type
-> class == OBERON_TYPE_BOOLEAN
)
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
)
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
;
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
144 oberon_error(ctx
, "oberon_generator_init_type: invalid type class %i", type
-> class);
148 gen_type
-> gcc_type
= gcc_type
;
149 gen_type
-> gcc_struct
= gcc_struct
;
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
;
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);
179 oberon_generator_get_full_name(char * name
, int max_len
, oberon_object_t
* x
)
187 int add_module_prefix
;
190 case OBERON_CLASS_FIELD
:
191 case OBERON_CLASS_PARAM
:
192 case OBERON_CLASS_VAR_PARAM
:
193 /* В локальных областях префиксы излишни */
194 add_module_prefix
= 0;
197 add_module_prefix
= 1;
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
);
214 snprintf(name
, max_len
, "%s", x
-> name
);
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
;
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
)
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
);
248 gcc_lvalue
= gcc_jit_context_new_global(
249 gcc_context
, NULL
, GCC_JIT_GLOBAL_EXPORTED
, gcc_type
, name
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
);
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
;
279 oberon_generator_init_proc(oberon_context_t
* ctx
, oberon_object_t
* proc
)
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
;
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
;
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
315 gen_proc
-> gcc_func
= gcc_func
;
318 // =======================================================================
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
);
326 oberon_generator_get_type_size(oberon_type_t
* type
)
328 printf("TODO: oberon_generator_get_type_size\n");
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
;
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
345 gcc_jit_block
* gcc_block
= gcc_jit_function_new_block(func
, NULL
);
347 oberon_generator_open_block(gen_context
, gcc_block
);
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
);
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
);
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
);
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
);
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
;
401 gcc_jit_block_end_with_void_return(gcc_block
, NULL
);
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
);
456 oberon_error(ctx
, "lvalue_from_item: invalid mode %i", item
-> mode
);
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
;
470 item
= (oberon_item_t
*) expr
;
471 left
= lvalue_from_item(ctx
, item
);
475 oberon_error(ctx
, "invalid lvalue expression");
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
);
503 right
= gcc_jit_context_one(gcc_context
, bool_type
);
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
);
529 args
[i
] = rvalue_from_expr(ctx
, expr
);
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
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
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
;
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
);
607 oberon_error(ctx
, "rvalue_from_item: invalid mode %i", item
-> mode
);
614 int type
; // 0 - unary, 1 - binary, 2 - comp
616 enum gcc_jit_unary_op unary_op
;
617 enum gcc_jit_binary_op binary_op
;
618 enum gcc_jit_comparison comp_op
;
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
}
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
;
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
);
678 oberon_error(ctx
, "rvalue_from_operator: wat");
684 static gcc_jit_rvalue
*
685 rvalue_from_expr(oberon_context_t
* ctx
, oberon_expr_t
* expr
)
687 gcc_jit_rvalue
* right
;
691 oberon_item_t
* item
= (oberon_item_t
*) expr
;
692 right
= rvalue_from_item(ctx
, item
);
696 oberon_oper_t
* operator = (oberon_oper_t
*) expr
;
697 right
= rvalue_from_operator(ctx
, operator);
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
);
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
);
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");
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);
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
);
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
);