X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=generator.c;h=709e5a65cbfb513cd502e2bf7d70383b89468449;hb=1bf625553dc35ac4a5c1afceb6950fd44776a424;hp=4c3a984a6b226d5377ffb5fdcfa0ca5979ffd212;hpb=518cba11c21426f922afef90048f5f9c8130fed2;p=dsw-obn.git diff --git a/generator.c b/generator.c index 4c3a984..709e5a6 100644 --- a/generator.c +++ b/generator.c @@ -8,8 +8,6 @@ #include "oberon.h" #include "generator.h" -#include - static void printcontext(oberon_context_t * ctx, char * s) { /* @@ -29,6 +27,24 @@ static void printcontext(oberon_context_t * ctx, char * s) // ALLOC // ======================================================================= +static void +oberon_generator_open_block(gen_context_t * gen_context, gcc_jit_block * gcc_block) +{ + gen_block_t * block = malloc(sizeof *block); + memset(block, 0, sizeof *block); + + block -> gcc_block = gcc_block; + block -> up = gen_context -> block; + + gen_context -> block = block; +} + +static void +oberon_generator_close_block(gen_context_t * gen_context) +{ + gen_context -> block = gen_context -> block -> up; +} + void oberon_generator_init_context(oberon_context_t * ctx) { @@ -87,7 +103,11 @@ oberon_generator_init_type(oberon_context_t * ctx, oberon_type_t * type) } else if(type -> class == OBERON_TYPE_RECORD) { - gcc_struct = gcc_jit_context_new_opaque_struct(gcc_context, NULL, ""); + char name[32]; + snprintf(name, 32, "RECORD%u", gen_context -> record_count); + gen_context -> record_count += 1; + + gcc_struct = gcc_jit_context_new_opaque_struct(gcc_context, NULL, name); gcc_type = gcc_jit_struct_as_type(gcc_struct); } else if(type -> class == OBERON_TYPE_POINTER) @@ -170,9 +190,19 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) gcc_jit_field * gcc_field = NULL; if(var -> class == OBERON_CLASS_VAR) { - gcc_lvalue = gcc_jit_context_new_global( - gcc_context, NULL, GCC_JIT_GLOBAL_INTERNAL, gcc_type, name - ); + if(var -> local) + { + gen_proc_t * gen_func = var -> parent -> gen_proc; + gcc_jit_function * func = gen_func -> gcc_func; + + gcc_lvalue = gcc_jit_function_new_local(func, NULL, gcc_type, name); + } + else + { + gcc_lvalue = gcc_jit_context_new_global( + gcc_context, NULL, GCC_JIT_GLOBAL_INTERNAL, gcc_type, name + ); + } } else if(var -> class == OBERON_CLASS_PARAM) { @@ -202,7 +232,10 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_object_t * var) void oberon_generator_init_proc(oberon_context_t * ctx, oberon_object_t * proc) { - assert(proc -> class == OBERON_CLASS_PROC); + if(proc -> local) + { + oberon_error(ctx, "generator: local procedures not supported"); + } gen_context_t * gen_context = ctx -> gen_context; gcc_jit_context * gcc_context = gen_context -> gcc_context; @@ -255,7 +288,7 @@ oberon_generate_begin_module(oberon_context_t * ctx) ); gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL); - gen_context -> gcc_block = gcc_block; + oberon_generator_open_block(gen_context, gcc_block); } void @@ -264,11 +297,11 @@ oberon_generate_end_module(oberon_context_t * ctx) printcontext(ctx, "oberon_generate_end_module"); gen_context_t * gen_context = ctx -> gen_context; - gcc_jit_block * gcc_block = gen_context -> gcc_block; + gcc_jit_block * gcc_block = gen_context -> block -> gcc_block; gcc_jit_block_end_with_void_return(gcc_block, NULL); - gen_context -> gcc_block = NULL; + oberon_generator_close_block(gen_context); } void @@ -280,15 +313,15 @@ oberon_generate_begin_proc(oberon_context_t * ctx, oberon_object_t * proc) gcc_jit_function * func = gen_proc -> gcc_func; gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL); - // TODO make stack for block - gen_context -> gcc_block = gcc_block; + oberon_generator_open_block(gen_context, 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; + gen_block_t * gen_block = gen_context -> block; + gcc_jit_block * block = gen_block -> gcc_block; gcc_jit_rvalue * return_value; return_value = rvalue_from_expr(ctx, desig); @@ -299,14 +332,15 @@ void oberon_generate_end_proc(oberon_context_t * ctx) { gen_context_t * gen_context = ctx -> gen_context; - gen_context -> gcc_block = NULL; + oberon_generator_close_block(gen_context); } void oberon_generate_return(oberon_context_t * ctx, oberon_expr_t * expr) { gen_context_t * gen_context = ctx -> gen_context; - gcc_jit_block * gcc_block = gen_context -> gcc_block; + gen_block_t * gen_block = gen_context -> block; + gcc_jit_block * gcc_block = gen_block -> gcc_block; if(expr == NULL) { @@ -485,14 +519,19 @@ struct { enum gcc_jit_comparison comp_op; }; } op_table[] = { - { 0, .unary_op = GCC_JIT_UNARY_OP_LOGICAL_NEGATE }, { 0, .unary_op = GCC_JIT_UNARY_OP_MINUS }, + { 0, .unary_op = GCC_JIT_UNARY_OP_BITWISE_NEGATE }, + { 0, .unary_op = GCC_JIT_UNARY_OP_LOGICAL_NEGATE }, + { 0, .unary_op = GCC_JIT_UNARY_OP_ABS }, { 1, .binary_op = GCC_JIT_BINARY_OP_PLUS }, { 1, .binary_op = GCC_JIT_BINARY_OP_MINUS }, { 1, .binary_op = GCC_JIT_BINARY_OP_MULT }, { 1, .binary_op = GCC_JIT_BINARY_OP_DIVIDE }, { 1, .binary_op = GCC_JIT_BINARY_OP_MODULO }, + { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_AND }, + { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_XOR }, + { 1, .binary_op = GCC_JIT_BINARY_OP_BITWISE_OR }, { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_AND }, { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_OR }, @@ -584,7 +623,8 @@ oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_ } gen_context_t * gen_context = ctx -> gen_context; - gcc_jit_block * gcc_block = gen_context -> gcc_block; + gen_block_t * gen_block = gen_context -> block; + gcc_jit_block * gcc_block = gen_block -> gcc_block; gcc_jit_block_add_assignment(gcc_block, NULL, left, right); }