🚀 add bitwise operators or, xor, and
This commit is contained in:
parent
068184f451
commit
c8eb1f1d16
13
README.md
13
README.md
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
12
nasal_ast.h
12
nasal_ast.h
|
@ -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",
|
||||
|
|
|
@ -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:
|
||||
|
|
10
nasal_dbg.h
10
nasal_dbg.h
|
@ -206,8 +206,8 @@ void debugger::run(
|
|||
&&loadl, &&loadu, &&pnum, &&pnil,
|
||||
&&pstr, &&newv, &&newh, &&newf,
|
||||
&&happ, &¶, &&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 );
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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)) {
|
||||
|
|
28
nasal_vm.h
28
nasal_vm.h
|
@ -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, &¶, &&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
|
||||
|
|
|
@ -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))]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue