🚀 add binary negation

This commit is contained in:
ValKmjolnir 2023-02-12 15:22:05 +08:00
parent f4deca4427
commit 368b057a91
9 changed files with 72 additions and 37 deletions

View File

@ -60,7 +60,7 @@ multive_expr::=
(unary|scalar) ('*' | '/') (unary|scalar)
;
unary::=
('-'|'!') (unary|scalar)
('-'|'!'|'~') (unary|scalar)
;
scalar::=
function {call_scalar}

View File

@ -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

View File

@ -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",

View File

@ -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);

View File

@ -206,7 +206,8 @@ void debugger::run(
&&loadl, &&loadu, &&pnum, &&pnil,
&&pstr, &&newv, &&newh, &&newf,
&&happ, &&para, &&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 );

View File

@ -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 },

View File

@ -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);

View File

@ -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, &&para, &&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

View File

@ -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);