🚀 add bitwise operators or, xor, and

This commit is contained in:
ValKmjolnir 2023-02-16 00:24:32 +08:00
parent 068184f451
commit c8eb1f1d16
9 changed files with 155 additions and 24 deletions

View File

@ -221,6 +221,19 @@ Unary operators `-` `!` have the same function as C/C++.
!0;
```
Bitwise operators `~` `|` `&` `^` have the same function as C/C++.
```javascript
# these operators will:
# 1. convert f64 to i32 (static_cast<int32_t>)
# 2. do the bitwise function
~0x80000000; # not 2147483647
0x8|0x1; # or
0x1&0x2; # and
0x8^0x1; # xor
```
Operators `=` `+=` `-=` `*=` `/=` `~=` are used in assignment expressions.
```javascript

View File

@ -199,13 +199,26 @@ Nasal拥有基本的四种数学运算符 `+` `-` `*` `/`以及一个特别的
1==0 or 1!=0;
```
单目运算符`-` `!`与C/C++中的运算符功能类似.
单目运算符`-` `!`与C/C++中的运算符功能类似
```javascript
-1;
!0;
```
位运算符`~` `|` `&` `^`与C/C++中的运算符功能类似。
```javascript
# 运行过程:
# 1. 将 f64 强转为 i32 (static_cast<int32_t>)
# 2. 执行位运算符
~0x80000000; # 按位取反 2147483647
0x8|0x1; # 按位或
0x1&0x2; # 按位与
0x8^0x1; # 按位异或
```
赋值运算符`=` `+=` `-=` `*=` `/=` `~=`正如其名,用于进行赋值。
```javascript

View File

