🚀 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;
|
!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.
|
Operators `=` `+=` `-=` `*=` `/=` `~=` are used in assignment expressions.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
|
@ -199,13 +199,26 @@ Nasal拥有基本的四种数学运算符 `+` `-` `*` `/`以及一个特别的
|
||||||
1==0 or 1!=0;
|
1==0 or 1!=0;
|
||||||
```
|
```
|
||||||
|
|
||||||
单目运算符`-` `!`与C/C++中的运算符功能类似.
|
单目运算符`-` `!`与C/C++中的运算符功能类似。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
-1;
|
-1;
|
||||||
!0;
|
!0;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
位运算符`~` `|` `&` `^`与C/C++中的运算符功能类似。
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
# 运行过程:
|
||||||
|
# 1. 将 f64 强转为 i32 (static_cast<int32_t>)
|
||||||
|
# 2. 执行位运算符
|
||||||
|
|
||||||
|
~0x80000000; # 按位取反 2147483647
|
||||||
|
0x8|0x1; # 按位或
|
||||||
|
0x1&0x2; # 按位与
|
||||||
|
0x8^0x1; # 按位异或
|
||||||
|
```
|
||||||
|
|
||||||
赋值运算符`=` `+=` `-=` `*=` `/=` `~=`正如其名,用于进行赋值。
|
赋值运算符`=` `+=` `-=` `*=` `/=` `~=`正如其名,用于进行赋值。
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
12
nasal_ast.h
12
nasal_ast.h
|
@ -48,7 +48,10 @@ enum ast_node:u32 {
|
||||||
ast_link, // ~
|
ast_link, // ~
|
||||||
ast_neg, // unary -
|
ast_neg, // unary -
|
||||||
ast_lnot, // 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_trino, // ?:
|
||||||
ast_for, // for keyword
|
ast_for, // for keyword
|
||||||
ast_forindex, // forindex keyword
|
ast_forindex, // forindex keyword
|
||||||
|
@ -110,8 +113,11 @@ const char* ast_name[]={
|
||||||
"DivExpression",
|
"DivExpression",
|
||||||
"LinkExpression",
|
"LinkExpression",
|
||||||
"NegativeExpression",
|
"NegativeExpression",
|
||||||
"LogicalNegationExpression",
|
"LogicalNotExpression",
|
||||||
"BinaryNegationExpression",
|
"BitwiseNotExpression",
|
||||||
|
"BitwiseOrExpression",
|
||||||
|
"BitwiseXorExpression",
|
||||||
|
"BitwiseAndExpression",
|
||||||
"TrinocularExpression",
|
"TrinocularExpression",
|
||||||
"ForLoop",
|
"ForLoop",
|
||||||
"ForindexLoop",
|
"ForindexLoop",
|
||||||
|
|
|
@ -27,7 +27,10 @@ enum op_code_type:u8 {
|
||||||
op_dyn, // dynamic parameter
|
op_dyn, // dynamic parameter
|
||||||
op_lnot, // ! logical negation
|
op_lnot, // ! logical negation
|
||||||
op_usub, // -
|
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_add, // +
|
||||||
op_sub, // -
|
op_sub, // -
|
||||||
op_mul, // *
|
op_mul, // *
|
||||||
|
@ -92,8 +95,8 @@ const char* opname[]={
|
||||||
"loadl ","loadu ","pnum ","pnil ",
|
"loadl ","loadu ","pnum ","pnil ",
|
||||||
"pstr ","newv ","newh ","newf ",
|
"pstr ","newv ","newh ","newf ",
|
||||||
"happ ","para ","def ","dyn ",
|
"happ ","para ","def ","dyn ",
|
||||||
"lnot ","usub ","bnot ","add ",
|
"lnot ","usub ","bnot ","btor ",
|
||||||
"sub ",
|
"btxor ","btand ","add ","sub ",
|
||||||
"mult ","div ","lnk ","addc ",
|
"mult ","div ","lnk ","addc ",
|
||||||
"subc ","multc ","divc ","lnkc ",
|
"subc ","multc ","divc ","lnkc ",
|
||||||
"addeq ","subeq ","muleq ","diveq ",
|
"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_vec:case ast_hash:case ast_func:
|
||||||
case ast_call:
|
case ast_call:
|
||||||
case ast_neg:case ast_lnot:case ast_bnot:
|
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_add:case ast_sub:
|
||||||
case ast_mult:case ast_div:
|
case ast_mult:case ast_div:
|
||||||
case ast_link:
|
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_vec:case ast_hash:case ast_func:
|
||||||
case ast_call:
|
case ast_call:
|
||||||
case ast_neg:case ast_lnot:case ast_bnot:
|
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_add:case ast_sub:case ast_mult:
|
||||||
case ast_div:case ast_link:
|
case ast_div:case ast_link:
|
||||||
case ast_cmpeq:case ast_neq:case ast_leq:
|
case ast_cmpeq:case ast_neq:case ast_leq:
|
||||||
|
@ -1120,6 +1125,21 @@ void codegen::calc_gen(const ast& node) {
|
||||||
calc_gen(node[0]);
|
calc_gen(node[0]);
|
||||||
gen(op_bnot,0,node.line());
|
gen(op_bnot,0,node.line());
|
||||||
break;
|
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:
|
case ast_def:
|
||||||
single_def(node);
|
single_def(node);
|
||||||
call_id(node[0]);
|
call_id(node[0]);
|
||||||
|
@ -1191,6 +1211,9 @@ void codegen::block_gen(const ast& node) {
|
||||||
case ast_neg:
|
case ast_neg:
|
||||||
case ast_lnot:
|
case ast_lnot:
|
||||||
case ast_bnot:
|
case ast_bnot:
|
||||||
|
case ast_bitor:
|
||||||
|
case ast_bitxor:
|
||||||
|
case ast_bitand:
|
||||||
case ast_add:
|
case ast_add:
|
||||||
case ast_sub:
|
case ast_sub:
|
||||||
case ast_mult:
|
case ast_mult:
|
||||||
|
|
10
nasal_dbg.h
10
nasal_dbg.h
|
@ -206,8 +206,8 @@ void debugger::run(
|
||||||
&&loadl, &&loadu, &&pnum, &&pnil,
|
&&loadl, &&loadu, &&pnum, &&pnil,
|
||||||
&&pstr, &&newv, &&newh, &&newf,
|
&&pstr, &&newv, &&newh, &&newf,
|
||||||
&&happ, &¶, &&deft, &&dyn,
|
&&happ, &¶, &&deft, &&dyn,
|
||||||
&&lnot, &&usub, &&bnot, &&add,
|
&&lnot, &&usub, &&bnot, &&btor,
|
||||||
&&sub,
|
&&btxor, &&btand, &&add, &&sub,
|
||||||
&&mul, &&div, &&lnk, &&addc,
|
&&mul, &&div, &&lnk, &&addc,
|
||||||
&&subc, &&mulc, &&divc, &&lnkc,
|
&&subc, &&mulc, &&divc, &&lnkc,
|
||||||
&&addeq, &&subeq, &&muleq, &&diveq,
|
&&addeq, &&subeq, &&muleq, &&diveq,
|
||||||
|
@ -242,7 +242,8 @@ void debugger::run(
|
||||||
&debugger::o_happ, &debugger::o_para,
|
&debugger::o_happ, &debugger::o_para,
|
||||||
&debugger::o_deft, &debugger::o_dyn,
|
&debugger::o_deft, &debugger::o_dyn,
|
||||||
&debugger::o_lnot, &debugger::o_usub,
|
&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_add, &debugger::o_sub,
|
||||||
&debugger::o_mul, &debugger::o_div,
|
&debugger::o_mul, &debugger::o_div,
|
||||||
&debugger::o_lnk, &debugger::o_addc,
|
&debugger::o_lnk, &debugger::o_addc,
|
||||||
|
@ -325,6 +326,9 @@ dyn: dbg(o_dyn ,op_dyn );
|
||||||
lnot: dbg(o_lnot ,op_lnot );
|
lnot: dbg(o_lnot ,op_lnot );
|
||||||
usub: dbg(o_usub ,op_usub );
|
usub: dbg(o_usub ,op_usub );
|
||||||
bnot: dbg(o_bnot ,op_bnot );
|
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 );
|
add: dbg(o_add ,op_add );
|
||||||
sub: dbg(o_sub ,op_sub );
|
sub: dbg(o_sub ,op_sub );
|
||||||
mul: dbg(o_mul ,op_mul );
|
mul: dbg(o_mul ,op_mul );
|
||||||
|
|
|
@ -52,9 +52,9 @@ enum class tok:u32 {
|
||||||
mult, // operator *
|
mult, // operator *
|
||||||
div, // operator /
|
div, // operator /
|
||||||
floater, // operator ~ and binary operator ~
|
floater, // operator ~ and binary operator ~
|
||||||
biand, // binary operator &
|
btand, // bitwise operator &
|
||||||
bior, // binary operator |
|
btor, // bitwise operator |
|
||||||
bixor, // binary operator ^
|
btxor, // bitwise operator ^
|
||||||
opnot, // operator !
|
opnot, // operator !
|
||||||
eq, // operator =
|
eq, // operator =
|
||||||
addeq, // operator +=
|
addeq, // operator +=
|
||||||
|
@ -127,9 +127,9 @@ private:
|
||||||
{"*" ,tok::mult },
|
{"*" ,tok::mult },
|
||||||
{"/" ,tok::div },
|
{"/" ,tok::div },
|
||||||
{"~" ,tok::floater },
|
{"~" ,tok::floater },
|
||||||
{"&" ,tok::biand },
|
{"&" ,tok::btand },
|
||||||
{"|" ,tok::bior },
|
{"|" ,tok::btor },
|
||||||
{"^" ,tok::bixor },
|
{"^" ,tok::btxor },
|
||||||
{"!" ,tok::opnot },
|
{"!" ,tok::opnot },
|
||||||
{"=" ,tok::eq },
|
{"=" ,tok::eq },
|
||||||
{"+=" ,tok::addeq },
|
{"+=" ,tok::addeq },
|
||||||
|
|
|
@ -86,9 +86,9 @@ private:
|
||||||
{tok::mult ,"*" },
|
{tok::mult ,"*" },
|
||||||
{tok::div ,"/" },
|
{tok::div ,"/" },
|
||||||
{tok::floater ,"~" },
|
{tok::floater ,"~" },
|
||||||
{tok::biand ,"&" },
|
{tok::btand ,"&" },
|
||||||
{tok::bior ,"|" },
|
{tok::btor ,"|" },
|
||||||
{tok::bixor ,"^" },
|
{tok::btxor ,"^" },
|
||||||
{tok::opnot ,"!" },
|
{tok::opnot ,"!" },
|
||||||
{tok::eq ,"=" },
|
{tok::eq ,"=" },
|
||||||
{tok::addeq ,"+=" },
|
{tok::addeq ,"+=" },
|
||||||
|
@ -129,6 +129,9 @@ private:
|
||||||
ast expr();
|
ast expr();
|
||||||
ast exprs();
|
ast exprs();
|
||||||
ast calc();
|
ast calc();
|
||||||
|
ast bitwise_or();
|
||||||
|
ast bitwise_xor();
|
||||||
|
ast bitwise_and();
|
||||||
ast or_expr();
|
ast or_expr();
|
||||||
ast and_expr();
|
ast and_expr();
|
||||||
ast cmp_expr();
|
ast cmp_expr();
|
||||||
|
@ -528,7 +531,7 @@ ast parse::exprs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast parse::calc() {
|
ast parse::calc() {
|
||||||
ast node=or_expr();
|
ast node=bitwise_or();
|
||||||
if (lookahead(tok::quesmark)) {
|
if (lookahead(tok::quesmark)) {
|
||||||
// trinocular calculation
|
// trinocular calculation
|
||||||
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_trino,toks[ptr].file);
|
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;
|
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 parse::or_expr() {
|
||||||
ast node=and_expr();
|
ast node=and_expr();
|
||||||
while(lookahead(tok::opor)) {
|
while(lookahead(tok::opor)) {
|
||||||
|
|
28
nasal_vm.h
28
nasal_vm.h
|
@ -70,6 +70,9 @@ protected:
|
||||||
void o_lnot();
|
void o_lnot();
|
||||||
void o_usub();
|
void o_usub();
|
||||||
void o_bnot();
|
void o_bnot();
|
||||||
|
void o_btor();
|
||||||
|
void o_btxor();
|
||||||
|
void o_btand();
|
||||||
void o_add();
|
void o_add();
|
||||||
void o_sub();
|
void o_sub();
|
||||||
void o_mul();
|
void o_mul();
|
||||||
|
@ -465,6 +468,21 @@ void vm::o_bnot() {
|
||||||
top[0]=var::num(~static_cast<int32_t>(top[0].num()));
|
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)\
|
#define op_calc(type)\
|
||||||
top[-1]=var::num(top[-1].tonum() type top[0].tonum());\
|
top[-1]=var::num(top[-1].tonum() type top[0].tonum());\
|
||||||
--top;
|
--top;
|
||||||
|
@ -1006,8 +1024,8 @@ void vm::run(
|
||||||
&&loadl, &&loadu, &&pnum, &&pnil,
|
&&loadl, &&loadu, &&pnum, &&pnil,
|
||||||
&&pstr, &&newv, &&newh, &&newf,
|
&&pstr, &&newv, &&newh, &&newf,
|
||||||
&&happ, &¶, &&deft, &&dyn,
|
&&happ, &¶, &&deft, &&dyn,
|
||||||
&&lnot, &&usub, &&bnot, &&add,
|
&&lnot, &&usub, &&bnot, &&btor,
|
||||||
&&sub,
|
&&btxor, &&btand, &&add, &&sub,
|
||||||
&&mul, &&div, &&lnk, &&addc,
|
&&mul, &&div, &&lnk, &&addc,
|
||||||
&&subc, &&mulc, &&divc, &&lnkc,
|
&&subc, &&mulc, &&divc, &&lnkc,
|
||||||
&&addeq, &&subeq, &&muleq, &&diveq,
|
&&addeq, &&subeq, &&muleq, &&diveq,
|
||||||
|
@ -1042,7 +1060,8 @@ void vm::run(
|
||||||
&vm::o_happ, &vm::o_para,
|
&vm::o_happ, &vm::o_para,
|
||||||
&vm::o_deft, &vm::o_dyn,
|
&vm::o_deft, &vm::o_dyn,
|
||||||
&vm::o_lnot, &vm::o_usub,
|
&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_add, &vm::o_sub,
|
||||||
&vm::o_mul, &vm::o_div,
|
&vm::o_mul, &vm::o_div,
|
||||||
&vm::o_lnk, &vm::o_addc,
|
&vm::o_lnk, &vm::o_addc,
|
||||||
|
@ -1125,6 +1144,9 @@ dyn: exec_nodie(o_dyn ); // -0
|
||||||
lnot: exec_nodie(o_lnot ); // -0
|
lnot: exec_nodie(o_lnot ); // -0
|
||||||
usub: exec_nodie(o_usub ); // -0
|
usub: exec_nodie(o_usub ); // -0
|
||||||
bnot: exec_nodie(o_bnot ); // -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
|
add: exec_nodie(o_add ); // -1
|
||||||
sub: exec_nodie(o_sub ); // -1
|
sub: exec_nodie(o_sub ); // -1
|
||||||
mul: exec_nodie(o_mul ); // -1
|
mul: exec_nodie(o_mul ); // -1
|
||||||
|
|
|
@ -211,4 +211,15 @@ println("~ 0x80: ",~0x80);
|
||||||
println("~ 0x8000: ",~0x8000);
|
println("~ 0x8000: ",~0x8000);
|
||||||
println("~ 0x80000000: ",~0x80000000);
|
println("~ 0x80000000: ",~0x80000000);
|
||||||
println("~ 0x8000000000000000: ",~0x8000000000000000);
|
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