🚀 add binary negation
This commit is contained in:
parent
f4deca4427
commit
368b057a91
|
@ -60,7 +60,7 @@ multive_expr::=
|
|||
(unary|scalar) ('*' | '/') (unary|scalar)
|
||||
;
|
||||
unary::=
|
||||
('-'|'!') (unary|scalar)
|
||||
('-'|'!'|'~') (unary|scalar)
|
||||
;
|
||||
scalar::=
|
||||
function {call_scalar}
|
||||
|
|
4
makefile
4
makefile
|
@ -42,7 +42,7 @@ test:nasal
|
|||
@ ./nasal -d test/calc.nas
|
||||
@ ./nasal -e test/choice.nas
|
||||
@ ./nasal -e test/class.nas
|
||||
@ ./nasal -t -d test/console3D.nas 50
|
||||
@ ./nasal -t -d test/console3D.nas 25
|
||||
@ ./nasal -e test/coroutine.nas
|
||||
@ ./nasal -t -d test/datalog.nas
|
||||
@ ./nasal -e test/diff.nas
|
||||
|
@ -63,7 +63,7 @@ test:nasal
|
|||
@ ./nasal -t -d test/md5compare.nas
|
||||
-@ ./nasal -d test/module_test.nas
|
||||
@ ./nasal -e test/nasal_test.nas
|
||||
@ ./nasal test/occupation.nas 10
|
||||
@ ./nasal test/occupation.nas 5
|
||||
@ ./nasal -t -d test/pi.nas
|
||||
@ ./nasal -c test/ppmgen.nas
|
||||
@ ./nasal -t -d test/prime.nas
|
||||
|
|
|
@ -46,8 +46,9 @@ enum ast_node:u32 {
|
|||
ast_mult, // *
|
||||
ast_div, // /
|
||||
ast_link, // ~
|
||||
ast_neg, // -
|
||||
ast_not, // ~
|
||||
ast_neg, // unary -
|
||||
ast_not, // unary !
|
||||
ast_negate, // unary ~
|
||||
ast_trino, // ?:
|
||||
ast_for, // for keyword
|
||||
ast_forindex, // forindex keyword
|
||||
|
@ -109,7 +110,8 @@ const char* ast_name[]={
|
|||
"DivExpression",
|
||||
"LinkExpression",
|
||||
"NegativeExpression",
|
||||
"NotExpression",
|
||||
"LogicalNegationExpression",
|
||||
"BinaryNegationExpression",
|
||||
"TrinocularExpression",
|
||||
"ForLoop",
|
||||
"ForindexLoop",
|
||||
|
|
|
@ -25,8 +25,9 @@ enum op_code_type:u8 {
|
|||
op_para, // normal parameter
|
||||
op_deft, // default parameter
|
||||
op_dyn, // dynamic parameter
|
||||
op_unot, // !
|
||||
op_lnot, // ! logical negation
|
||||
op_usub, // -
|
||||
op_bnot, // ~ binary negation static_cast<i32>
|
||||
op_add, // +
|
||||
op_sub, // -
|
||||
op_mul, // *
|
||||
|
@ -91,7 +92,8 @@ const char* opname[]={
|
|||
"loadl ","loadu ","pnum ","pnil ",
|
||||
"pstr ","newv ","newh ","newf ",
|
||||
"happ ","para ","def ","dyn ",
|
||||
"not ","usub ","add ","sub ",
|
||||
"lnot ","usub ","bnot ","add ",
|
||||
"sub ",
|
||||
"mult ","div ","lnk ","addc ",
|
||||
"subc ","multc ","divc ","lnkc ",
|
||||
"addeq ","subeq ","muleq ","diveq ",
|
||||
|
@ -1112,7 +1114,11 @@ void codegen::calc_gen(const ast& node) {
|
|||
break;
|
||||
case ast_not:
|
||||
calc_gen(node[0]);
|
||||
gen(op_unot,0,node.line());
|
||||
gen(op_lnot,0,node.line());
|
||||
break;
|
||||
case ast_negate:
|
||||
calc_gen(node[0]);
|
||||
gen(op_bnot,0,node.line());
|
||||
break;
|
||||
case ast_def:
|
||||
single_def(node);
|
||||
|
|
|
@ -206,7 +206,8 @@ void debugger::run(
|
|||
&&loadl, &&loadu, &&pnum, &&pnil,
|
||||
&&pstr, &&newv, &&newh, &&newf,
|
||||
&&happ, &¶, &&deft, &&dyn,
|
||||
&&unot, &&usub, &&add, &&sub,
|
||||
&&lnot, &&usub, &&bnot, &&add,
|
||||
&&sub,
|
||||
&&mul, &&div, &&lnk, &&addc,
|
||||
&&subc, &&mulc, &&divc, &&lnkc,
|
||||
&&addeq, &&subeq, &&muleq, &&diveq,
|
||||
|
@ -240,7 +241,8 @@ void debugger::run(
|
|||
&debugger::o_newh, &debugger::o_newf,
|
||||
&debugger::o_happ, &debugger::o_para,
|
||||
&debugger::o_deft, &debugger::o_dyn,
|
||||
&debugger::o_unot, &debugger::o_usub,
|
||||
&debugger::o_lnot, &debugger::o_usub,
|
||||
&debugger::o_bnot,
|
||||
&debugger::o_add, &debugger::o_sub,
|
||||
&debugger::o_mul, &debugger::o_div,
|
||||
&debugger::o_lnk, &debugger::o_addc,
|
||||
|
@ -320,8 +322,9 @@ happ: dbg(o_happ ,op_happ );
|
|||
para: dbg(o_para ,op_para );
|
||||
deft: dbg(o_deft ,op_deft );
|
||||
dyn: dbg(o_dyn ,op_dyn );
|
||||
unot: dbg(o_unot ,op_unot );
|
||||
lnot: dbg(o_lnot ,op_lnot );
|
||||
usub: dbg(o_usub ,op_usub );
|
||||
bnot: dbg(o_bnot ,op_bnot );
|
||||
add: dbg(o_add ,op_add );
|
||||
sub: dbg(o_sub ,op_sub );
|
||||
mul: dbg(o_mul ,op_mul );
|
||||
|
|
|
@ -51,7 +51,10 @@ enum class tok:u32 {
|
|||
sub, // operator -
|
||||
mult, // operator *
|
||||
div, // operator /
|
||||
link, // operator ~
|
||||
floater, // operator ~ and binary operator ~
|
||||
biand, // binary operator &
|
||||
bior, // binary operator |
|
||||
bixor, // binary operator ^
|
||||
opnot, // operator !
|
||||
eq, // operator =
|
||||
addeq, // operator +=
|
||||
|
@ -123,7 +126,10 @@ private:
|
|||
{"-" ,tok::sub },
|
||||
{"*" ,tok::mult },
|
||||
{"/" ,tok::div },
|
||||
{"~" ,tok::link },
|
||||
{"~" ,tok::floater },
|
||||
{"&" ,tok::biand },
|
||||
{"|" ,tok::bior },
|
||||
{"^" ,tok::bixor },
|
||||
{"!" ,tok::opnot },
|
||||
{"=" ,tok::eq },
|
||||
{"+=" ,tok::addeq },
|
||||
|
|
|
@ -54,7 +54,7 @@ private:
|
|||
ast root;
|
||||
error& err;
|
||||
std::unordered_map<tok,string> tokname {
|
||||
{tok::rfor ,"for" },
|
||||
{tok::rfor ,"for" },
|
||||
{tok::forindex,"forindex"},
|
||||
{tok::foreach ,"foreach" },
|
||||
{tok::rwhile ,"while" },
|
||||
|
@ -85,7 +85,10 @@ private:
|
|||
{tok::sub ,"-" },
|
||||
{tok::mult ,"*" },
|
||||
{tok::div ,"/" },
|
||||
{tok::link ,"~" },
|
||||
{tok::floater ,"~" },
|
||||
{tok::biand ,"&" },
|
||||
{tok::bior ,"|" },
|
||||
{tok::bixor ,"^" },
|
||||
{tok::opnot ,"!" },
|
||||
{tok::eq ,"=" },
|
||||
{tok::addeq ,"+=" },
|
||||
|
@ -356,7 +359,7 @@ ast parse::vec() {
|
|||
const tok panic[]={
|
||||
tok::id,tok::str,tok::num,tok::tktrue,
|
||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
||||
tok::func,tok::var,tok::lcurve,
|
||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
||||
tok::lbrace,tok::lbracket,tok::null
|
||||
};
|
||||
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_vec,toks[ptr].file);
|
||||
|
@ -585,12 +588,12 @@ ast parse::cmp_expr() {
|
|||
|
||||
ast parse::additive_expr() {
|
||||
ast node=multive_expr();
|
||||
while(lookahead(tok::add) || lookahead(tok::sub) || lookahead(tok::link)) {
|
||||
while(lookahead(tok::add) || lookahead(tok::sub) || lookahead(tok::floater)) {
|
||||
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
|
||||
switch(toks[ptr].type) {
|
||||
case tok::add: tmp.set_type(ast_add); break;
|
||||
case tok::sub: tmp.set_type(ast_sub); break;
|
||||
case tok::link: tmp.set_type(ast_link); break;
|
||||
case tok::add: tmp.set_type(ast_add); break;
|
||||
case tok::sub: tmp.set_type(ast_sub); break;
|
||||
case tok::floater: tmp.set_type(ast_link); break;
|
||||
default: break;
|
||||
}
|
||||
tmp.add(std::move(node));
|
||||
|
@ -602,12 +605,12 @@ ast parse::additive_expr() {
|
|||
}
|
||||
|
||||
ast parse::multive_expr() {
|
||||
ast node=(lookahead(tok::sub) || lookahead(tok::opnot))?unary():scalar();
|
||||
ast node=(lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar();
|
||||
while(lookahead(tok::mult) || lookahead(tok::div)) {
|
||||
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,(u32)toks[ptr].type-(u32)tok::mult+ast_mult,toks[ptr].file);
|
||||
tmp.add(std::move(node));
|
||||
match(toks[ptr].type);
|
||||
tmp.add((lookahead(tok::sub) || lookahead(tok::opnot))?unary():scalar());
|
||||
tmp.add((lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar());
|
||||
node=std::move(tmp);
|
||||
}
|
||||
return node;
|
||||
|
@ -616,11 +619,12 @@ ast parse::multive_expr() {
|
|||
ast parse::unary() {
|
||||
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_null,toks[ptr].file);
|
||||
switch(toks[ptr].type) {
|
||||
case tok::sub: node.set_type(ast_neg);match(tok::sub);break;
|
||||
case tok::opnot: node.set_type(ast_not);match(tok::opnot);break;
|
||||
case tok::sub: node.set_type(ast_neg);match(tok::sub);break;
|
||||
case tok::opnot: node.set_type(ast_not);match(tok::opnot);break;
|
||||
case tok::floater: node.set_type(ast_negate);match(tok::floater);break;
|
||||
default: break;
|
||||
}
|
||||
node.add((lookahead(tok::sub) || lookahead(tok::opnot))?unary():scalar());
|
||||
node.add((lookahead(tok::sub) || lookahead(tok::opnot) || lookahead(tok::floater))?unary():scalar());
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -695,9 +699,8 @@ ast parse::callv() {
|
|||
const tok panic[]={
|
||||
tok::id,tok::str,tok::num,tok::tktrue,
|
||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
||||
tok::func,tok::var,tok::lcurve,
|
||||
tok::lbrace,tok::lbracket,tok::colon,
|
||||
tok::null
|
||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
||||
tok::lbrace,tok::lbracket,tok::colon,tok::null
|
||||
};
|
||||
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_callv,toks[ptr].file);
|
||||
match(tok::lbracket);
|
||||
|
@ -725,7 +728,7 @@ ast parse::callf() {
|
|||
const tok panic[]={
|
||||
tok::id,tok::str,tok::num,tok::tktrue,
|
||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
||||
tok::func,tok::var,tok::lcurve,
|
||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
||||
tok::lbrace,tok::lbracket,tok::null
|
||||
};
|
||||
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_callf,toks[ptr].file);
|
||||
|
@ -816,7 +819,7 @@ ast parse::multi_scalar() {
|
|||
const tok panic[]={
|
||||
tok::id,tok::str,tok::num,tok::tktrue,
|
||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
||||
tok::func,tok::var,tok::lcurve,
|
||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
||||
tok::lbrace,tok::lbracket,tok::null
|
||||
};
|
||||
ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_tuple,toks[ptr].file);
|
||||
|
|
18
nasal_vm.h
18
nasal_vm.h
|
@ -67,8 +67,9 @@ protected:
|
|||
void o_para();
|
||||
void o_deft();
|
||||
void o_dyn();
|
||||
void o_unot();
|
||||
void o_lnot();
|
||||
void o_usub();
|
||||
void o_bnot();
|
||||
void o_add();
|
||||
void o_sub();
|
||||
void o_mul();
|
||||
|
@ -436,7 +437,7 @@ void vm::o_dyn() {
|
|||
top[0].func().dpara=imm[pc];
|
||||
}
|
||||
|
||||
void vm::o_unot() {
|
||||
void vm::o_lnot() {
|
||||
var val=top[0];
|
||||
switch(val.type) {
|
||||
case vm_nil:top[0]=one;break;
|
||||
|
@ -460,6 +461,10 @@ void vm::o_usub() {
|
|||
top[0]=var::num(-top[0].tonum());
|
||||
}
|
||||
|
||||
void vm::o_bnot() {
|
||||
top[0]=var::num(~static_cast<int32_t>(top[0].num()));
|
||||
}
|
||||
|
||||
#define op_calc(type)\
|
||||
top[-1]=var::num(top[-1].tonum() type top[0].tonum());\
|
||||
--top;
|
||||
|
@ -1001,7 +1006,8 @@ void vm::run(
|
|||
&&loadl, &&loadu, &&pnum, &&pnil,
|
||||
&&pstr, &&newv, &&newh, &&newf,
|
||||
&&happ, &¶, &&deft, &&dyn,
|
||||
&&unot, &&usub, &&add, &&sub,
|
||||
&&lnot, &&usub, &&bnot, &&add,
|
||||
&&sub,
|
||||
&&mul, &&div, &&lnk, &&addc,
|
||||
&&subc, &&mulc, &&divc, &&lnkc,
|
||||
&&addeq, &&subeq, &&muleq, &&diveq,
|
||||
|
@ -1035,7 +1041,8 @@ void vm::run(
|
|||
&vm::o_newh, &vm::o_newf,
|
||||
&vm::o_happ, &vm::o_para,
|
||||
&vm::o_deft, &vm::o_dyn,
|
||||
&vm::o_unot, &vm::o_usub,
|
||||
&vm::o_lnot, &vm::o_usub,
|
||||
&vm::o_bnot,
|
||||
&vm::o_add, &vm::o_sub,
|
||||
&vm::o_mul, &vm::o_div,
|
||||
&vm::o_lnk, &vm::o_addc,
|
||||
|
@ -1115,8 +1122,9 @@ happ: exec_nodie(o_happ ); // -1
|
|||
para: exec_nodie(o_para ); // -0
|
||||
deft: exec_nodie(o_deft ); // -1
|
||||
dyn: exec_nodie(o_dyn ); // -0
|
||||
unot: exec_nodie(o_unot ); // -0
|
||||
lnot: exec_nodie(o_lnot ); // -0
|
||||
usub: exec_nodie(o_usub ); // -0
|
||||
bnot: exec_nodie(o_bnot ); // -0
|
||||
add: exec_nodie(o_add ); // -1
|
||||
sub: exec_nodie(o_sub ); // -1
|
||||
mul: exec_nodie(o_mul ); // -1
|
||||
|
|
|
@ -204,4 +204,11 @@ foreach(i;a){
|
|||
println(runtime.argv());
|
||||
func(a,b,c,d="只有红茶可以吗"){
|
||||
println(a,' ',b,' ',c,' ',d,' true: ',true,' false: ',false);
|
||||
}(c:1919810,b:514,a:114);
|
||||
}(c:1919810,b:514,a:114);
|
||||
|
||||
# test binary negation
|
||||
println("~ 0x80: ",~0x80);
|
||||
println("~ 0x8000: ",~0x8000);
|
||||
println("~ 0x80000000: ",~0x80000000);
|
||||
println("~ 0x8000000000000000: ",~0x8000000000000000);
|
||||
println(~0x80000000==~0x8000000000000000);
|
Loading…
Reference in New Issue