9 #include "../../../include/oberon.h"
10 #include "../../oberon-internals.h"
11 #include "generator-jvm.h"
14 new_string(const char * format
, ...)
17 va_start(ptr
, format
);
20 vsnprintf(buf
, 1024, format
, ptr
);
28 result
= GC_MALLOC(size
+ 1);
29 memset(result
, 0, size
);
30 strncpy(result
, buf
, size
);
36 oberon_generator_init_context(oberon_context_t
* ctx
)
38 gen_context_t
* gen_context
= GC_MALLOC(sizeof *gen_context
);
39 memset(gen_context
, 0, sizeof *gen_context
);
41 ctx
-> gen_context
= gen_context
;
45 oberon_generator_destroy_context(oberon_context_t
* ctx
)
47 ctx
-> gen_context
= NULL
;
50 static char * get_class_full_name(oberon_context_t
* ctx
, oberon_type_t
* type
);
53 get_descriptor(oberon_context_t
* ctx
, oberon_type_t
* type
)
59 case OBERON_TYPE_VOID
:
60 return new_string("V");
62 case OBERON_TYPE_INTEGER
:
66 return new_string("B");
69 return new_string("S");
72 return new_string("I");
75 return new_string("J");
78 oberon_error(ctx
, "get_descriptor: unsupported int size %i", type
-> size
);
82 case OBERON_TYPE_REAL
:
86 return new_string("F");
89 return new_string("D");
92 oberon_error(ctx
, "get_descriptor: unsupported float size %i", type
-> size
);
96 case OBERON_TYPE_BOOLEAN
:
97 return new_string("Z");
99 case OBERON_TYPE_PROCEDURE
:
100 case OBERON_TYPE_RECORD
:
101 desc
= get_class_full_name(ctx
, type
);
102 return new_string("L%s;", desc
);
104 case OBERON_TYPE_ARRAY
:
105 desc
= get_descriptor(ctx
, type
-> base
);
106 return new_string("[%s", desc
);
109 oberon_error(ctx
, "print_descriptor: unsupported type class %i", type
-> class);
117 get_prefix(oberon_context_t
* ctx
, oberon_type_t
* type
)
119 int size
= type
-> size
;
120 switch(type
-> class)
122 case OBERON_TYPE_BOOLEAN
:
123 case OBERON_TYPE_INTEGER
:
124 return (size
<= 4) ? ('i') : ('l');
126 case OBERON_TYPE_PROCEDURE
:
127 case OBERON_TYPE_ARRAY
:
128 case OBERON_TYPE_RECORD
:
129 case OBERON_TYPE_POINTER
:
132 case OBERON_TYPE_REAL
:
133 return (size
<= 4) ? ('f') : ('d');
137 oberon_error(ctx
, "get_prefix: wat");
142 get_field_full_name(oberon_context_t
* ctx
, oberon_object_t
* x
)
144 return new_string("%s/%s", x
-> module
-> name
, x
-> name
);
148 get_class_full_name(oberon_context_t
* ctx
, oberon_type_t
* type
)
153 switch(type
-> class)
155 case OBERON_TYPE_PROCEDURE
:
156 name
= new_string("SYSTEM$PROCEDURE");
159 desc
= get_descriptor(ctx
, type
-> base
);
160 name
= new_string("%s$%s", name
, desc
);
162 int num
= type
-> num_decl
;
163 oberon_object_t
* arg
= type
-> decl
;
164 for(int i
= 0; i
< num
; i
++)
166 desc
= get_descriptor(ctx
, arg
-> type
);
167 name
= new_string("%s%s", name
, desc
);
172 case OBERON_TYPE_RECORD
:
173 assert(type
-> module
);
174 assert(type
-> module
-> gen_mod
);
175 rec_id
= type
-> gen_type
-> rec_id
;
176 name
= new_string("%s$RECORD%i", type
-> module
-> name
, rec_id
);
179 oberon_error(ctx
, "get_record_full_name: unk type class %i", type
-> class);
187 get_procedure_signature(oberon_context_t
* ctx
, oberon_type_t
* proc
)
192 signature
= new_string("(");
194 int num
= proc
-> num_decl
;
195 oberon_object_t
* arg
= proc
-> decl
;
196 for(int i
= 0; i
< num
; i
++)
198 desc
= get_descriptor(ctx
, arg
-> type
);
199 signature
= new_string("%s%s", signature
, desc
);
203 desc
= get_descriptor(ctx
, proc
-> base
);
204 signature
= new_string("%s)%s", signature
, desc
);
210 oberon_generate_procedure_class(oberon_context_t
* ctx
, oberon_type_t
* proc
)
217 cname
= get_class_full_name(ctx
, proc
);
218 fname
= new_string("%s.j", cname
);
220 fp
= fopen(fname
, "w");
222 fprintf(fp
, ".source SYSTEM\n");
223 fprintf(fp
, ".class public abstract %s\n", cname
);
224 fprintf(fp
, ".super java/lang/Object\n\n");
226 signature
= get_procedure_signature(ctx
, proc
);
228 fprintf(fp
, ".method public <init>()V\n");
229 fprintf(fp
, " aload_0\n");
230 fprintf(fp
, " invokespecial java/lang/Object/<init>()V\n");
231 fprintf(fp
, " return\n");
232 fprintf(fp
, ".end method\n\n");
234 fprintf(fp
, ".method public abstract invoke%s\n", signature
);
235 fprintf(fp
, ".end method\n\n");
241 oberon_generate_record_class(oberon_context_t
* ctx
, oberon_type_t
* rec
)
247 /* Устанавливаем новоый id */
248 rec
-> gen_type
-> rec_id
= rec
-> module
-> gen_mod
-> rec_id
;
249 rec
-> module
-> gen_mod
-> rec_id
+= 1;
251 cname
= get_class_full_name(ctx
, rec
);
252 fname
= new_string("%s.j", cname
);
254 fp
= fopen(fname
, "w");
256 fprintf(fp
, ".source %s\n", rec
-> module
-> name
);
257 fprintf(fp
, ".class public %s\n", cname
);
258 fprintf(fp
, ".super java/lang/Object\n\n");
260 rec
-> gen_type
-> fp
= fp
;
264 oberon_generator_init_type(oberon_context_t
* ctx
, oberon_type_t
* type
)
266 gen_type_t
* t
= GC_MALLOC(sizeof *t
);
267 memset(t
, 0, sizeof *t
);
268 type
-> gen_type
= t
;
270 switch(type
-> class)
272 case OBERON_TYPE_VOID
:
273 case OBERON_TYPE_INTEGER
:
274 case OBERON_TYPE_BOOLEAN
:
275 case OBERON_TYPE_ARRAY
:
276 case OBERON_TYPE_REAL
:
278 case OBERON_TYPE_RECORD
:
279 oberon_generate_record_class(ctx
, type
);
281 case OBERON_TYPE_PROCEDURE
:
282 oberon_generate_procedure_class(ctx
, type
);
284 case OBERON_TYPE_POINTER
:
285 assert(type
-> base
-> class == OBERON_TYPE_VOID
);
288 oberon_error(ctx
, "oberon_generator_init_type: unk calss %i", type
-> class);
294 oberon_generate_object(oberon_context_t
* ctx
, FILE * fp
, oberon_object_t
* x
)
300 desc
= get_descriptor(ctx
, x
-> type
);
303 case OBERON_CLASS_VAR
:
304 fprintf(fp
, ".field public static %s %s\n\n", name
, desc
);
306 case OBERON_CLASS_FIELD
:
307 fprintf(fp
, ".field public %s %s\n\n", name
, desc
);
310 oberon_error(ctx
, "oberon_generate_object: unk class %i", x
-> class);
316 oberon_generator_init_record(oberon_context_t
* ctx
, oberon_type_t
* rec
)
320 fp
= rec
-> gen_type
-> fp
;
322 int num
= rec
-> num_decl
;
323 oberon_object_t
* field
= rec
-> decl
;
324 for(int i
= 0; i
< num
; i
++)
326 oberon_generate_object(ctx
, fp
, field
);
327 field
= field
-> next
;
330 fprintf(fp
, ".method public <init>()V\n");
331 fprintf(fp
, " aload_0\n");
332 fprintf(fp
, " invokespecial java/lang/Object/<init>()V\n");
333 fprintf(fp
, " return\n");
334 fprintf(fp
, ".end method\n");
340 oberon_generator_init_var(oberon_context_t
* ctx
, oberon_object_t
* var
)
342 gen_var_t
* v
= GC_MALLOC(sizeof *v
);
343 memset(v
, 0, sizeof *v
);
346 gen_module_t
* m
= ctx
-> mod
-> gen_mod
;
350 case OBERON_CLASS_VAR_PARAM
:
351 oberon_error(ctx
, "generator: VAR-parameters not implemented");
353 case OBERON_CLASS_PARAM
:
354 case OBERON_CLASS_FIELD
:
356 case OBERON_CLASS_VAR
:
357 oberon_generate_object(ctx
, m
-> fp
, var
);
360 oberon_error(ctx
, "oberon_generator_init_var: unk var class %i", var
-> class);
366 oberon_generator_init_proc(oberon_context_t
* ctx
, oberon_object_t
* proc
)
368 gen_proc_t
* p
= GC_MALLOC(sizeof *p
);
369 memset(p
, 0, sizeof *p
);
370 proc
-> gen_proc
= p
;
372 struct gen_register_file
* rf
= GC_MALLOC(sizeof *rf
);
373 memset(rf
, 0, sizeof *rf
);
378 oberon_error(ctx
, "generator: local procedures not implemented");
383 oberon_generator_init_module(oberon_context_t
* ctx
, oberon_module_t
* mod
)
385 gen_module_t
* m
= GC_MALLOC(sizeof *m
);
386 memset(m
, 0, sizeof *m
);
389 int fnamesz
= strlen(mod
-> name
) + 3;
390 char fname
[fnamesz
+ 1];
391 snprintf(fname
, fnamesz
, "%s.j", mod
-> name
);
394 fp
= fopen(fname
, "w");
397 fprintf(fp
, ".source %s\n", mod
-> name
);
398 fprintf(fp
, ".class %s\n", mod
-> name
);
399 fprintf(fp
, ".super java/lang/Object\n\n");
404 // =======================================================================
406 // =======================================================================
409 push_expr(oberon_context_t
* ctx
, FILE * fp
, oberon_expr_t
* expr
);
412 oberon_generate_begin_module(oberon_context_t
* ctx
)
414 gen_module_t
* m
= ctx
-> mod
-> gen_mod
;
415 fprintf(m
-> fp
, ".method public <init>()V\n");
416 fprintf(m
-> fp
, " aload_0\n");
417 fprintf(m
-> fp
, " invokespecial java/lang/Object/<init>()V\n");
421 oberon_generate_end_module(oberon_context_t
* ctx
)
423 gen_module_t
* m
= ctx
-> mod
-> gen_mod
;
425 fprintf(m
-> fp
, " .limit stack 32\n");
426 fprintf(m
-> fp
, " .limit locals 32\n");
427 fprintf(m
-> fp
, " return\n");
428 fprintf(m
-> fp
, ".end method\n");
432 jvm_cell_size_for_type(oberon_type_t
* type
)
434 if(type
-> class == OBERON_TYPE_INTEGER
435 || type
-> class == OBERON_TYPE_REAL
)
447 jvm_is_wide_type(oberon_type_t
* type
)
450 cell
= jvm_cell_size_for_type(type
);
456 jvm_is_free_register(struct gen_register_file
* rf
, int i
, bool wide
)
460 assert(i
+ 1 < MAX_REGISTERS
);
461 return !(rf
-> reg
[i
].used
|| rf
-> reg
[i
+ 1].used
);
465 assert(i
< MAX_REGISTERS
);
466 return !(rf
-> reg
[i
].used
);
471 jvm_alloc_register(struct gen_register_file
* rf
, oberon_type_t
* type
)
474 wide
= jvm_is_wide_type(type
);
477 while(i
< MAX_REGISTERS
&& !jvm_is_free_register(rf
, i
, wide
))
484 assert(i
+ 1 <= MAX_REGISTERS
);
486 rf
-> reg
[i
].used
= true;
487 rf
-> reg
[i
+ 1].used
= true;
488 rf
-> reg
[i
].used
= true;
489 rf
-> reg
[i
+ 1].wide
= false;
493 assert(i
<= MAX_REGISTERS
);
495 rf
-> reg
[i
].used
= true;
496 rf
-> reg
[i
].wide
= false;
499 if(rf
-> num_used
> rf
-> max_used
)
501 rf
-> max_used
= rf
-> num_used
;
508 jvm_init_local_object(oberon_context_t
* ctx
, FILE * fp
, oberon_object_t
* x
)
515 c
= ctx
-> gen_context
;
517 desc
= get_descriptor(ctx
, x
-> type
);
522 case OBERON_CLASS_VAR
:
523 case OBERON_CLASS_PARAM
:
526 reg
= jvm_alloc_register(c
-> rf
, x
-> type
);
529 fprintf(fp
, ".var %i is %s %s from start to end\n", reg
, x
-> name
, desc
);
532 oberon_error(ctx
, "jvm_init_local_object: wat");
538 oberon_generate_begin_proc(oberon_context_t
* ctx
, oberon_object_t
* proc
)
545 c
= ctx
-> gen_context
;
546 m
= ctx
-> mod
-> gen_mod
;
547 p
= proc
-> gen_proc
;
549 signature
= get_procedure_signature(ctx
, proc
-> type
);
550 fprintf(m
-> fp
, ".method public static %s%s\n", proc
-> name
, signature
);
552 /* Сохраняем регистровый файл в стеке */
553 p
-> rf
-> up
= c
-> rf
;
556 oberon_object_t
* var
= proc
-> type
-> decl
;
559 jvm_init_local_object(ctx
, m
-> fp
, var
);
563 fprintf(m
-> fp
, "start:\n");
567 oberon_generate_end_proc(oberon_context_t
* ctx
)
572 c
= ctx
-> gen_context
;
573 m
= ctx
-> mod
-> gen_mod
;
575 fprintf(m
-> fp
, "end:\n");
576 fprintf(m
-> fp
, " .limit stack 32\n");
577 fprintf(m
-> fp
, " .limit locals %i\n", c
-> rf
-> max_used
);
578 fprintf(m
-> fp
, ".end method\n\n");
580 /* Возвращаем исходный регистровый файл */
581 c
-> rf
= c
-> rf
-> up
;
585 oberon_generate_call_proc(oberon_context_t
* ctx
, oberon_expr_t
* desig
)
587 oberon_object_t
* proc
;
592 assert(desig
-> is_item
);
593 assert(desig
-> item
.mode
== MODE_CALL
);
595 m
= ctx
-> mod
-> gen_mod
;
596 proc
= desig
-> item
.var
;
597 fullname
= get_field_full_name(ctx
, proc
);
598 signature
= get_procedure_signature(ctx
, proc
-> type
);
600 int num
= desig
-> item
.num_args
;
601 oberon_expr_t
* arg
= desig
-> item
.args
;
602 for(int i
= 0; i
< num
; i
++)
604 push_expr(ctx
, m
-> fp
, arg
);
608 fprintf(m
-> fp
, "invokestatic %s%s\n", fullname
, signature
);
612 oberon_generate_return(oberon_context_t
* ctx
, oberon_expr_t
* expr
)
617 m
= ctx
-> mod
-> gen_mod
;
621 push_expr(ctx
, m
-> fp
, expr
);
622 prefix
= get_prefix(ctx
, expr
-> result
);
623 fprintf(m
-> fp
, " %creturn\n", prefix
);
627 fprintf(m
-> fp
, " return\n");
632 push_int(FILE * fp
, long i
)
636 fprintf(fp
, "iconst_m1\n");
638 else if(i
>= 0 && i
<= 5)
640 fprintf(fp
, "iconst_%li\n", i
);
642 else if(i
>= -128 && i
<= 127)
644 fprintf(fp
, "bipush %li\n", i
);
646 else if(i
>= -32768 && i
<= 32767)
648 fprintf(fp
, "sipush %li\n", i
);
650 else if(i
>= -2147483648 && i
<= 2147483647)
652 fprintf(fp
, "ldc %li\n", i
);
656 fprintf(fp
, "ldc2 %li\n", i
);
661 push_float(FILE * fp
, double f
, int size
)
667 fprintf(fp
, "fconst_0\n");
671 fprintf(fp
, "fconst_1\n");
675 fprintf(fp
, "fconst_2\n");
679 fprintf(fp
, "ldc %lf\n", f
);
686 fprintf(fp
, "dconst_0\n");
690 fprintf(fp
, "dconst_1\n");
694 fprintf(fp
, "ldc2 %lf\n", f
);
700 push_var(oberon_context_t
* ctx
, FILE * fp
, oberon_object_t
* var
)
704 int reg
= var
-> gen_var
-> reg
;
705 char prefix
= get_prefix(ctx
, var
-> type
);
706 fprintf(fp
, "%cload %i\n", prefix
, reg
);
710 char * fullname
= get_field_full_name(ctx
, var
);
711 char * desc
= get_descriptor(ctx
, var
-> type
);
712 fprintf(fp
, "getstatic %s %s\n", fullname
, desc
);
717 push_item(oberon_context_t
* ctx
, FILE * fp
, oberon_item_t
* item
)
722 push_var(ctx
, fp
, item
-> var
);
725 push_int(fp
, item
-> integer
);
728 push_int(fp
, item
-> boolean
);
731 oberon_generate_call_proc(ctx
, (oberon_expr_t
*) item
);
734 oberon_error(ctx
, "push_item: TODO index");
737 oberon_error(ctx
, "push_item: TODO field");
740 oberon_error(ctx
, "push_item: TODO deref");
743 fprintf(fp
, "aconst_null\n");
746 oberon_error(ctx
, "push_item: TODO new");
749 push_float(fp
, item
-> real
, item
-> result
-> size
);
752 oberon_error(ctx
, "push_item: unk mode %i", item
-> mode
);
758 jvm_new_label_id(oberon_context_t
* ctx
)
760 gen_context_t
* c
= ctx
-> gen_context
;
761 int label_id
= c
-> label_id
;
767 jvm_get_label_name(int label_id
)
769 return new_string("L%i", label_id
);
773 jvm_generate_label(FILE * fp
, int label_id
)
775 fprintf(fp
, "L%i:\n", label_id
);
779 jvm_generate_logical_not(oberon_context_t
* ctx
, FILE * fp
)
781 int label_true
= jvm_new_label_id(ctx
);
782 int label_false
= jvm_new_label_id(ctx
);
783 char * label_name_true
= jvm_get_label_name(label_true
);
784 char * label_name_false
= jvm_get_label_name(label_false
);
786 fprintf(fp
, "ifne %s\n", label_name_false
);
787 fprintf(fp
, "iconst_1\n");
788 fprintf(fp
, "goto %s\n", label_name_true
);
789 jvm_generate_label(fp
, label_false
);
790 fprintf(fp
, "iconst_0\n");
791 jvm_generate_label(fp
, label_true
);
795 jvm_get_type_of_prefix(char prefix
)
817 jvm_generate_abs(FILE * fp
, char prefix
)
819 char t
= jvm_get_type_of_prefix(prefix
);
820 fprintf(fp
, "invokestatic java/lang/Math/abs(%c)%c\n", t
, t
);
824 jvm_generate_compare_op(oberon_context_t
* ctx
, FILE *fp
, char prefix
, int op
)
826 int label_true
= jvm_new_label_id(ctx
);
827 int label_false
= jvm_new_label_id(ctx
);
828 char * label_name_true
= jvm_get_label_name(label_true
);
829 char * label_name_false
= jvm_get_label_name(label_false
);
831 assert(prefix
== 'i' || prefix
== 'a');
836 fprintf(fp
, "if_%ccmpeq %s\n", prefix
, label_name_true
);
839 fprintf(fp
, "if_%ccmpne %s\n", prefix
, label_name_true
);
842 fprintf(fp
, "if_icmplt %s\n", label_name_true
);
845 fprintf(fp
, "if_icmple %s\n", label_name_true
);
848 fprintf(fp
, "if_icmpgt %s\n", label_name_true
);
851 fprintf(fp
, "if_icmpge %s\n", label_name_true
);
854 oberon_error(ctx
, "jvm_generate_compare_op: wat");
858 fprintf(fp
, "iconst_0\n");
859 fprintf(fp
, "goto %s\n", label_name_false
);
860 jvm_generate_label(fp
, label_true
);
861 fprintf(fp
, "iconst_1\n");
862 jvm_generate_label(fp
, label_false
);
866 jvm_generate_operator(oberon_context_t
* ctx
, FILE *fp
, char prefix
, int op
)
871 fprintf(fp
, "%cneg\n", prefix
);
875 fprintf(fp
, "%cxor\n", prefix
);
878 jvm_generate_logical_not(ctx
, fp
);
881 jvm_generate_abs(fp
, prefix
);
885 fprintf(fp
, "%cadd\n", prefix
);
888 fprintf(fp
, "%csub\n", prefix
);
891 fprintf(fp
, "%cmul\n", prefix
);
894 fprintf(fp
, "%cdiv\n", prefix
);
897 fprintf(fp
, "%crem\n", prefix
);
900 fprintf(fp
, "%cand\n", prefix
);
903 fprintf(fp
, "%cxor\n", prefix
);
906 fprintf(fp
, "%cor\n", prefix
);
915 jvm_generate_compare_op(ctx
, fp
, prefix
, op
);
918 oberon_error(ctx
, "jvm_generate_operator: unk op %i", op
);
924 jvm_generate_logical_or(oberon_context_t
* ctx
, FILE * fp
, oberon_expr_t
* p
, oberon_expr_t
* q
)
926 int label_calc_q
= jvm_new_label_id(ctx
);
927 int label_done
= jvm_new_label_id(ctx
);
928 char * label_name_calc_q
= jvm_get_label_name(label_calc_q
);
929 char * label_name_done
= jvm_get_label_name(label_done
);
931 /* p OR q -- если p, то TRUE, иначе q */
933 push_expr(ctx
, fp
, p
);
934 fprintf(fp
, "ifne %s\n", label_name_calc_q
);
935 fprintf(fp
, "iconst_1\n");
936 fprintf(fp
, "goto %s\n", label_name_done
);
937 jvm_generate_label(fp
, label_calc_q
);
938 push_expr(ctx
, fp
, q
);
939 jvm_generate_label(fp
, label_done
);
943 jvm_generate_logical_and(oberon_context_t
* ctx
, FILE * fp
, oberon_expr_t
* p
, oberon_expr_t
* q
)
945 int label_false
= jvm_new_label_id(ctx
);
946 int label_done
= jvm_new_label_id(ctx
);
947 char * label_name_false
= jvm_get_label_name(label_false
);
948 char * label_name_done
= jvm_get_label_name(label_done
);
950 /* p AND q -- если p, то q, иначе FALSE */
952 push_expr(ctx
, fp
, p
);
953 fprintf(fp
, "ifne %s\n", label_name_false
);
954 push_expr(ctx
, fp
, q
);
955 fprintf(fp
, "goto %s\n", label_name_done
);
956 jvm_generate_label(fp
, label_false
);
957 fprintf(fp
, "iconst_0\n");
958 jvm_generate_label(fp
, label_done
);
962 push_operator(oberon_context_t
* ctx
, FILE * fp
, oberon_oper_t
* oper
)
964 char prefix
= get_prefix(ctx
, oper
-> result
);
972 push_expr(ctx
, fp
, oper
-> left
);
973 jvm_generate_operator(ctx
, fp
, prefix
, op
);
991 push_expr(ctx
, fp
, oper
-> left
);
992 push_expr(ctx
, fp
, oper
-> right
);
993 jvm_generate_operator(ctx
, fp
, prefix
, op
);
997 jvm_generate_logical_or(ctx
, fp
, oper
-> left
, oper
-> right
);
1000 jvm_generate_logical_and(ctx
, fp
, oper
-> left
, oper
-> right
);
1003 oberon_error(ctx
, "push_oper: unk op %i", op
);
1009 push_expr(oberon_context_t
* ctx
, FILE * fp
, oberon_expr_t
* expr
)
1013 push_item(ctx
, fp
, (oberon_item_t
*) expr
);
1017 push_operator(ctx
, fp
, (oberon_oper_t
*) expr
);
1022 store_expr(oberon_context_t
* ctx
, FILE * fp
, oberon_expr_t
* expr
)
1024 assert(expr
-> is_item
);
1025 oberon_item_t
* item
= (oberon_item_t
*) expr
;
1028 switch(item
-> mode
)
1031 if(item
-> var
-> local
)
1033 int reg
= item
-> var
-> gen_var
-> reg
;
1034 prefix
= get_prefix(ctx
, item
-> result
);
1035 fprintf(fp
, "%cstore %i\n", prefix
, reg
);
1039 char * fullname
= get_field_full_name(ctx
, item
-> var
);
1040 char * desc
= get_descriptor(ctx
, item
-> result
);
1041 fprintf(fp
, "putstatic %s %s\n", fullname
, desc
);
1045 oberon_error(ctx
, "store_expr: unk mode %i", item
-> mode
);
1051 oberon_generate_assign(oberon_context_t
* ctx
, oberon_expr_t
* src
, oberon_expr_t
* dst
)
1054 m
= ctx
-> mod
-> gen_mod
;
1056 push_expr(ctx
, m
-> fp
, src
);
1057 store_expr(ctx
, m
-> fp
, dst
);
1061 oberon_generate_code(oberon_context_t
* ctx
)
1063 printf("generate code\n");
1067 oberon_generator_dump(oberon_context_t
* ctx
, char * path
)
1069 printf("jit: dump code\n");
1073 oberon_generator_get_procedure(oberon_context_t
* ctx
, const char * name
)
1075 printf("jit: get pointer to procedure %s\n", name
);
1080 oberon_generator_get_var(oberon_context_t
* ctx
, const char * name
)
1082 printf("jit: get pointer to var %s\n", name
);