🚀 add operator `^=` `&=` `|=`
fix bug of parsing expressions beginning with floater
This commit is contained in:
parent
461e5ac647
commit
e11793d340
|
@ -234,7 +234,7 @@ Bitwise operators `~` `|` `&` `^` have the same function as C/C++.
|
|||
0x8^0x1; # xor
|
||||
```
|
||||
|
||||
Operators `=` `+=` `-=` `*=` `/=` `~=` are used in assignment expressions.
|
||||
Operators `=` `+=` `-=` `*=` `/=` `~=` `^=` `&=` `|=` are used in assignment expressions.
|
||||
|
||||
```javascript
|
||||
a=b=c=d=1;
|
||||
|
@ -243,6 +243,10 @@ a-=1;
|
|||
a*=1;
|
||||
a/=1;
|
||||
a~="string";
|
||||
|
||||
a^=0xff;
|
||||
a&=0xca;
|
||||
a|=0xba;
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
|
@ -219,7 +219,7 @@ Nasal拥有基本的四种数学运算符 `+` `-` `*` `/`以及一个特别的
|
|||
0x8^0x1; # 按位异或
|
||||
```
|
||||
|
||||
赋值运算符`=` `+=` `-=` `*=` `/=` `~=`正如其名,用于进行赋值。
|
||||
赋值运算符`=` `+=` `-=` `*=` `/=` `~=` `^=` `&=` `|=`正如其名,用于进行赋值。
|
||||
|
||||
```javascript
|
||||
a=b=c=d=1;
|
||||
|
@ -228,6 +228,10 @@ a-=1;
|
|||
a*=1;
|
||||
a/=1;
|
||||
a~="string";
|
||||
|
||||
a^=0xff;
|
||||
a&=0xca;
|
||||
a|=0xba;
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
|
@ -41,8 +41,17 @@ exprs::=
|
|||
;
|
||||
calculation::=
|
||||
calculation '?' calculation ':' calculation
|
||||
|or_expr
|
||||
|calculation ('=' | '+=' | '-=' | '*=' | '/=' | '~=') calculation
|
||||
|bitwise_or
|
||||
|calculation ('=' | '+=' | '-=' | '*=' | '/=' | '~=' | '^=' | '&=' | '|=') calculation
|
||||
;
|
||||
bitwise_or::=
|
||||
bitwise_xor '|' bitwise_xor
|
||||
;
|
||||
bitwise_xor::=
|
||||
bitwise_and '^' bitwise_and
|
||||
;
|
||||
bitwise_and::=
|
||||
or_expr '&' or_expr
|
||||
;
|
||||
or_expr::=
|
||||
and_expr or and_expr
|
||||
|
|
12
main.cpp
12
main.cpp
|
@ -32,14 +32,14 @@ std::ostream& help(std::ostream& out) {
|
|||
#endif
|
||||
<<"\nnasal <option>\n"
|
||||
<<"option:\n"
|
||||
<<" -h, --help | get help.\n"
|
||||
<<" -h, --help | get help.\n"
|
||||
<<"\nnasal [option] <file> [argv]\n"
|
||||
<<"option:\n"
|
||||
<<" -a, --ast | view abstract syntax tree.\n"
|
||||
<<" -c, --code | view bytecode.\n"
|
||||
<<" -e, --exec | execute.\n"
|
||||
<<" -t, --time | show execute time.\n"
|
||||
<<" -d, --detail | get detail info.\n"
|
||||
<<" -a, --ast | view abstract syntax tree.\n"
|
||||
<<" -c, --code | view bytecode.\n"
|
||||
<<" -e, --exec | execute.\n"
|
||||
<<" -t, --time | show execute time.\n"
|
||||
<<" -d, --detail | get detail info.\n"
|
||||
<<" -dbg, --debug | debug mode.\n"
|
||||
<<"file:\n"
|
||||
<<" <filename> | execute file.\n"
|
||||
|
|
76
nasal_ast.h
76
nasal_ast.h
|
@ -35,6 +35,9 @@ enum ast_node:u32 {
|
|||
ast_multeq, // *=
|
||||
ast_diveq, // /=
|
||||
ast_lnkeq, // ~=
|
||||
ast_btandeq, // &=
|
||||
ast_btoreq, // |=
|
||||
ast_btxoreq, // ^=
|
||||
ast_cmpeq, // ==
|
||||
ast_neq, // !=
|
||||
ast_less, // <
|
||||
|
@ -85,56 +88,59 @@ const char* ast_name[]={
|
|||
"HashMap",
|
||||
"Vector",
|
||||
"HashMapPair",
|
||||
"IdentifierCallExpression",
|
||||
"HashMapCallExpression",
|
||||
"VectorCallExpression",
|
||||
"FunctionCallExpression",
|
||||
"IdentifierCall",
|
||||
"HashMapCall",
|
||||
"VectorCall",
|
||||
"FunctionCall",
|
||||
"SubVector",
|
||||
"ParameterList",
|
||||
"DefaultParameter",
|
||||
"DynamicParameter",
|
||||
"AndExpression",
|
||||
"OrExpression",
|
||||
"EqualExpression",
|
||||
"AddEqualExpression",
|
||||
"SubEqualExpression",
|
||||
"MultEqualExpression",
|
||||
"DivEqualExpression",
|
||||
"LinkEqualExpression",
|
||||
"CompareEqualExpression",
|
||||
"NotEqualExpression",
|
||||
"LessExpression",
|
||||
"LessOrEqualExpression",
|
||||
"GreatExpression",
|
||||
"GreatOrEqualExpression",
|
||||
"AddExpression",
|
||||
"SubExpression",
|
||||
"MultExpression",
|
||||
"DivExpression",
|
||||
"LinkExpression",
|
||||
"NegativeExpression",
|
||||
"LogicalNotExpression",
|
||||
"BitwiseNotExpression",
|
||||
"BitwiseOrExpression",
|
||||
"BitwiseXorExpression",
|
||||
"BitwiseAndExpression",
|
||||
"TrinocularExpression",
|
||||
"And",
|
||||
"Or",
|
||||
"Equal",
|
||||
"AddEqual",
|
||||
"SubEqual",
|
||||
"MultEqual",
|
||||
"DivEqual",
|
||||
"LinkEqual",
|
||||
"BitwiseAndEqual",
|
||||
"BitwiseOrEqual",
|
||||
"BitwiseXorEqual",
|
||||
"CompareEqual",
|
||||
"NotEqual",
|
||||
"Less",
|
||||
"LessOrEqual",
|
||||
"Great",
|
||||
"GreatOrEqual",
|
||||
"Add",
|
||||
"Sub",
|
||||
"Mult",
|
||||
"Div",
|
||||
"Link",
|
||||
"Negative",
|
||||
"LogicalNot",
|
||||
"BitwiseNot",
|
||||
"BitwiseOr",
|
||||
"BitwiseXor",
|
||||
"BitwiseAnd",
|
||||
"Trinocular",
|
||||
"ForLoop",
|
||||
"ForindexLoop",
|
||||
"ForeachLoop",
|
||||
"WhileLoop",
|
||||
"Iterator",
|
||||
"ConditionStatement",
|
||||
"IfStatement",
|
||||
"ElsifStatement",
|
||||
"ElseStatement",
|
||||
"Condition",
|
||||
"If",
|
||||
"Elsif",
|
||||
"Else",
|
||||
"LeftTuple",
|
||||
"Tuple",
|
||||
"Definition",
|
||||
"MultipleAssignment",
|
||||
"Continue",
|
||||
"Break",
|
||||
"ReturnStatement"
|
||||
"Return"
|
||||
};
|
||||
|
||||
class ast {
|
||||
|
|
|
@ -46,6 +46,9 @@ enum op_code_type:u8 {
|
|||
op_muleq, // *=
|
||||
op_diveq, // /=
|
||||
op_lnkeq, // ~=
|
||||
op_btandeq,// &=
|
||||
op_btoreq, // |=
|
||||
op_btxoreq,// ^=
|
||||
op_addeqc, // += const
|
||||
op_subeqc, // -= const
|
||||
op_muleqc, // *= const
|
||||
|
@ -100,17 +103,18 @@ const char* opname[]={
|
|||
"mult ","div ","lnk ","addc ",
|
||||
"subc ","multc ","divc ","lnkc ",
|
||||
"addeq ","subeq ","muleq ","diveq ",
|
||||
"lnkeq ","addeqc","subeqc","muleqc",
|
||||
"diveqc","lnkeqc","meq ","eq ",
|
||||
"neq ","less ","leq ","grt ",
|
||||
"geq ","lessc ","leqc ","grtc ",
|
||||
"geqc ","pop ","jmp ","jt ",
|
||||
"jf ","cnt ","findx ","feach ",
|
||||
"callg ","calll ","upval ","callv ",
|
||||
"callvi","callh ","callfv","callfh",
|
||||
"callb ","slcbeg","slcend","slc ",
|
||||
"slc2 ","mcallg","mcalll","mupval",
|
||||
"mcallv","mcallh","ret "
|
||||
"lnkeq ","bandeq","boreq ","bxoreq",
|
||||
"addeqc","subeqc","muleqc","diveqc",
|
||||
"lnkeqc","meq ","eq ","neq ",
|
||||
"less ","leq ","grt ","geq ",
|
||||
"lessc ","leqc ","grtc ","geqc ",
|
||||
"pop ","jmp ","jt ","jf ",
|
||||
"cnt ","findx ","feach ","callg ",
|
||||
"calll ","upval ","callv ","callvi",
|
||||
"callh ","callfv","callfh","callb ",
|
||||
"slcbeg","slcend","slc ","slc2 ",
|
||||
"mcallg","mcalll","mupval","mcallv",
|
||||
"mcallh","ret "
|
||||
};
|
||||
|
||||
struct opcode {
|
||||
|
@ -146,7 +150,8 @@ public:
|
|||
<<opname[op]<<" "<<std::dec;
|
||||
switch(op) {
|
||||
case op_addeq: case op_subeq: case op_muleq: case op_diveq:
|
||||
case op_lnkeq: case op_meq:
|
||||
case op_lnkeq: case op_meq: case op_btandeq: case op_btoreq:
|
||||
case op_btxoreq:
|
||||
out<<std::hex<<"0x"<<num<<std::dec
|
||||
<<" sp-"<<num;break;
|
||||
case op_addeqc:case op_subeqc: case op_muleqc:case op_diveqc:
|
||||
|
@ -801,8 +806,9 @@ void codegen::for_gen(const ast& node) {
|
|||
case ast_multi_assign:multi_assign_gen(node[0]);break;
|
||||
case ast_addeq:case ast_subeq:
|
||||
case ast_multeq:case ast_diveq:case ast_lnkeq:
|
||||
case ast_btandeq:case ast_btoreq:case ast_btxoreq:
|
||||
calc_gen(node[0]);
|
||||
if (op_addeq<=code.back().op && code.back().op<=op_lnkeq) {
|
||||
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
|
||||
code.back().num=1;
|
||||
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
|
||||
code.back().num|=0x80000000;
|
||||
|
@ -868,8 +874,9 @@ void codegen::for_gen(const ast& node) {
|
|||
case ast_multi_assign:multi_assign_gen(node[2]);break;
|
||||
case ast_addeq:case ast_subeq:
|
||||
case ast_multeq:case ast_diveq:case ast_lnkeq:
|
||||
case ast_btandeq:case ast_btoreq:case ast_btxoreq:
|
||||
calc_gen(node[2]);
|
||||
if (op_addeq<=code.back().op && code.back().op<=op_lnkeq) {
|
||||
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
|
||||
code.back().num=1;
|
||||
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
|
||||
code.back().num|=0x80000000;
|
||||
|
@ -1073,6 +1080,11 @@ void codegen::calc_gen(const ast& node) {
|
|||
gen(op_lnkeqc,str_table[node[1].str()],node.line());
|
||||
}
|
||||
break;
|
||||
case ast_btandeq:case ast_btoreq:case ast_btxoreq:
|
||||
calc_gen(node[1]);
|
||||
mcall(node[0]);
|
||||
gen(node.type()-ast_btandeq+op_btandeq,0,node.line());
|
||||
break;
|
||||
case ast_or:or_gen(node);break;
|
||||
case ast_and:and_gen(node);break;
|
||||
// ast_add(33)~ast_link(37) op_add(18)~op_lnk(22)
|
||||
|
@ -1194,8 +1206,9 @@ void codegen::block_gen(const ast& node) {
|
|||
break;
|
||||
case ast_addeq:case ast_subeq:
|
||||
case ast_multeq:case ast_diveq:case ast_lnkeq:
|
||||
case ast_btandeq:case ast_btoreq:case ast_btxoreq:
|
||||
calc_gen(tmp);
|
||||
if (op_addeq<=code.back().op && code.back().op<=op_lnkeq) {
|
||||
if (op_addeq<=code.back().op && code.back().op<=op_btxoreq) {
|
||||
code.back().num=1;
|
||||
} else if (op_addeqc<=code.back().op && code.back().op<=op_lnkeqc) {
|
||||
code.back().num|=0x80000000;
|
||||
|
|
30
nasal_dbg.h
30
nasal_dbg.h
|
@ -211,17 +211,18 @@ void debugger::run(
|
|||
&&mul, &&div, &&lnk, &&addc,
|
||||
&&subc, &&mulc, &&divc, &&lnkc,
|
||||
&&addeq, &&subeq, &&muleq, &&diveq,
|
||||
&&lnkeq, &&addeqc, &&subeqc, &&muleqc,
|
||||
&&diveqc, &&lnkeqc, &&meq, &&eq,
|
||||
&&neq, &&less, &&leq, &&grt,
|
||||
&&geq, &&lessc, &&leqc, &&grtc,
|
||||
&&geqc, &&pop, &&jmp, &&jt,
|
||||
&&jf, &&cnt, &&findex, &&feach,
|
||||
&&callg, &&calll, &&upval, &&callv,
|
||||
&&callvi, &&callh, &&callfv, &&callfh,
|
||||
&&callb, &&slcbeg, &&slcend, &&slc,
|
||||
&&slc2, &&mcallg, &&mcalll, &&mupval,
|
||||
&&mcallv, &&mcallh, &&ret
|
||||
&&lnkeq, &&bandeq, &&boreq, &&bxoreq,
|
||||
&&addeqc, &&subeqc, &&muleqc, &&diveqc,
|
||||
&&lnkeqc, &&meq, &&eq, &&neq,
|
||||
&&less, &&leq, &&grt, &&geq,
|
||||
&&lessc, &&leqc, &&grtc, &&geqc,
|
||||
&&pop, &&jmp, &&jt, &&jf,
|
||||
&&cnt, &&findex, &&feach, &&callg,
|
||||
&&calll, &&upval, &&callv, &&callvi,
|
||||
&&callh, &&callfv, &&callfh, &&callb,
|
||||
&&slcbeg, &&slcend, &&slc, &&slc2,
|
||||
&&mcallg, &&mcalll, &&mupval, &&mcallv,
|
||||
&&mcallh, &&ret
|
||||
};
|
||||
std::vector<const void*> code;
|
||||
for(auto& i:gen.codes()) {
|
||||
|
@ -251,7 +252,9 @@ void debugger::run(
|
|||
&debugger::o_divc, &debugger::o_lnkc,
|
||||
&debugger::o_addeq, &debugger::o_subeq,
|
||||
&debugger::o_muleq, &debugger::o_diveq,
|
||||
&debugger::o_lnkeq, &debugger::o_addeqc,
|
||||
&debugger::o_lnkeq, &debugger::o_bandeq,
|
||||
&debugger::o_boreq, &debugger::o_bxoreq,
|
||||
&debugger::o_addeqc,
|
||||
&debugger::o_subeqc, &debugger::o_muleqc,
|
||||
&debugger::o_diveqc, &debugger::o_lnkeqc,
|
||||
&debugger::o_meq, &debugger::o_eq,
|
||||
|
@ -344,6 +347,9 @@ subeq: dbg(o_subeq ,op_subeq );
|
|||
muleq: dbg(o_muleq ,op_muleq );
|
||||
diveq: dbg(o_diveq ,op_diveq );
|
||||
lnkeq: dbg(o_lnkeq ,op_lnkeq );
|
||||
bandeq: dbg(o_bandeq,op_btandeq);
|
||||
boreq: dbg(o_boreq, op_btoreq);
|
||||
bxoreq: dbg(o_bxoreq,op_btxoreq);
|
||||
addeqc: dbg(o_addeqc,op_addeqc);
|
||||
subeqc: dbg(o_subeqc,op_subeqc);
|
||||
muleqc: dbg(o_muleqc,op_muleqc);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define F_OK 0
|
||||
#endif
|
||||
|
||||
#include "nasal.h"
|
||||
#include "nasal_ast.h"
|
||||
#include "nasal_lexer.h"
|
||||
#include "nasal_parse.h"
|
||||
|
@ -61,25 +62,28 @@ string linker::path(const ast& node) {
|
|||
}
|
||||
string fpath=".";
|
||||
for(usize i=1;i<node.size();++i) {
|
||||
#ifndef _WIN32
|
||||
fpath+="/"+node[i].str();
|
||||
#else
|
||||
fpath+="\\"+node[i].str();
|
||||
#endif
|
||||
fpath+=(is_windows()? "\\":"/")+node[i].str();
|
||||
}
|
||||
return fpath+".nas";
|
||||
}
|
||||
|
||||
string linker::findf(const string& fname) {
|
||||
// first add file name itself into the file path
|
||||
std::vector<string> fpath={fname};
|
||||
|
||||
// generate search path from environ path
|
||||
for(auto&p:envpath) {
|
||||
fpath.push_back(p+(is_windows()? "\\":"/")+fname);
|
||||
}
|
||||
|
||||
// search file
|
||||
for(auto& i:fpath) {
|
||||
if (access(i.c_str(),F_OK)!=-1) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// we will find lib.nas in nasal std directory
|
||||
if (fname=="lib.nas") {
|
||||
return is_windows()? findf("stl\\lib.nas"):findf("stl/lib.nas");
|
||||
}
|
||||
|
|
|
@ -62,6 +62,9 @@ enum class tok:u32 {
|
|||
multeq, // operator *=
|
||||
diveq, // operator /=
|
||||
lnkeq, // operator ~=
|
||||
btandeq, // operator &=
|
||||
btoreq, // operator |=
|
||||
btxoreq, // operator ^=
|
||||
cmpeq, // operator ==
|
||||
neq, // operator !=
|
||||
less, // operator <
|
||||
|
@ -137,6 +140,9 @@ private:
|
|||
{"*=" ,tok::multeq },
|
||||
{"/=" ,tok::diveq },
|
||||
{"~=" ,tok::lnkeq },
|
||||
{"&=" ,tok::btandeq },
|
||||
{"|=" ,tok::btoreq },
|
||||
{"^=" ,tok::btxoreq },
|
||||
{"==" ,tok::cmpeq },
|
||||
{"!=" ,tok::neq },
|
||||
{"<" ,tok::less },
|
||||
|
@ -200,9 +206,8 @@ bool lexer::is_single_opr(char c) {
|
|||
return (
|
||||
c=='('||c==')'||c=='['||c==']'||
|
||||
c=='{'||c=='}'||c==','||c==';'||
|
||||
c=='|'||c==':'||c=='?'||c=='`'||
|
||||
c=='&'||c=='@'||c=='%'||c=='$'||
|
||||
c=='^'||c=='\\'
|
||||
c==':'||c=='?'||c=='`'||c=='@'||
|
||||
c=='%'||c=='$'||c=='\\'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -210,7 +215,7 @@ bool lexer::is_calc_opr(char c) {
|
|||
return (
|
||||
c=='='||c=='+'||c=='-'||c=='*'||
|
||||
c=='!'||c=='/'||c=='<'||c=='>'||
|
||||
c=='~'
|
||||
c=='~'||c=='|'||c=='&'||c=='^'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
23
nasal_opt.h
23
nasal_opt.h
|
@ -15,14 +15,17 @@ void const_num(ast& root) {
|
|||
auto& vec=root.child();
|
||||
f64 res=0;
|
||||
switch(root.type()) {
|
||||
case ast_add: res=vec[0].num()+vec[1].num(); break;
|
||||
case ast_sub: res=vec[0].num()-vec[1].num(); break;
|
||||
case ast_mult:res=vec[0].num()*vec[1].num(); break;
|
||||
case ast_div: res=vec[0].num()/vec[1].num(); break;
|
||||
case ast_less:res=vec[0].num()<vec[1].num(); break;
|
||||
case ast_leq: res=vec[0].num()<=vec[1].num();break;
|
||||
case ast_grt: res=vec[0].num()>vec[1].num(); break;
|
||||
case ast_geq: res=vec[0].num()>=vec[1].num();break;
|
||||
case ast_add: res=vec[0].num()+vec[1].num(); break;
|
||||
case ast_sub: res=vec[0].num()-vec[1].num(); break;
|
||||
case ast_mult: res=vec[0].num()*vec[1].num(); break;
|
||||
case ast_div: res=vec[0].num()/vec[1].num(); break;
|
||||
case ast_less: res=vec[0].num()<vec[1].num(); break;
|
||||
case ast_leq: res=vec[0].num()<=vec[1].num();break;
|
||||
case ast_grt: res=vec[0].num()>vec[1].num(); break;
|
||||
case ast_geq: res=vec[0].num()>=vec[1].num();break;
|
||||
case ast_bitor: res=i32(vec[0].num())|i32(vec[1].num()); break;
|
||||
case ast_bitxor: res=i32(vec[0].num())^i32(vec[1].num()); break;
|
||||
case ast_bitand: res=i32(vec[0].num())&i32(vec[1].num()); break;
|
||||
}
|
||||
// inf and nan will cause number hashmap error in codegen
|
||||
if (std::isinf(res) || std::isnan(res)) {
|
||||
|
@ -52,7 +55,8 @@ void calc_const(ast& root) {
|
|||
root.type()!=ast_mult && root.type()!=ast_div &&
|
||||
root.type()!=ast_link && root.type()!=ast_less &&
|
||||
root.type()!=ast_leq && root.type()!=ast_grt &&
|
||||
root.type()!=ast_geq) {
|
||||
root.type()!=ast_geq && root.type()!=ast_bitor &&
|
||||
root.type()!=ast_bitxor && root.type()!=ast_bitand) {
|
||||
return;
|
||||
}
|
||||
if (root.type()==ast_link &&
|
||||
|
@ -63,6 +67,7 @@ void calc_const(ast& root) {
|
|||
const_num(root);
|
||||
}
|
||||
}
|
||||
|
||||
void optimize(ast& root) {
|
||||
for(auto& i:root.child()) {
|
||||
calc_const(i);
|
||||
|
|
|
@ -96,6 +96,9 @@ private:
|
|||
{tok::multeq ,"*=" },
|
||||
{tok::diveq ,"/=" },
|
||||
{tok::lnkeq ,"~=" },
|
||||
{tok::btandeq ,"&=" },
|
||||
{tok::btoreq ,"|=" },
|
||||
{tok::btxoreq ,"^=" },
|
||||
{tok::cmpeq ,"==" },
|
||||
{tok::neq ,"!=" },
|
||||
{tok::less ,"<" },
|
||||
|
@ -464,8 +467,8 @@ ast parse::lcurve_expr() {
|
|||
return definition();
|
||||
return check_tuple()?multi_assgin():calc();
|
||||
}
|
||||
ast parse::expr()
|
||||
{
|
||||
|
||||
ast parse::expr() {
|
||||
tok type=toks[ptr].type;
|
||||
if ((type==tok::brk || type==tok::cont) && !in_loop) {
|
||||
die(thisline,thiscol,thislen,"must use break/continue in loops");
|
||||
|
@ -484,6 +487,7 @@ ast parse::expr()
|
|||
case tok::lbracket:
|
||||
case tok::lbrace:
|
||||
case tok::sub:
|
||||
case tok::floater:
|
||||
case tok::opnot: return calc(); break;
|
||||
case tok::var: return definition(); break;
|
||||
case tok::lcurve: return lcurve_expr(); break;
|
||||
|
@ -548,6 +552,12 @@ ast parse::calc() {
|
|||
match(toks[ptr].type);
|
||||
tmp.add(calc());
|
||||
node=std::move(tmp);
|
||||
} else if (toks[ptr].type==tok::btandeq || toks[ptr].type==tok::btoreq || toks[ptr].type==tok::btxoreq) {
|
||||
ast tmp(toks[ptr].tk_end_line,toks[ptr].tk_end_column,(u32)toks[ptr].type-(u32)tok::btandeq+ast_btandeq,toks[ptr].file);
|
||||
tmp.add(std::move(node));
|
||||
match(toks[ptr].type);
|
||||
tmp.add(calc());
|
||||
node=std::move(tmp);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
|
61
nasal_vm.h
61
nasal_vm.h
|
@ -88,6 +88,9 @@ protected:
|
|||
void o_muleq();
|
||||
void o_diveq();
|
||||
void o_lnkeq();
|
||||
void o_bandeq();
|
||||
void o_boreq();
|
||||
void o_bxoreq();
|
||||
void o_addeqc();
|
||||
void o_subeqc();
|
||||
void o_muleqc();
|
||||
|
@ -507,6 +510,11 @@ void vm::o_lnkc() {
|
|||
top[0]=ngc.newstr(top[0].tostr()+cstr[imm[pc]]);
|
||||
}
|
||||
|
||||
// top[0] stores the value of memr[0], to avoid being garbage-collected
|
||||
// so when the calculation ends, top-=1, then top-=imm[pc]
|
||||
// because this return value is meaningless if on stack when imm[pc]=1
|
||||
// like this: func{a+=c;}(); the result of 'a+c' will no be used later, imm[pc]=1
|
||||
// but if b+=a+=c; the result of 'a+c' will be used later, imm[pc]=0
|
||||
#define op_calc_eq(type)\
|
||||
top[-1]=memr[0]=var::num(memr[0].tonum() type top[-1].tonum());\
|
||||
memr=nullptr;\
|
||||
|
@ -522,6 +530,29 @@ void vm::o_lnkeq() {
|
|||
top-=imm[pc]+1;
|
||||
}
|
||||
|
||||
void vm::o_bandeq() {
|
||||
top[-1]=memr[0]=var::num(i32(memr[0].tonum())&i32(top[-1].tonum()));
|
||||
memr=nullptr;
|
||||
top-=imm[pc]+1;
|
||||
}
|
||||
|
||||
void vm::o_boreq() {
|
||||
top[-1]=memr[0]=var::num(i32(memr[0].tonum())|i32(top[-1].tonum()));
|
||||
memr=nullptr;
|
||||
top-=imm[pc]+1;
|
||||
}
|
||||
|
||||
void vm::o_bxoreq() {
|
||||
top[-1]=memr[0]=var::num(i32(memr[0].tonum())^i32(top[-1].tonum()));
|
||||
memr=nullptr;
|
||||
top-=imm[pc]+1;
|
||||
}
|
||||
|
||||
// top[0] stores the value of memr[0], to avoid being garbage-collected
|
||||
// so when the calculation ends, top-=imm[pc]>>31
|
||||
// because this return value is meaningless if on stack when imm[pc]>>31=1
|
||||
// like this: func{a+=1;}(); the result of 'a+1' will no be used later, imm[pc]>>31=1
|
||||
// but if b+=a+=1; the result of 'a+1' will be used later, imm[pc]>>31=0
|
||||
#define op_calc_eq_const(type)\
|
||||
top[0]=memr[0]=var::num(memr[0].tonum() type cnum[imm[pc]&0x7fffffff]);\
|
||||
memr=nullptr;\
|
||||
|
@ -1029,17 +1060,18 @@ void vm::run(
|
|||
&&mul, &&div, &&lnk, &&addc,
|
||||
&&subc, &&mulc, &&divc, &&lnkc,
|
||||
&&addeq, &&subeq, &&muleq, &&diveq,
|
||||
&&lnkeq, &&addeqc, &&subeqc, &&muleqc,
|
||||
&&diveqc, &&lnkeqc, &&meq, &&eq,
|
||||
&&neq, &&less, &&leq, &&grt,
|
||||
&&geq, &&lessc, &&leqc, &&grtc,
|
||||
&&geqc, &&pop, &&jmp, &&jt,
|
||||
&&jf, &&cnt, &&findex, &&feach,
|
||||
&&callg, &&calll, &&upval, &&callv,
|
||||
&&callvi, &&callh, &&callfv, &&callfh,
|
||||
&&callb, &&slcbeg, &&slcend, &&slc,
|
||||
&&slc2, &&mcallg, &&mcalll, &&mupval,
|
||||
&&mcallv, &&mcallh, &&ret
|
||||
&&lnkeq, &&bandeq, &&boreq, &&bxoreq,
|
||||
&&addeqc, &&subeqc, &&muleqc, &&diveqc,
|
||||
&&lnkeqc, &&meq, &&eq, &&neq,
|
||||
&&less, &&leq, &&grt, &&geq,
|
||||
&&lessc, &&leqc, &&grtc, &&geqc,
|
||||
&&pop, &&jmp, &&jt, &&jf,
|
||||
&&cnt, &&findex, &&feach, &&callg,
|
||||
&&calll, &&upval, &&callv, &&callvi,
|
||||
&&callh, &&callfv, &&callfh, &&callb,
|
||||
&&slcbeg, &&slcend, &&slc, &&slc2,
|
||||
&&mcallg, &&mcalll, &&mupval, &&mcallv,
|
||||
&&mcallh, &&ret
|
||||
};
|
||||
std::vector<const void*> code;
|
||||
for(auto& i:gen.codes()) {
|
||||
|
@ -1069,7 +1101,9 @@ void vm::run(
|
|||
&vm::o_divc, &vm::o_lnkc,
|
||||
&vm::o_addeq, &vm::o_subeq,
|
||||
&vm::o_muleq, &vm::o_diveq,
|
||||
&vm::o_lnkeq, &vm::o_addeqc,
|
||||
&vm::o_lnkeq, &vm::o_bandeq,
|
||||
&vm::o_boreq, &vm::o_bxoreq,
|
||||
&vm::o_addeqc,
|
||||
&vm::o_subeqc, &vm::o_muleqc,
|
||||
&vm::o_diveqc, &vm::o_lnkeqc,
|
||||
&vm::o_meq, &vm::o_eq,
|
||||
|
@ -1162,6 +1196,9 @@ subeq: exec_nodie(o_subeq ); // -1
|
|||
muleq: exec_nodie(o_muleq ); // -1
|
||||
diveq: exec_nodie(o_diveq ); // -1
|
||||
lnkeq: exec_nodie(o_lnkeq ); // -1
|
||||
bandeq: exec_nodie(o_bandeq); // -1
|
||||
boreq: exec_nodie(o_boreq ); // -1
|
||||
bxoreq: exec_nodie(o_bxoreq); // -1
|
||||
addeqc: exec_nodie(o_addeqc); // -0
|
||||
subeqc: exec_nodie(o_subeqc); // -0
|
||||
muleqc: exec_nodie(o_muleqc); // -0
|
||||
|
|
|
@ -222,4 +222,10 @@ for(var a=0;a<16;a+=1) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(var a=0;a<16;a+=1) {
|
||||
for(var b=0;b<16;b+=1) {
|
||||
var temp=b;
|
||||
println("temp^=0x"~h[a]~" -> 0x",h[temp^=a]," temp&=0x"~h[a]~" -> 0x",h[temp&=a]," temp|=0x"~h[a]~" -> 0x",h[temp|=a]);
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@ while(1){
|
|||
var cmd=(os.platform()=="windows"?"":"./")~"nasal "~filename;
|
||||
foreach(var i;args)
|
||||
cmd~=" "~i;
|
||||
println(os_time(),info_hd(),"\e[1mexecuting command \"",cmd,"\"\e[0m");
|
||||
var ret=system(cmd);
|
||||
if(ret!=0){
|
||||
println(os_time(),err_hd(),"\e[1mprocess returned ",ret,"\e[0m");
|
||||
|
|
Loading…
Reference in New Issue