X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=generator.c;h=07e7bc470ee1b1fb9a337810e695fce530bf16d3;hb=90ad7d921e60c24b11bc08cd173c0e1c80f9b06d;hp=21506b0626fe5db7cfbd117a444d2295de3448a2;hpb=7f3e5aeb0348e6c0af28869bad6acc13fe483177;p=dsw-obn.git diff --git a/generator.c b/generator.c index 21506b0..07e7bc4 100644 --- a/generator.c +++ b/generator.c @@ -11,9 +11,9 @@ #include /* - * oberon_var_t -> gvar == gcc_jit_lvalue; - * oberon_type_t -> gtype == gcc_jit_type; - * oberon_context_t -> gctx == gen_context_t; + * oberon_object_t -> gen_var == gcc_jit_lvalue; + * oberon_type_t -> gen_type == gcc_jit_type; + * oberon_context_t -> gen_context == gen_context_t; */ typedef struct @@ -94,9 +94,10 @@ oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) } void -oberon_generator_init_var(oberon_context_t * ctx, oberon_var_t * var) +oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) { printcontext(ctx, "oberon_generator_init_var"); + assert(var -> class == OBERON_CLASS_VAR); gen_context_t * gen_context = ctx -> gen_context; gcc_jit_context * gcc_context = gen_context -> gcc_context; @@ -109,10 +110,33 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_var_t * var) var -> gen_var = gen_var; } +void +oberon_generator_init_proc(oberon_context_t * ctx, oberon_object_t * proc) +{ + assert(proc -> class == OBERON_CLASS_PROC); + + gen_context_t * gen_context = ctx -> gen_context; + gcc_jit_context * gcc_context = gen_context -> gcc_context; + //gcc_jit_type * gen_type = proc -> type -> gen_type; + const char * name = proc -> name; + + gcc_jit_function * gen_proc; + + // TODO make real signature + gcc_jit_type * void_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID); + gen_proc = gcc_jit_context_new_function( + gcc_context, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, name, 0, NULL, 0 + ); + + proc -> gen_proc = gen_proc; +} + // ======================================================================= // GENERATOR // ======================================================================= +static gcc_jit_rvalue * rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr); + void oberon_generate_begin_module(oberon_context_t * ctx) { @@ -143,6 +167,40 @@ oberon_generate_end_module(oberon_context_t * ctx) gen_context -> gcc_block = NULL; } +void +oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc) +{ + gen_context_t * gen_context = ctx -> gen_context; + + gcc_jit_function * func = proc -> gen_proc; + gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL); + + // TODO make stack for block + gen_context -> gcc_block = gcc_block; +} + +void +oberon_generate_call_proc(oberon_context_t * ctx, oberon_expr_t * desig) +{ + gen_context_t * gen_context = ctx -> gen_context; + gcc_jit_block * block = gen_context -> gcc_block; + + gcc_jit_rvalue * return_value; + return_value = rvalue_from_expr(ctx, desig); + gcc_jit_block_add_eval(block, NULL, return_value); +} + +void +oberon_generate_end_proc(oberon_context_t * ctx) +{ + gen_context_t * gen_context = ctx -> gen_context; + gcc_jit_block * gcc_block = gen_context -> gcc_block; + + gcc_jit_block_end_with_void_return(gcc_block, NULL); + + gen_context -> gcc_block = NULL; +} + static gcc_jit_lvalue * lvalue_from_expr(oberon_context_t *ctx, oberon_expr_t * expr) { @@ -166,8 +224,6 @@ lvalue_from_expr(oberon_context_t *ctx, oberon_expr_t * expr) return left; } -static gcc_jit_rvalue * rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr); - static gcc_jit_rvalue * rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item) { @@ -177,6 +233,7 @@ rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item) gcc_jit_rvalue * right; if(item -> mode == MODE_VAR) { + assert(item -> var -> class == OBERON_CLASS_VAR); gcc_jit_lvalue * gen_var = item -> var -> gen_var; right = gcc_jit_lvalue_as_rvalue(gen_var); } @@ -197,6 +254,15 @@ rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item) right = gcc_jit_context_zero(gcc_context, bool_type); } } + else if(item -> mode == MODE_CALL) + { + assert(item -> var -> class == OBERON_CLASS_PROC); + /* TODO args */ + gcc_jit_function * func = item -> var -> gen_proc; + right = gcc_jit_context_new_call( + gcc_context, NULL, func, 0, NULL + ); + } else { oberon_error(ctx, "oberon_generate_push: invalid mode %i", item -> mode);