Add bitshift operators

This commit is contained in:
AmazingPP 2022-07-21 10:59:19 +08:00
parent 1d2c12e980
commit f2bfa61fc6
10 changed files with 57 additions and 4 deletions

View file

@ -51,6 +51,8 @@ const char* expr_name(ExprTag t)
"&", "&",
"|", "|",
"^", "^",
"<<",
">>",
"&&", "&&",
"||", "||",
"<", "<",
@ -957,6 +959,12 @@ ValPtr BinaryExpr::Fold(Val* v1, Val* v2) const
case EXPR_XOR: case EXPR_XOR:
DO_UINT_FOLD(^); DO_UINT_FOLD(^);
break; break;
case EXPR_LSHIFT:
DO_INT_FOLD(<<);
break;
case EXPR_RSHIFT:
DO_INT_FOLD(>>);
break;
case EXPR_AND_AND: case EXPR_AND_AND:
DO_INT_FOLD(&&); DO_INT_FOLD(&&);
@ -2156,7 +2164,22 @@ BitExpr::BitExpr(ExprTag arg_tag, ExprPtr arg_op1, ExprPtr arg_op2)
if ( IsVector(bt2) ) if ( IsVector(bt2) )
bt2 = t2->AsVectorType()->Yield()->Tag(); bt2 = t2->AsVectorType()->Yield()->Tag();
if ( (bt1 == TYPE_COUNT) && (bt2 == TYPE_COUNT) ) if ( tag == EXPR_LSHIFT || tag == EXPR_RSHIFT )
{
if ( IsIntegral(bt1) && bt2 == TYPE_COUNT )
{
if ( is_vector(op1) || is_vector(op2) )
SetType(make_intrusive<VectorType>(base_type(bt1)));
else
SetType(base_type(bt1));
}
else if ( IsIntegral(bt1) && bt2 == TYPE_INT )
ExprError("requires \"count\" right operand");
else
ExprError("requires integral operands");
}
else if ( (bt1 == TYPE_COUNT) && (bt2 == TYPE_COUNT) )
{ {
if ( is_vector(op1) || is_vector(op2) ) if ( is_vector(op1) || is_vector(op2) )
SetType(make_intrusive<VectorType>(base_type(TYPE_COUNT))); SetType(make_intrusive<VectorType>(base_type(TYPE_COUNT)));

View file

@ -53,6 +53,8 @@ enum ExprTag : int
EXPR_AND, EXPR_AND,
EXPR_OR, EXPR_OR,
EXPR_XOR, EXPR_XOR,
EXPR_LSHIFT,
EXPR_RSHIFT,
EXPR_AND_AND, EXPR_AND_AND,
EXPR_OR_OR, EXPR_OR_OR,
EXPR_LT, EXPR_LT,

View file

@ -5,7 +5,7 @@
// Switching parser table type fixes ambiguity problems. // Switching parser table type fixes ambiguity problems.
%define lr.type ielr %define lr.type ielr
%expect 195 %expect 199
%token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY
%token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF
@ -46,6 +46,7 @@
%left '|' %left '|'
%left '^' %left '^'
%left '&' %left '&'
%left TOK_LSHIFT TOK_RSHIFT
%left '+' '-' %left '+' '-'
%left '*' '/' '%' %left '*' '/' '%'
%left TOK_INCR TOK_DECR %left TOK_INCR TOK_DECR
@ -554,6 +555,18 @@ expr:
$$ = new BitExpr(EXPR_XOR, {AdoptRef{}, $1}, {AdoptRef{}, $3}); $$ = new BitExpr(EXPR_XOR, {AdoptRef{}, $1}, {AdoptRef{}, $3});
} }
| expr TOK_LSHIFT expr
{
set_location(@1, @3);
$$ = new BitExpr(EXPR_LSHIFT, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_RSHIFT expr
{
set_location(@1, @3);
$$ = new BitExpr(EXPR_RSHIFT, {AdoptRef{}, $1}, {AdoptRef{}, $3});
}
| expr TOK_AND_AND expr | expr TOK_AND_AND expr
{ {
set_location(@1, @3); set_location(@1, @3);

View file

@ -248,6 +248,9 @@ ESCSEQ (\\([^\r\n]|[0-7]+|x[[:xdigit:]]+))
"&&" return TOK_AND_AND; "&&" return TOK_AND_AND;
"||" return TOK_OR_OR; "||" return TOK_OR_OR;
"<<" return TOK_LSHIFT;
">>" return TOK_RSHIFT;
add return TOK_ADD; add return TOK_ADD;
addr return TOK_ADDR; addr return TOK_ADDR;
any return TOK_ANY; any return TOK_ANY;

View file

@ -89,6 +89,10 @@ string CPPCompile::GenExpr(const Expr* e, GenType gt, bool top_level)
return GenBinary(e, gt, "|", "or"); return GenBinary(e, gt, "|", "or");
case EXPR_XOR: case EXPR_XOR:
return GenBinary(e, gt, "^", "xor"); return GenBinary(e, gt, "^", "xor");
case EXPR_LSHIFT:
return GenBinary(e, gt, "<<", "lshift");
case EXPR_RSHIFT:
return GenBinary(e, gt, ">>", "rshift");
case EXPR_AND_AND: case EXPR_AND_AND:
return GenBinary(e, gt, "&&", "andand"); return GenBinary(e, gt, "&&", "andand");
case EXPR_OR_OR: case EXPR_OR_OR:

View file

@ -257,6 +257,8 @@ bool Expr::IsFieldAssignable(const Expr* e) const
case EXPR_AND: case EXPR_AND:
case EXPR_OR: case EXPR_OR:
case EXPR_XOR: case EXPR_XOR:
case EXPR_LSHIFT:
case EXPR_RSHIFT:
case EXPR_FIELD: case EXPR_FIELD:
case EXPR_HAS_FIELD: case EXPR_HAS_FIELD:
case EXPR_IN: case EXPR_IN:
@ -1293,7 +1295,7 @@ bool BitExpr::WillTransform(Reducer* c) const
ExprPtr BitExpr::Reduce(Reducer* c, StmtPtr& red_stmt) ExprPtr BitExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
{ {
if ( GetType()->Tag() != TYPE_COUNT ) if ( ! IsIntegral(GetType()->Tag()) )
return BinaryExpr::Reduce(c, red_stmt); return BinaryExpr::Reduce(c, red_stmt);
auto zero1 = op1->IsZero(); auto zero1 = op1->IsZero();
@ -1311,7 +1313,7 @@ ExprPtr BitExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
if ( Tag() == EXPR_AND ) if ( Tag() == EXPR_AND )
return zero_op->ReduceToSingleton(c, red_stmt); return zero_op->ReduceToSingleton(c, red_stmt);
else else
// OR or XOR // OR or XOR or LSHIFT or RSHIFT
return non_zero_op->ReduceToSingleton(c, red_stmt); return non_zero_op->ReduceToSingleton(c, red_stmt);
} }

View file

@ -20,6 +20,8 @@ bitwise and (PASS)
bitwise or (PASS) bitwise or (PASS)
bitwise or (PASS) bitwise or (PASS)
bitwise xor (PASS) bitwise xor (PASS)
bitwise lshift (PASS)
bitwise rshift (PASS)
bitwise complement (PASS) bitwise complement (PASS)
bitwise complement (PASS) bitwise complement (PASS)
max count value = 18446744073709551615 (PASS) max count value = 18446744073709551615 (PASS)

View file

@ -18,6 +18,7 @@ modulus operator (PASS)
division operator (PASS) division operator (PASS)
assignment operator (PASS) assignment operator (PASS)
assignment operator (PASS) assignment operator (PASS)
bitwise rshift (PASS)
max int value = 9223372036854775807 (PASS) max int value = 9223372036854775807 (PASS)
min int value = -9223372036854775808 (PASS) min int value = -9223372036854775808 (PASS)
max int value = 9223372036854775807 (PASS) max int value = 9223372036854775807 (PASS)

View file

@ -49,6 +49,8 @@ event zeek_init()
test_case( "bitwise or", c2 | 0x4 == c2 ); test_case( "bitwise or", c2 | 0x4 == c2 );
test_case( "bitwise or", c4 | 0x4 == c4 ); test_case( "bitwise or", c4 | 0x4 == c4 );
test_case( "bitwise xor", c4 ^ 0x4 == 251 ); test_case( "bitwise xor", c4 ^ 0x4 == 251 );
test_case( "bitwise lshift", c4 << 0x4 == 4080 );
test_case( "bitwise rshift", c4 >> 0x4 == 15 );
test_case( "bitwise complement", ~c6 == 0 ); test_case( "bitwise complement", ~c6 == 0 );
test_case( "bitwise complement", ~~c4 == c4 ); test_case( "bitwise complement", ~~c4 == c4 );

View file

@ -54,6 +54,7 @@ event zeek_init()
test_case( "assignment operator", i2 == 7 ); test_case( "assignment operator", i2 == 7 );
i2 -= 2; i2 -= 2;
test_case( "assignment operator", i2 == 5 ); test_case( "assignment operator", i2 == 5 );
test_case( "bitwise rshift", i10 >> 1 == -6 );
# Max/min value tests # Max/min value tests