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 packing
X setup tests
X add bitmanip operators
handling of overflown or negative expression
add bitmanip operators
release 1.0.0

View File

@ -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_();

67
biner.y
View File

@ -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 <ptr> IDENT
%token <i> INTEGER;
@ -99,7 +99,10 @@ resolve_constant_(
%type <ptr> enum_member_list enum_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> 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
@ -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

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"},
};
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_(

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_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 {