From ec1b284979bc22c8d4859431f6a6e4d3940d433d Mon Sep 17 00:00:00 2001 From: falsycat Date: Thu, 31 Dec 2020 00:00:00 +0000 Subject: [PATCH] Implements bitwise operators. --- TODO.TXT | 2 +- biner.l | 6 ++++- biner.y | 67 ++++++++++++++++++++++++++++++++++++++-------- transpile_c.c | 74 ++++++++++++++++++++------------------------------- tree.h | 8 ++++++ 5 files changed, 99 insertions(+), 58 deletions(-) diff --git a/TODO.TXT b/TODO.TXT index 8d4108e..5277752 100644 --- a/TODO.TXT +++ b/TODO.TXT @@ -11,6 +11,6 @@ X union support X C transpiler for unpacking X C transpiler for packing X setup tests +X add bitmanip operators handling of overflown or negative expression - add bitmanip operators release 1.0.0 diff --git a/biner.l b/biner.l index 21d8bd2..90b5d45 100644 --- a/biner.l +++ b/biner.l @@ -28,6 +28,10 @@ H [0-9A-Fa-f] "!=" { count_(); return NEQUAL; } "<=" { count_(); return LESS_EQUAL; } ">=" { count_(); return GREATER_EQUAL; } +"&&" { count_(); return AND; } +"||" { count_(); return OR; } +"<<" { count_(); return BIT_LSHIFT; } +">>" { count_(); return BIT_RSHIFT; } "const" { count_(); return CONST; } "enum" { count_(); return ENUM; } @@ -39,7 +43,7 @@ H [0-9A-Fa-f] {D}+ { yylval.i = parse_int_(10); count_(); return INTEGER; } 0[xX]{H}+ { yylval.i = parse_int_(16); count_(); return INTEGER; } -[\+\-\*\/\!\=\<\>\.\(\)[\]\{\}\;\,] { count_(); return yytext[0]; } +[\+\-\*\/\!\=\<\>\.\(\)[\]\{\}\;\,\&\|\~\^] { count_(); return yytext[0]; } (.|\n) count_(); diff --git a/biner.y b/biner.y index a9fbaeb..f91e12d 100644 --- a/biner.y +++ b/biner.y @@ -90,7 +90,7 @@ resolve_constant_( uintptr_t ptr; } -%token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL +%token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL AND OR BIT_LSHIFT BIT_RSHIFT %token CONST ENUM STRUCT UNION %token IDENT %token INTEGER; @@ -99,7 +99,10 @@ resolve_constant_( %type enum_member_list enum_member %type struct_member_list struct_member union_member_list union_member %type struct_member_type array_struct_member_type unqualified_struct_member_type -%type expr compare_expr add_expr mul_expr unary_expr operand + +%type expr or_expr and_expr bit_or_expr bit_xor_expr +%type bit_and_expr equality_expr relational_expr add_expr +%type mul_expr unary_expr operand %start decl_list @@ -260,27 +263,66 @@ unqualified_struct_member_type ; expr - : compare_expr + : or_expr ; -compare_expr - : add_expr - | compare_expr EQUAL add_expr { +or_expr + : and_expr + | or_expr OR and_expr { + $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_OR, $3); + } + ; + +and_expr + : bit_or_expr + | and_expr AND bit_or_expr { + $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_AND, $3); + } + ; + +bit_or_expr + : bit_xor_expr + | bit_or_expr '|' bit_xor_expr { + $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_OR, $3); + } + ; + +bit_xor_expr + : bit_and_expr + | bit_xor_expr '^' bit_and_expr { + $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_XOR, $3); + } + ; + +bit_and_expr + : equality_expr + | bit_and_expr '&' equality_expr { + $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_AND, $3); + } + ; + +equality_expr + : relational_expr + | equality_expr EQUAL relational_expr { $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_EQUAL, $3); } - | compare_expr NEQUAL add_expr { + | equality_expr NEQUAL relational_expr { $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_NEQUAL, $3); } - | compare_expr '>' add_expr { + ; + +relational_expr + : add_expr + | relational_expr '>' add_expr { $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER, $3); } - | compare_expr '<' add_expr { + | relational_expr '<' add_expr { $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_LESS, $3); } - | compare_expr GREATER_EQUAL add_expr { + | relational_expr GREATER_EQUAL add_expr { $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER_EQUAL, $3); } - | compare_expr LESS_EQUAL add_expr { + | relational_expr LESS_EQUAL add_expr { $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL, $3); } ; @@ -310,6 +352,9 @@ unary_expr | '!' operand { $$ = create_operator_(0, BINER_TREE_EXPR_TYPE_OPERATOR_NOT, $2); } + | '~' operand { + $$ = create_operator_(0, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT, $2); + } ; operand diff --git a/transpile_c.c b/transpile_c.c index 65c84c4..96500c2 100644 --- a/transpile_c.c +++ b/transpile_c.c @@ -39,6 +39,27 @@ static const struct_member_type_name_meta_t struct_member_type_name_meta_map_ [BINER_TREE_STRUCT_MEMBER_TYPE_NAME_F64] = {"f64", "double"}, }; +static const char* const expr_operator_string_map_ + [BINER_TREE_EXPR_TYPE_OPERATOR_MAX_] = { + [BINER_TREE_EXPR_TYPE_OPERATOR_EQUAL] = "==", + [BINER_TREE_EXPR_TYPE_OPERATOR_NEQUAL] = "!=", + [BINER_TREE_EXPR_TYPE_OPERATOR_GREATER_EQUAL] = ">=", + [BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL] = "<=", + [BINER_TREE_EXPR_TYPE_OPERATOR_GREATER] = ">", + [BINER_TREE_EXPR_TYPE_OPERATOR_LESS] = "<", + [BINER_TREE_EXPR_TYPE_OPERATOR_AND] = "&&", + [BINER_TREE_EXPR_TYPE_OPERATOR_OR] = "||", + [BINER_TREE_EXPR_TYPE_OPERATOR_NOT] = "!", + [BINER_TREE_EXPR_TYPE_OPERATOR_ADD] = "+", + [BINER_TREE_EXPR_TYPE_OPERATOR_SUB] = "-", + [BINER_TREE_EXPR_TYPE_OPERATOR_MUL] = "*", + [BINER_TREE_EXPR_TYPE_OPERATOR_DIV] = "/", + [BINER_TREE_EXPR_TYPE_OPERATOR_BIT_AND] = "&", + [BINER_TREE_EXPR_TYPE_OPERATOR_BIT_OR] = "|", + [BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT] = "~", + [BINER_TREE_EXPR_TYPE_OPERATOR_BIT_XOR] = "^", +}; + typedef struct struct_member_info_t { const biner_transpile_param_t* p; const biner_tree_struct_member_t* m; @@ -160,16 +181,6 @@ static void print_expr_( assert(p != NULL); assert(e != NULL); -# define print_operator_(op) do { \ - if (e->operands.l) { \ - print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.l)); \ - } \ - fprintf(p->dst, op); \ - if (e->operands.r) { \ - print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.r)); \ - } \ - } while (0) - fprintf(p->dst, "("); switch (e->type) { @@ -181,44 +192,17 @@ static void print_expr_( print_struct_member_reference_( p, (const biner_tree_struct_member_reference_t*) (p->zone+e->r)); break; - case BINER_TREE_EXPR_TYPE_OPERATOR_EQUAL: - print_operator_("=="); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_NEQUAL: - print_operator_("!="); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_GREATER_EQUAL: - print_operator_(">="); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL: - print_operator_("<="); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_GREATER: - print_operator_(">"); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_LESS: - print_operator_("<"); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_NOT: - print_operator_("!"); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_ADD: - print_operator_("+"); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_SUB: - print_operator_("-"); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_MUL: - print_operator_("*"); - break; - case BINER_TREE_EXPR_TYPE_OPERATOR_DIV: - print_operator_("/"); - break; + default: + if (e->operands.l) { + print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.l)); + } + fprintf(p->dst, expr_operator_string_map_[e->type]); + if (e->operands.r) { + print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.r)); + } } fprintf(p->dst, ")"); - -# undef print_operator_ } static void print_enum_member_decls_( diff --git a/tree.h b/tree.h index 1fc221a..fef0c6a 100644 --- a/tree.h +++ b/tree.h @@ -25,11 +25,19 @@ typedef enum biner_tree_expr_type_t { BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER, BINER_TREE_EXPR_TYPE_OPERATOR_LESS, + BINER_TREE_EXPR_TYPE_OPERATOR_AND, + BINER_TREE_EXPR_TYPE_OPERATOR_OR, BINER_TREE_EXPR_TYPE_OPERATOR_NOT, BINER_TREE_EXPR_TYPE_OPERATOR_ADD, BINER_TREE_EXPR_TYPE_OPERATOR_SUB, BINER_TREE_EXPR_TYPE_OPERATOR_MUL, BINER_TREE_EXPR_TYPE_OPERATOR_DIV, + BINER_TREE_EXPR_TYPE_OPERATOR_BIT_AND, + BINER_TREE_EXPR_TYPE_OPERATOR_BIT_OR, + BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT, + BINER_TREE_EXPR_TYPE_OPERATOR_BIT_XOR, + + BINER_TREE_EXPR_TYPE_OPERATOR_MAX_, } biner_tree_expr_type_t; typedef struct biner_tree_expr_t {