From 390a7e053165954865bc013a7c7057982c206453 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 24 Jul 2017 22:05:22 +0300 Subject: [PATCH] =?utf8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=D1=8B=20=D0=B2=D1=8B=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- gdb_run.sh | 8 + generator.c | 173 ++++++++++++++++----- generator.h | 2 +- oberon.c | 427 +++++++++++++++++++++++++++++++++++++++++++++------- oberon.h | 53 ++++++- test.c | 9 +- 6 files changed, 570 insertions(+), 102 deletions(-) create mode 100755 gdb_run.sh diff --git a/gdb_run.sh b/gdb_run.sh new file mode 100755 index 0000000..b6e0bbd --- /dev/null +++ b/gdb_run.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +export PATH="/usr/lib/gcc/x86_64-pc-linux-gnu/7.1.1:${PATH}" +export LIBRARY_PATH="/usr/lib/gcc/x86_64-pc-linux-gnu/7.1.1:${LIBRARY_PATH}" + +exec gdb ./a.out diff --git a/generator.c b/generator.c index c633e54..21506b0 100644 --- a/generator.c +++ b/generator.c @@ -113,11 +113,64 @@ oberon_generator_init_var(oberon_context_t * ctx, oberon_var_t * var) // GENERATOR // ======================================================================= -static gcc_jit_rvalue * -oberon_generate_rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item) +void +oberon_generate_begin_module(oberon_context_t * ctx) +{ + printcontext(ctx, "oberon_generate_begin_module"); + + gen_context_t * gen_context = ctx -> gen_context; + gcc_jit_context * gcc_context = gen_context -> gcc_context; + + gcc_jit_type * void_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID); + gcc_jit_function * func = gcc_jit_context_new_function( + gcc_context, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "BEGIN", 0, NULL, 0 + ); + gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL); + + gen_context -> gcc_block = gcc_block; +} + +void +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_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) { - printcontext(ctx, "oberon_generate_rvalue_from_item"); + gcc_jit_lvalue * left; + oberon_item_t * item; + + if(expr -> is_item) + { + item = (oberon_item_t *) expr; + if(item -> mode != MODE_VAR) + { + oberon_error(ctx, "invalid lvalue expression"); + } + left = item -> var -> gen_var; + } + else + { + oberon_error(ctx, "invalid lvalue expression"); + } + + 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) +{ gen_context_t * gen_context = ctx -> gen_context; gcc_jit_context * gcc_context = gen_context -> gcc_context; @@ -126,13 +179,11 @@ oberon_generate_rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item) { gcc_jit_lvalue * gen_var = item -> var -> gen_var; right = gcc_jit_lvalue_as_rvalue(gen_var); - printf("PUSH (var) %s\n", item -> var -> name); } else if(item -> mode == MODE_INTEGER) { gcc_jit_type * int_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_INT); right = gcc_jit_context_new_rvalue_from_int(gcc_context, int_type, item -> integer); - printf("PUSH (int) %i\n", item -> integer); } else if(item -> mode == MODE_BOOLEAN) { @@ -145,7 +196,6 @@ oberon_generate_rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item) { right = gcc_jit_context_zero(gcc_context, bool_type); } - printf("PUSH (bool) %i\n", item -> boolean); } else { @@ -155,59 +205,100 @@ oberon_generate_rvalue_from_item(oberon_context_t * ctx, oberon_item_t * item) return right; } -void -oberon_generate_begin_module(oberon_context_t * ctx) +struct { + int type; // 0 - unary, 1 - binary, 2 - comp + union { + enum gcc_jit_unary_op unary_op; + enum gcc_jit_binary_op binary_op; + 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 }, + + { 1, .binary_op = GCC_JIT_BINARY_OP_PLUS }, + { 1, .binary_op = GCC_JIT_BINARY_OP_MINUS }, + { 1, .binary_op = GCC_JIT_BINARY_OP_DIVIDE }, + { 1, .binary_op = GCC_JIT_BINARY_OP_MODULO }, + { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_AND }, + { 1, .binary_op = GCC_JIT_BINARY_OP_LOGICAL_OR }, + + { 2, .comp_op = GCC_JIT_COMPARISON_EQ }, + { 2, .comp_op = GCC_JIT_COMPARISON_NE }, + { 2, .comp_op = GCC_JIT_COMPARISON_LT }, + { 2, .comp_op = GCC_JIT_COMPARISON_LE }, + { 2, .comp_op = GCC_JIT_COMPARISON_GT }, + { 2, .comp_op = GCC_JIT_COMPARISON_GE } +}; + +static gcc_jit_rvalue * +rvalue_from_operator(oberon_context_t * ctx, oberon_oper_t * operator) { - printcontext(ctx, "oberon_generate_begin_module"); + gcc_jit_rvalue * right; gen_context_t * gen_context = ctx -> gen_context; gcc_jit_context * gcc_context = gen_context -> gcc_context; + gcc_jit_type * result_type = operator -> result -> gen_type; - gcc_jit_type * void_type = gcc_jit_context_get_type(gcc_context, GCC_JIT_TYPE_VOID); - gcc_jit_function * func = gcc_jit_context_new_function( - gcc_context, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "BEGIN", 0, NULL, 0 - ); - gcc_jit_block * gcc_block = gcc_jit_function_new_block(func, NULL); + int expr_type = op_table[operator -> op].type; + if(expr_type == 0) + { + enum gcc_jit_unary_op op = op_table[operator -> op].unary_op; + gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left); + right = gcc_jit_context_new_unary_op(gcc_context, NULL, op, result_type, l); + } + else if(expr_type == 1) + { + enum gcc_jit_unary_op op = op_table[operator -> op].binary_op; + gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left); + gcc_jit_rvalue * r = rvalue_from_expr(ctx, operator -> right); + right = gcc_jit_context_new_binary_op(gcc_context, NULL, op, result_type, l, r); + } + else if(expr_type == 2) + { + enum gcc_jit_comparison op = op_table[operator -> op].comp_op; + gcc_jit_rvalue * l = rvalue_from_expr(ctx, operator -> left); + gcc_jit_rvalue * r = rvalue_from_expr(ctx, operator -> right); + right = gcc_jit_context_new_comparison(gcc_context, NULL, op, l, r); + } + else + { + oberon_error(ctx, "rvalue_from_operator: wat"); + } - gen_context -> gcc_block = gcc_block; + return right; } -void -oberon_generate_end_module(oberon_context_t * ctx) +static gcc_jit_rvalue * +rvalue_from_expr(oberon_context_t * ctx, oberon_expr_t * expr) { - 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_rvalue * right; - gcc_jit_block_end_with_void_return(gcc_block, NULL); + if(expr -> is_item) + { + oberon_item_t * item = (oberon_item_t *) expr; + right = rvalue_from_item(ctx, item); + } + else + { + oberon_oper_t * operator = (oberon_oper_t *) expr; + right = rvalue_from_operator(ctx, operator); + } - gen_context -> gcc_block = NULL; + return right; } void -oberon_generate_assign(oberon_context_t * ctx, oberon_item_t * src, oberon_item_t * dst) +oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst) { - printcontext(ctx, "oberon_generate_assign"); - - gen_context_t * gen_context = ctx -> gen_context; - gcc_jit_block * gcc_block = gen_context -> gcc_block; - gcc_jit_lvalue * left; - gcc_jit_rvalue * right; - - right = oberon_generate_rvalue_from_item(ctx, src); + left = lvalue_from_expr(ctx, dst); - if(dst -> mode == MODE_VAR) - { - printf("STORE %s\n", dst -> var -> name); - left = dst -> var -> gen_var; - } - else - { - oberon_error(ctx, "oberon_generate_assign: invalid assignment"); - } + gcc_jit_rvalue * right; + right = rvalue_from_expr(ctx, src); + gen_context_t * gen_context = ctx -> gen_context; + gcc_jit_block * gcc_block = gen_context -> gcc_block; gcc_jit_block_add_assignment(gcc_block, NULL, left, right); } diff --git a/generator.h b/generator.h index e9dbd53..78ae860 100644 --- a/generator.h +++ b/generator.h @@ -6,6 +6,6 @@ void oberon_generator_init_var(oberon_context_t * ctx, oberon_var_t * var); void oberon_generate_begin_module(oberon_context_t * ctx); void oberon_generate_end_module(oberon_context_t * ctx); -void oberon_generate_assign(oberon_context_t * ctx, oberon_item_t * src, oberon_item_t * dst); +void oberon_generate_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst); void oberon_generate_code(oberon_context_t * ctx); diff --git a/oberon.c b/oberon.c index 4dfc604..ec4cab0 100644 --- a/oberon.c +++ b/oberon.c @@ -22,7 +22,22 @@ enum { TRUE, FALSE, LPAREN, - RPAREN + RPAREN, + EQUAL, + NEQ, + LESS, + LEQ, + GREAT, + GEQ, + PLUS, + MINUS, + OR, + STAR, + SLASH, + DIV, + MOD, + AND, + NOT }; // ======================================================================= @@ -44,6 +59,7 @@ oberon_error(oberon_context_t * ctx, const char * fmt, ...) exit(1); } +/* static int oberon_item_to_type_class(oberon_context_t * ctx, oberon_item_t * item) { @@ -67,7 +83,9 @@ oberon_item_to_type_class(oberon_context_t * ctx, oberon_item_t * item) return class; } +*/ +/* static void oberon_autocast_to(oberon_context_t * ctx, oberon_item_t * from, oberon_item_t * to) { @@ -79,6 +97,7 @@ oberon_autocast_to(oberon_context_t * ctx, oberon_item_t * from, oberon_item_t * oberon_error(ctx, "oberon_autocast_to: types not matched %i -> %i", from_class, to_class); } } +*/ // ======================================================================= // TABLE @@ -197,6 +216,18 @@ oberon_read_ident(oberon_context_t * ctx) { ctx -> token = FALSE; } + else if(strcmp(ident, "OR") == 0) + { + ctx -> token = OR; + } + else if(strcmp(ident, "DIV") == 0) + { + ctx -> token = DIV; + } + else if(strcmp(ident, "MOD") == 0) + { + ctx -> token = MOD; + } } static void @@ -267,6 +298,56 @@ oberon_read_symbol(oberon_context_t * ctx) ctx -> token = RPAREN; oberon_get_char(ctx); break; + case '=': + ctx -> token = EQUAL; + oberon_get_char(ctx); + break; + case '#': + ctx -> token = NEQ; + oberon_get_char(ctx); + break; + case '<': + ctx -> token = LESS; + oberon_get_char(ctx); + if(ctx -> c == '=') + { + ctx -> token = LEQ; + oberon_get_char(ctx); + } + break; + case '>': + ctx -> token = GREAT; + oberon_get_char(ctx); + if(ctx -> c == '=') + { + ctx -> token = GEQ; + oberon_get_char(ctx); + } + break; + case '+': + ctx -> token = PLUS; + oberon_get_char(ctx); + break; + case '-': + ctx -> token = MINUS; + oberon_get_char(ctx); + break; + case '*': + ctx -> token = STAR; + oberon_get_char(ctx); + break; + case '/': + ctx -> token = SLASH; + oberon_get_char(ctx); + break; + case '&': + ctx -> token = AND; + oberon_get_char(ctx); + break; + case '~': + ctx -> token = NOT; + oberon_get_char(ctx); + break; default: oberon_error(ctx, "invalid char"); break; @@ -294,22 +375,56 @@ oberon_read_token(oberon_context_t * ctx) } // ======================================================================= -// EXPR +// EXPRESSION // ======================================================================= static void oberon_expect_token(oberon_context_t * ctx, int token); -static oberon_item_t * oberon_expr(oberon_context_t * ctx); +static oberon_expr_t * oberon_expr(oberon_context_t * ctx); static void oberon_assert_token(oberon_context_t * ctx, int token); static char * oberon_assert_ident(oberon_context_t * ctx); -static oberon_item_t * +static oberon_expr_t * +oberon_new_operator(int op, oberon_type_t * result, oberon_expr_t * left, oberon_expr_t * right) +{ + oberon_oper_t * operator; + operator = malloc(sizeof *operator); + memset(operator, 0, sizeof *operator); + + operator -> is_item = 0; + operator -> result = result; + operator -> op = op; + operator -> left = left; + operator -> right = right; + + return (oberon_expr_t *) operator; +} + +static oberon_expr_t * +oberon_new_item(int mode, oberon_type_t * result) +{ + oberon_item_t * item; + item = malloc(sizeof *item); + memset(item, 0, sizeof *item); + + item -> is_item = 1; + item -> result = result; + item -> mode = mode; + + return (oberon_expr_t *)item; +} + +static oberon_expr_t * +oberon_make_not(oberon_context_t * ctx, oberon_expr_t * expr) +{ + return oberon_new_operator(OP_LOGIC_NOT, expr -> result, expr, NULL); +} + +static oberon_expr_t * oberon_factor(oberon_context_t * ctx) { char * name; oberon_var_t * var; - - oberon_item_t * item = malloc(sizeof *item); - memset(item, 0, sizeof *item); + oberon_expr_t * expr; switch(ctx -> token) { @@ -320,40 +435,229 @@ oberon_factor(oberon_context_t * ctx) { oberon_error(ctx, "undefined variable %s", name); } - item -> mode = MODE_VAR; - item -> var = var; + expr = oberon_new_item(MODE_VAR, var -> type); + expr -> item.var = var; break; case INTEGER: - item -> mode = MODE_INTEGER; - item -> integer = ctx -> integer; + expr = oberon_new_item(MODE_INTEGER, ctx -> int_type); + expr -> item.integer = ctx -> integer; oberon_assert_token(ctx, INTEGER); break; case TRUE: - item -> mode = MODE_BOOLEAN; - item -> boolean = 1; + expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type); + expr -> item.boolean = 1; oberon_assert_token(ctx, TRUE); break; case FALSE: - item -> mode = MODE_BOOLEAN; - item -> boolean = 0; + expr = oberon_new_item(MODE_BOOLEAN, ctx -> bool_type); + expr -> item.boolean = 0; oberon_assert_token(ctx, FALSE); break; case LPAREN: oberon_assert_token(ctx, LPAREN); - item = oberon_expr(ctx); + expr = oberon_expr(ctx); oberon_assert_token(ctx, RPAREN); break; + case NOT: + oberon_assert_token(ctx, NOT); + expr = oberon_factor(ctx); + expr = oberon_make_not(ctx, expr); + break; default: oberon_error(ctx, "invalid expression"); } - return item; + return expr; +} + +static oberon_expr_t * +oberon_make_mul_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b) +{ + oberon_expr_t * expr; + oberon_type_t * result; + + result = a -> result; + + if(token == STAR) + { + expr = oberon_new_operator(OP_MUL, result, a, b); + } + else if(token == SLASH) + { + expr = oberon_new_operator(OP_DIV, result, a, b); + } + else if(token == DIV) + { + expr = oberon_new_operator(OP_DIV, result, a, b); + } + else if(token == MOD) + { + expr = oberon_new_operator(OP_MOD, result, a, b); + } + else if(token == AND) + { + expr = oberon_new_operator(OP_LOGIC_AND, result, a, b); + } + else + { + oberon_error(ctx, "oberon_make_mul_op: wat"); + } + + return expr; +} + +#define ISMULOP(x) \ + ((x) >= STAR && (x) <= AND) + +static oberon_expr_t * +oberon_term_expr(oberon_context_t * ctx) +{ + oberon_expr_t * expr; + + expr = oberon_factor(ctx); + while(ISMULOP(ctx -> token)) + { + int token = ctx -> token; + oberon_read_token(ctx); + + oberon_expr_t * inter = oberon_factor(ctx); + expr = oberon_make_mul_op(ctx, token, expr, inter); + } + + return expr; } -static oberon_item_t * +static oberon_expr_t * +oberon_make_add_op(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b) +{ + oberon_expr_t * expr; + oberon_type_t * result; + + result = a -> result; + + if(token == PLUS) + { + expr = oberon_new_operator(OP_ADD, result, a, b); + } + else if(token == MINUS) + { + expr = oberon_new_operator(OP_SUB, result, a, b); + } + else if(token == OR) + { + expr = oberon_new_operator(OP_LOGIC_OR, result, a, b); + } + else + { + oberon_error(ctx, "oberon_make_add_op: wat"); + } + + return expr; +} + +static oberon_expr_t * +oberon_make_unary_minus(oberon_context_t * ctx, oberon_expr_t * expr) +{ + return oberon_new_operator(OP_UNARY_MINUS, expr -> result, expr, NULL); +} + +#define ISADDOP(x) \ + ((x) >= PLUS && (x) <= OR) + +static oberon_expr_t * +oberon_simple_expr(oberon_context_t * ctx) +{ + oberon_expr_t * expr; + + int minus = 0; + if(ctx -> token == PLUS) + { + minus = 0; + oberon_assert_token(ctx, PLUS); + } + else if(ctx -> token == MINUS) + { + minus = 1; + oberon_assert_token(ctx, MINUS); + } + + expr = oberon_term_expr(ctx); + while(ISADDOP(ctx -> token)) + { + int token = ctx -> token; + oberon_read_token(ctx); + + oberon_expr_t * inter = oberon_term_expr(ctx); + expr = oberon_make_add_op(ctx, token, expr, inter); + } + + if(minus) + { + expr = oberon_make_unary_minus(ctx, expr); + } + + return expr; +} + +static oberon_expr_t * +oberon_make_relation(oberon_context_t * ctx, int token, oberon_expr_t * a, oberon_expr_t * b) +{ + oberon_expr_t * expr; + oberon_type_t * result; + + result = a -> result; + + if(token == EQUAL) + { + expr = oberon_new_operator(OP_EQ, result, a, b); + } + else if(token == NEQ) + { + expr = oberon_new_operator(OP_NEQ, result, a, b); + } + else if(token == LESS) + { + expr = oberon_new_operator(OP_LSS, result, a, b); + } + else if(token == LEQ) + { + expr = oberon_new_operator(OP_LEQ, result, a, b); + } + else if(token == GREAT) + { + expr = oberon_new_operator(OP_GRT, result, a, b); + } + else if(token == GEQ) + { + expr = oberon_new_operator(OP_GEQ, result, a, b); + } + else + { + oberon_error(ctx, "oberon_make_relation: wat"); + } + + return expr; +} + +#define ISRELATION(x) \ + ((x) >= EQUAL && (x) <= GEQ) + +static oberon_expr_t * oberon_expr(oberon_context_t * ctx) { - return oberon_factor(ctx); + oberon_expr_t * expr; + + expr = oberon_simple_expr(ctx); + while(ISRELATION(ctx -> token)) + { + int token = ctx -> token; + oberon_read_token(ctx); + + oberon_expr_t * inter = oberon_simple_expr(ctx); + expr = oberon_make_relation(ctx, token, expr, inter); + } + + return expr; } // ======================================================================= @@ -423,14 +727,14 @@ oberon_decl_seq(oberon_context_t * ctx) } static void -oberon_assign(oberon_context_t * ctx, oberon_item_t * src, oberon_item_t * dst) +oberon_assign(oberon_context_t * ctx, oberon_expr_t * src, oberon_expr_t * dst) { - if(dst -> mode == MODE_INTEGER) - { - oberon_error(ctx, "invalid assignment"); - } - - oberon_autocast_to(ctx, src, dst); +// if(dst -> mode == MODE_INTEGER) +// { +// oberon_error(ctx, "invalid assignment"); +// } +// +// oberon_autocast_to(ctx, src, dst); oberon_generate_assign(ctx, src, dst); } @@ -438,8 +742,8 @@ oberon_assign(oberon_context_t * ctx, oberon_item_t * src, oberon_item_t * dst) static void oberon_statement(oberon_context_t * ctx) { - oberon_item_t * item1; - oberon_item_t * item2; + oberon_expr_t * item1; + oberon_expr_t * item2; if(ctx -> token == IDENT) { @@ -496,6 +800,46 @@ oberon_parse_module(oberon_context_t * ctx) // LIBRARY // ======================================================================= +static oberon_type_t * +oberon_register_global_type_ret(oberon_context_t * ctx, oberon_type_t * type) +{ + oberon_type_t * x = ctx -> types; + while(x -> next && strcmp(x -> next -> name, type -> name) != 0) + { + x = x -> next; + } + + if(x -> next) + { + oberon_error(ctx, "already defined"); + } + + // TODO: copy type name (not a pointer) + oberon_type_t * newtype = malloc(sizeof *newtype); + memcpy(newtype, type, sizeof *newtype); + newtype -> next = NULL; + oberon_generator_init_type(ctx, newtype); + + x -> next = newtype; + return newtype; +} + +static void +register_default_types(oberon_context_t * ctx) +{ + static oberon_type_t integer = { "INTEGER", OBERON_TYPE_INTEGER, sizeof(int) }; + static oberon_type_t boolean = { "BOOLEAN", OBERON_TYPE_BOOLEAN, sizeof(int) }; + + ctx -> int_type = oberon_register_global_type_ret(ctx, &integer); + ctx -> bool_type = oberon_register_global_type_ret(ctx, &boolean); +} + +void +oberon_register_global_type(oberon_context_t * ctx, oberon_type_t * type) +{ + oberon_register_global_type_ret(ctx, type); +} + oberon_context_t * oberon_create_context() { @@ -504,9 +848,12 @@ oberon_create_context() oberon_type_t * types = malloc(sizeof *types); memset(types, 0, sizeof *types); + ctx -> types = types; oberon_generator_init_context(ctx); - ctx -> types = types; + + register_default_types(ctx); + return ctx; } @@ -534,25 +881,3 @@ oberon_compile_module(oberon_context_t * ctx, const char * code) return mod; } -void -oberon_register_global_type(oberon_context_t * ctx, oberon_type_t * type) -{ - oberon_type_t * x = ctx -> types; - while(x -> next && strcmp(x -> next -> name, type -> name) != 0) - { - x = x -> next; - } - - if(x -> next) - { - oberon_error(ctx, "already defined"); - } - - // TODO: copy type name (not a pointer) - oberon_type_t * newtype = malloc(sizeof *newtype); - memcpy(newtype, type, sizeof *newtype); - newtype -> next = NULL; - oberon_generator_init_type(ctx, newtype); - - x -> next = newtype; -} diff --git a/oberon.h b/oberon.h index ec742c6..7ed1629 100644 --- a/oberon.h +++ b/oberon.h @@ -51,6 +51,9 @@ struct oberon_context_s oberon_module_t * mod; oberon_type_t * types; + oberon_type_t * int_type; + oberon_type_t * bool_type; + void * gen_context; }; @@ -60,13 +63,59 @@ enum { MODE_BOOLEAN }; -typedef struct +enum { + OP_LOGIC_NOT, + OP_UNARY_MINUS, + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_LOGIC_AND, + OP_LOGIC_OR, + OP_EQ, + OP_NEQ, + OP_LSS, + OP_LEQ, + OP_GRT, + OP_GEQ +}; + +typedef struct oberon_item_s oberon_item_t; +typedef struct oberon_oper_s oberon_oper_t; +typedef union oberon_expr_u oberon_expr_t; + +struct oberon_item_s { + int is_item; + oberon_type_t * result; + int mode; int integer; int boolean; oberon_var_t * var; -} oberon_item_t; +}; + +struct oberon_oper_s +{ + int is_item; + oberon_type_t * result; + + int op; + oberon_expr_t * left; + oberon_expr_t * right; +}; + +union oberon_expr_u +{ + struct { + int is_item; + oberon_type_t * result; + }; + + oberon_item_t item; + oberon_oper_t oper; +}; oberon_context_t * oberon_create_context(); void oberon_destroy_context(oberon_context_t * ctx); diff --git a/test.c b/test.c index 7149026..0837de4 100644 --- a/test.c +++ b/test.c @@ -1,9 +1,6 @@ #include "oberon.h" #include -static oberon_type_t integer = { "INTEGER", OBERON_TYPE_INTEGER, sizeof(int) }; -static oberon_type_t boolean = { "BOOLEAN", OBERON_TYPE_BOOLEAN, sizeof(int) }; - static const char source[] = "MODULE Test;" "VAR" @@ -11,9 +8,9 @@ static const char source[] = " i : INTEGER;" " b : BOOLEAN;" "BEGIN" - " k := 10;" + " k := -10 + 1;" " i := k;" - " b := TRUE;" + " b := ~TRUE OR FALSE;" "END Test." ; @@ -24,8 +21,6 @@ int main(int argc, char ** argv) { ctx = oberon_create_context(); - oberon_register_global_type(ctx, &integer); - oberon_register_global_type(ctx, &boolean); mod = oberon_compile_module(ctx, source); oberon_destroy_context(ctx); return 0; -- 2.29.2