@ -48,7 +48,10 @@ enum ast_node:u32 {
ast_link, // ~
ast_neg, // unary -
ast_lnot, // unary !
ast_bnot, // unary ~
ast_bnot, // unary ~ bitwise not
ast_bitor, // bitwise or
ast_bitxor, // bitwise xor
ast_bitand, // bitwise and
ast_trino, // ?:
ast_for, // for keyword
ast_forindex, // forindex keyword
@ -110,8 +113,11 @@ const char* ast_name[]={
"DivExpression",
"LinkExpression",
"NegativeExpression",
"LogicalNegationExpression",
"BinaryNegationExpression",
"LogicalNotExpression",
"BitwiseNotExpression",
"BitwiseOrExpression",
"BitwiseXorExpression",
"BitwiseAndExpression",
"TrinocularExpression",
"ForLoop",
"ForindexLoop",

View File

@ -27,7 +27,10 @@ enum op_code_type:u8 {
op_dyn, // dynamic parameter
op_lnot, // ! logical negation
op_usub, // -
op_bnot, // ~ binary negation static_cast<i32>
op_bnot, // ~ bitwise not static_cast<i32>
op_btor, // | bitwise or
op_btxor, // ^ bitwise xor
op_btand, // & bitwise and
op_add, // +
op_sub, // -
op_mul, // *
@ -92,8 +95,8 @@ const char* opname[]={
"loadl ","loadu ","pnum ","pnil ",
"pstr ","newv ","newh ","newf ",
"happ ","para ","def ","dyn ",
"lnot ","usub ","bnot ","add ",
"sub ",
"lnot ","usub ","bnot ","btor ",
"btxor ","btand ","add ","sub ",
"mult ","div ","lnk ","addc ",
"subc ","multc ","divc ","lnkc ",
"addeq ","subeq ","muleq ","diveq ",
@ -811,6 +814,7 @@ void codegen::for_gen(const ast& node) {
case ast_vec:case ast_hash:case ast_func:
case ast_call:
case ast_neg:case ast_lnot:case ast_bnot:
case ast_bitor:case ast_bitxor:case ast_bitand:
case ast_add:case ast_sub:
case ast_mult:case ast_div:
case ast_link:
@ -877,6 +881,7 @@ void codegen::for_gen(const ast& node) {
case ast_vec:case ast_hash:case ast_func:
case ast_call:
case ast_neg:case ast_lnot:case ast_bnot:
case ast_bitor:case ast_bitxor:case ast_bitand:
case ast_add:case ast_sub:case ast_mult:
case ast_div:case ast_link:
case ast_cmpeq:case ast_neq:case ast_leq:
@ -1120,6 +1125,21 @@ void codegen::calc_gen(const ast& node) {
calc_gen(node[0]);
gen(op_bnot,0,node.line());
break;
case ast_bitor:
calc_gen(node[0]);
calc_gen(node[1]);
gen(op_btor,0,node.line());
break;
case ast_bitxor:
calc_gen(node[0]);
calc_gen(node[1]);
gen(op_btxor,0,node.line());
break;
case ast_bitand:
calc_gen(node[0]);
calc_gen(node[1]);
gen(op_btand,0,node.line());
break;
case ast_def:
single_def(node);
call_id(node[0]);
@ -1191,6 +1211,9 @@ void codegen::block_gen(const ast& node) {
case ast_neg:
case ast_lnot:
case ast_bnot:
case ast_bitor:
case ast_bitxor:
case ast_bitand:
case ast_add:
case ast_sub:
case ast_mult:

View File

@ -206,8 +206,8 @@ void debugger::run(
&&loadl, &&loadu, &&pnum, &&pnil,
&&pstr, &&newv, &&newh, &&newf,
&&happ, &&para, &&deft, &&dyn,
&&lnot, &&usub, &&bnot, &&add,
&&sub,
&&lnot, &&usub, &&bnot, &&btor,
&&btxor, &&btand, &&add, &&sub,
&&mul, &&div, &&lnk, &&addc,
&&subc, &&mulc, &&divc, &&lnkc,
&&addeq, &&subeq, &&muleq, &&diveq,
@ -242,7 +242,8 @@ void debugger::run(
&debugger::o_happ, &debugger::o_para,
&debugger::o_deft, &debugger::o_dyn,
&debugger::o_lnot, &debugger::o_usub,
&debugger::o_bnot,
&debugger::o_bnot, &debugger::o_btor,
&debugger::o_btxor, &debugger::o_btand,
&debugger::o_add, &debugger::o_sub,
&debugger::o_mul, &debugger::o_div,
&debugger::o_lnk, &debugger::o_addc,
@ -325,6 +326,9 @@ dyn: dbg(o_dyn ,op_dyn );
lnot: dbg(o_lnot ,op_lnot );
usub: dbg(o_usub ,op_usub );
bnot: dbg(o_bnot ,op_bnot );
btor: dbg(o_btor ,op_btor );
btxor: dbg(o_btxor ,op_btxor );
btand: dbg(o_btand ,op_btand );
add: dbg(o_add ,op_add );
sub: dbg(o_sub ,op_sub );
mul: dbg(o_mul ,op_mul );

View File

@ -52,9 +52,9 @@ enum class tok:u32 {
mult, // operator *
div, // operator /
floater, // operator ~ and binary operator ~
biand, // binary operator &
bior, // binary operator |
bixor, // binary operator ^
btand, // bitwise operator &
btor, // bitwise operator |
btxor, // bitwise operator ^
opnot, // operator !
eq, // operator =
addeq, // operator +=
@ -127,9 +127,9 @@ private:
{"*" ,tok::mult },
{"/" ,tok::div },
{"~" ,tok::floater },
{"&" ,tok::biand },
{"|" ,tok::bior },
{"^" ,tok::bixor },
{"&" ,tok::btand },
{"|" ,tok::btor },
{"^" ,tok::btxor },
{"!" ,tok::opnot },
{"=" ,tok::eq },
{"+=" ,tok::addeq },

View File

@ -86,9 +86,9 @@ private:
{tok::mult ,"*" },
{tok::div ,"/" },
{tok::floater ,"~" },
{tok::biand ,"&" },
{tok::bior ,"|" },
{tok::bixor ,"^" },
{tok::btand ,"&" },
{tok::btor ,"|" },
{tok::btxor ,"^" },
{tok::opnot ,"!" },
{tok::eq ,"=" },
{tok::addeq ,"+=" },
@ -129,6 +129,9 @@ private:
ast expr();
ast exprs();
ast calc();
ast bitwise_or();
ast bitwise_xor();
ast bitwise_and();
ast or_expr();
ast and_expr();
ast cmp_expr();
@ -528,7 +531,7 @@ ast parse::exprs() {
}
ast parse::calc() {
ast node=or_expr();
ast node=bitwise_or();
if (lookahead(tok::quesmark)) {
// trinocular calculation
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_trino,toks[ptr].file);
@ -549,6 +552,42 @@ ast parse::calc() {
return node;
}
ast parse::bitwise_or() {
ast node=bitwise_xor();
while(lookahead(tok::btor)) {
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_bitor,toks[ptr].file);
tmp.add(std::move(node));
match(tok::btor);
tmp.add(bitwise_xor());
node=std::move(tmp);
}
return node;
}
ast parse::bitwise_xor() {
ast node=bitwise_and();
while(lookahead(tok::btxor)) {
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_bitxor,toks[ptr].file);
tmp.add(std::move(node));
match(tok::btxor);
tmp.add(bitwise_and());
node=std::move(tmp);
}
return node;
}
ast parse::bitwise_and() {
ast node=or_expr();
while(lookahead(tok::btand)) {
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_bitand,toks[ptr].file);
tmp.add(std::move(node));
match(tok::btand);
tmp.add(or_expr());
node=std::move(tmp);
}
return node;
}
ast parse::or_expr() {
ast node=and_expr();
while(lookahead(tok::opor)) {

View File

@ -70,6 +70,9 @@ protected:
void o_lnot();
void o_usub();
void o_bnot();
void o_btor();
void o_btxor();
void o_btand();
void o_add();
void o_sub();
void o_mul();
@ -465,6 +468,21 @@ void vm::o_bnot() {
top[0]=var::num(~static_cast<int32_t>(top[0].num()));
}
void vm::o_btor() {
top[-1]=var::num(static_cast<int32_t>(top[-1].tonum())|static_cast<int32_t>(top[0].tonum()));
--top;
}
void vm::o_btxor() {
top[-1]=var::num(static_cast<int32_t>(top[-1].tonum())^static_cast<int32_t>(top[0].tonum()));
--top;
}
void vm::o_btand() {
top[-1]=var::num(static_cast<int32_t>(top[-1].tonum())&static_cast<int32_t>(top[0].tonum()));
--top;
}
#define op_calc(type)\
top[-1]=var::num(top[-1].tonum() type top[0].tonum());\
--top;
@ -1006,8 +1024,8 @@ void vm::run(
&&loadl, &&loadu, &&pnum, &&pnil,
&&pstr, &&newv, &&newh, &&newf,
&&happ, &&para, &&deft, &&dyn,
&&lnot, &&usub, &&bnot, &&add,
&&sub,
&&lnot, &&usub, &&bnot, &&btor,
&&btxor, &&btand, &&add, &&sub,
&&mul, &&div, &&lnk, &&addc,
&&subc, &&mulc, &&divc, &&lnkc,
&&addeq, &&subeq, &&muleq, &&diveq,
@ -1042,7 +1060,8 @@ void vm::run(
&vm::o_happ, &vm::o_para,
&vm::o_deft, &vm::o_dyn,
&vm::o_lnot, &vm::o_usub,
&vm::o_bnot,
&vm::o_bnot, &vm::o_btor,
&vm::o_btxor, &vm::o_btand,
&vm::o_add, &vm::o_sub,
&vm::o_mul, &vm::o_div,
&vm::o_lnk, &vm::o_addc,
@ -1125,6 +1144,9 @@ dyn: exec_nodie(o_dyn ); // -0
lnot: exec_nodie(o_lnot ); // -0
usub: exec_nodie(o_usub ); // -0
bnot: exec_nodie(o_bnot ); // -0
btor: exec_nodie(o_btor ); // -1
btxor: exec_nodie(o_btxor ); // -1
btand: exec_nodie(o_btand ); // -1
add: exec_nodie(o_add ); // -1
sub: exec_nodie(o_sub ); // -1
mul: exec_nodie(o_mul ); // -1

View File

@ -211,4 +211,15 @@ println("~ 0x80: ",~0x80);
println("~ 0x8000: ",~0x8000);
println("~ 0x80000000: ",~0x80000000);
println("~ 0x8000000000000000: ",~0x8000000000000000);
println(~0x80000000==~0x8000000000000000);
println(~0x80000000==~0x8000000000000000);
var h=split(" ","0 1 2 3 4 5 6 7 8 9 a b c d e f");
for(var a=0;a<16;a+=1) {
for(var b=0;b<16;b+=1) {
for(var c=0;c<16;c+=1) {
if(((a^b)&c)!=(a^(b&c))) {
println("0x"~h[a],"^","0x"~h[b],"&","0x"~h[c]," -> a^b&c = 0x",h[a^b&c]," (a^b)&c = 0x",h[(a^b)&c]," a^(b&c) = 0x",h[(a^(b&c))]);
}
}
}
}