Implements bitwise operators.

This commit is contained in:
falsycat 2020-12-31 00:00:00 +00:00
parent d418241f95
commit ec1b284979
5 changed files with 99 additions and 58 deletions

View File

@ -11,6 +11,6 @@ X union support
X C transpiler for unpacking X C transpiler for unpacking
X C transpiler for packing X C transpiler for packing
X setup tests X setup tests
X add bitmanip operators
handling of overflown or negative expression handling of overflown or negative expression
add bitmanip operators
release 1.0.0 release 1.0.0

View File

@ -28,6 +28,10 @@ H [0-9A-Fa-f]
"!=" { count_(); return NEQUAL; } "!=" { count_(); return NEQUAL; }
"<=" { count_(); return LESS_EQUAL; } "<=" { count_(); return LESS_EQUAL; }
">=" { count_(); return GREATER_EQUAL; } ">=" { count_(); return GREATER_EQUAL; }
"&&" { count_(); return AND; }
"||" { count_(); return OR; }
"<<" { count_(); return BIT_LSHIFT; }
">>" { count_(); return BIT_RSHIFT; }
"const" { count_(); return CONST; } "const" { count_(); return CONST; }
"enum" { count_(); return ENUM; } "enum" { count_(); return ENUM; }
@ -39,7 +43,7 @@ H [0-9A-Fa-f]
{D}+ { yylval.i = parse_int_(10); count_(); return INTEGER; } {D}+ { yylval.i = parse_int_(10); count_(); return INTEGER; }
0[xX]{H}+ { yylval.i = parse_int_(16); count_(); return INTEGER; } 0[xX]{H}+ { yylval.i = parse_int_(16); count_(); return INTEGER; }
[\+\-\*\/\!\=\<\>\.\(\)[\]\{\}\;\,] { count_(); return yytext[0]; } [\+\-\*\/\!\=\<\>\.\(\)[\]\{\}\;\,\&\|\~\^] { count_(); return yytext[0]; }
(.|\n) count_(); (.|\n) count_();

67
biner.y
View File

@ -90,7 +90,7 @@ resolve_constant_(
uintptr_t ptr; 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 CONST ENUM STRUCT UNION
%token <ptr> IDENT %token <ptr> IDENT
%token <i> INTEGER; %token <i> INTEGER;
@ -99,7 +99,10 @@ resolve_constant_(
%type <ptr> enum_member_list enum_member %type <ptr> enum_member_list enum_member
%type <ptr> struct_member_list struct_member union_member_list union_member %type <ptr> struct_member_list struct_member union_member_list union_member
%type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type %type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type
%type <ptr> expr compare_expr add_expr mul_expr unary_expr operand
%type <ptr> expr or_expr and_expr bit_or_expr bit_xor_expr
%type <ptr> bit_and_expr equality_expr relational_expr add_expr
%type <ptr> mul_expr unary_expr operand
%start decl_list %start decl_list
@ -260,27 +263,66 @@ unqualified_struct_member_type
; ;
expr expr
: compare_expr : or_expr
; ;
compare_expr or_expr
: add_expr : and_expr
| compare_expr EQUAL add_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); $$ = 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); $$ = 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); $$ = 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); $$ = 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); $$ = 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); $$ = create_operator_($1, BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL, $3);
} }
; ;
@ -310,6 +352,9 @@ unary_expr
| '!' operand { | '!' operand {
$$ = create_operator_(0, BINER_TREE_EXPR_TYPE_OPERATOR_NOT, $2); $$ = create_operator_(0, BINER_TREE_EXPR_TYPE_OPERATOR_NOT, $2);
} }
| '~' operand {
$$ = create_operator_(0, BINER_TREE_EXPR_TYPE_OPERATOR_BIT_NOT, $2);
}
; ;
operand operand

View File

@ -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"}, [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 { typedef struct struct_member_info_t {
const biner_transpile_param_t* p; const biner_transpile_param_t* p;
const biner_tree_struct_member_t* m; const biner_tree_struct_member_t* m;
@ -160,16 +181,6 @@ static void print_expr_(
assert(p != NULL); assert(p != NULL);
assert(e != 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, "("); fprintf(p->dst, "(");
switch (e->type) { switch (e->type) {
@ -181,44 +192,17 @@ static void print_expr_(
print_struct_member_reference_( print_struct_member_reference_(
p, (const biner_tree_struct_member_reference_t*) (p->zone+e->r)); p, (const biner_tree_struct_member_reference_t*) (p->zone+e->r));
break; break;
case BINER_TREE_EXPR_TYPE_OPERATOR_EQUAL: default:
print_operator_("=="); if (e->operands.l) {
break; print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.l));
case BINER_TREE_EXPR_TYPE_OPERATOR_NEQUAL: }
print_operator_("!="); fprintf(p->dst, expr_operator_string_map_[e->type]);
break; if (e->operands.r) {
case BINER_TREE_EXPR_TYPE_OPERATOR_GREATER_EQUAL: print_expr_(p, (const biner_tree_expr_t*) (p->zone+e->operands.r));
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;
} }
fprintf(p->dst, ")"); fprintf(p->dst, ")");
# undef print_operator_
} }
static void print_enum_member_decls_( static void print_enum_member_decls_(

8
tree.h
View File

@ -25,11 +25,19 @@ typedef enum biner_tree_expr_type_t {
BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL, BINER_TREE_EXPR_TYPE_OPERATOR_LESS_EQUAL,
BINER_TREE_EXPR_TYPE_OPERATOR_GREATER, BINER_TREE_EXPR_TYPE_OPERATOR_GREATER,
BINER_TREE_EXPR_TYPE_OPERATOR_LESS, 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_NOT,
BINER_TREE_EXPR_TYPE_OPERATOR_ADD, BINER_TREE_EXPR_TYPE_OPERATOR_ADD,
BINER_TREE_EXPR_TYPE_OPERATOR_SUB, BINER_TREE_EXPR_TYPE_OPERATOR_SUB,
BINER_TREE_EXPR_TYPE_OPERATOR_MUL, BINER_TREE_EXPR_TYPE_OPERATOR_MUL,
BINER_TREE_EXPR_TYPE_OPERATOR_DIV, 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; } biner_tree_expr_type_t;
typedef struct biner_tree_expr_t { typedef struct biner_tree_expr_t {