diff --git a/doc/nasal.ebnf b/doc/nasal.ebnf index 604a150..339039c 100644 --- a/doc/nasal.ebnf +++ b/doc/nasal.ebnf @@ -10,6 +10,7 @@ nil ::= nil; id ::= identifier; number::= number; string::= string; +bool ::= true | false; vector::= '[' {calculation ','} ']' ; @@ -68,6 +69,7 @@ scalar::= |number |string |nil + |bool |'(' calculation ')' {call_scalar} ; call_scalar::= diff --git a/nasal.h b/nasal.h index dd8bb7e..c38dcc7 100644 --- a/nasal.h +++ b/nasal.h @@ -11,6 +11,30 @@ #include #include +bool is_windows() { +#if defined _WIN32 || defined _WIN64 + return true; +#else + return false; +#endif +} + +bool is_linux() { +#if defined __linux__ + return true; +#else + return false; +#endif +} + +bool is_macos() { +#if defined __APPLE__ + return true; +#else + return false; +#endif +} + using i32=std::int32_t; using i64=std::int64_t; using u8=std::uint8_t; @@ -139,13 +163,11 @@ string chrhex(const char c) { string rawstr(const string& str,const usize maxlen=0) { string ret(""); for(auto i:str) { -#ifdef _WIN32 // windows doesn't output unicode normally, so we output the hex - if (i<=0) { + if (is_windows() && i<=0) { ret+="\\x"+chrhex(i); continue; } -#endif switch(i) { case '\0': ret+="\\0"; break; case '\a': ret+="\\a"; break; diff --git a/nasal_ast.h b/nasal_ast.h index 0e4e35a..69f00f4 100644 --- a/nasal_ast.h +++ b/nasal_ast.h @@ -14,6 +14,7 @@ enum ast_node:u32 { ast_num, // number, basic value type ast_str, // string, basic value type ast_id, // identifier + ast_bool, // bools ast_func, // func keyword ast_hash, // hash, basic value type ast_vec, // vector, basic value type @@ -71,10 +72,11 @@ const char* ast_name[]={ "AbstractSyntaxTreeRoot", "CodeBlock", "FileIndex", - "LiteralNil", - "LiteralNumber", - "LiteralString", + "NilLiteral", + "NumberLiteral", + "StringLiteral", "Identifier", + "BoolLiteral", "Function", "HashMap", "Vector", @@ -188,6 +190,7 @@ void ast::print(u32 depth,bool last,std::vector& indent) const{ std::cout<& indent) const{ if (last && depth) { indent.back()=" "; } else if (!last && depth) { -#ifdef _WIN32 - indent.back()="| "; -#else - indent.back()="│ "; -#endif + indent.back()=is_windows()? "| ":"│ "; } for(u32 i=0;i> "; std::getline(std::cin,cmd); auto res=parse(cmd); diff --git a/nasal_import.h b/nasal_import.h index 1bc9f7d..d296d58 100644 --- a/nasal_import.h +++ b/nasal_import.h @@ -39,11 +39,7 @@ public: }; linker::linker(error& e):show_path(false),lib_loaded(false),err(e) { -#ifdef _WIN32 - char sep=';'; -#else - char sep=':'; -#endif + char sep=is_windows()? ';':':'; string PATH=getenv("PATH"); usize last=0,pos=PATH.find(sep,0); while(pos!=string::npos) { @@ -77,11 +73,7 @@ string linker::path(const ast& node) { string linker::findf(const string& fname) { std::vector fpath={fname}; for(auto&p:envpath) { -#ifdef _WIN32 - fpath.push_back(p+"\\"+fname); -#else - fpath.push_back(p+"/"+fname); -#endif + fpath.push_back(p+(is_windows()? "\\":"/")+fname); } for(auto& i:fpath) { if (access(i.c_str(),F_OK)!=-1) { @@ -89,11 +81,7 @@ string linker::findf(const string& fname) { } } if (fname=="lib.nas") { -#ifdef _WIN32 - return findf("stl\\lib.nas"); -#else - return findf("stl/lib.nas"); -#endif + return is_windows()? findf("stl\\lib.nas"):findf("stl/lib.nas"); } if (!show_path) { err.err("link","cannot find file <"+fname+">"); diff --git a/nasal_lexer.h b/nasal_lexer.h index cb9e51d..ddcc3a9 100644 --- a/nasal_lexer.h +++ b/nasal_lexer.h @@ -18,6 +18,8 @@ enum class tok:u32 { num, // number literal str, // string literal id, // identifier + tktrue, // keyword true + tkfalse, // keyword false rfor, // loop keyword for forindex, // loop keyword forindex foreach, // loop keyword foreach @@ -88,6 +90,8 @@ private: error& err; std::vector toks; std::unordered_map typetbl { + {"true" ,tok::tktrue }, + {"false" ,tok::tkfalse }, {"for" ,tok::rfor }, {"forindex",tok::forindex}, {"foreach" ,tok::foreach }, diff --git a/nasal_parse.h b/nasal_parse.h index 5f79853..541e989 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -116,6 +116,7 @@ private: ast num(); ast str(); ast id(); + ast bools(); ast vec(); ast hash(); ast pair(); @@ -337,13 +338,24 @@ ast parse::id() { return node; } +ast parse::bools() { + ast node(toks[ptr].tk_end_line,toks[ptr].tk_end_column,ast_bool,toks[ptr].file); + node.set_str(toks[ptr].str); + if (lookahead(tok::tktrue)) { + match(tok::tktrue); + } else { + match(tok::tkfalse); + } + return node; +} + ast parse::vec() { // panic set for this token is not ',' // this is the FIRST set of calculation // array end with tok::null=0 const tok panic[]={ - tok::id,tok::str,tok::num, - tok::opnot,tok::sub,tok::tknil, + 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::null }; @@ -460,6 +472,8 @@ ast parse::expr() case tok::num: case tok::str: case tok::id: + case tok::tktrue: + case tok::tkfalse: case tok::func: case tok::lbracket: case tok::lbrace: @@ -621,6 +635,8 @@ ast parse::scalar() { node=str(); } else if (lookahead(tok::id)) { node=id(); + } else if (lookahead(tok::tktrue) || lookahead(tok::tkfalse)) { + node=bools(); } else if (lookahead(tok::func)) { node=func(); } else if (lookahead(tok::lbracket)) { @@ -677,8 +693,8 @@ ast parse::callv() { // this is the FIRST set of subvec // array end with tok::null=0 const tok panic[]={ - tok::id,tok::str,tok::num, - tok::opnot,tok::sub,tok::tknil, + 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 @@ -707,8 +723,8 @@ ast parse::callf() { // this is the FIRST set of calculation/hashmember // array end with tok::null=0 const tok panic[]={ - tok::id,tok::str,tok::num, - tok::opnot,tok::sub,tok::tknil, + 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::null }; @@ -798,8 +814,8 @@ ast parse::multi_id() { ast parse::multi_scalar() { // if check_call_memory is true,we will check if value called here can reach a memory space const tok panic[]={ - tok::id,tok::str,tok::num, - tok::opnot,tok::sub,tok::tknil, + 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::null }; diff --git a/test/nasal_test.nas b/test/nasal_test.nas index b430a4c..60f40dd 100644 --- a/test/nasal_test.nas +++ b/test/nasal_test.nas @@ -51,6 +51,7 @@ z.funcc(); #//f is called println(z.funcccall); #//func(..){..} z2.listt2[3].hashh.funcc(); #//f is called println(y1[f2()][w]); #//hello +println(true,' ',false); #//1 0 # ValKmjolnir diff --git a/test/scalar.nas b/test/scalar.nas index d9350f4..ec6a0d3 100644 --- a/test/scalar.nas +++ b/test/scalar.nas @@ -203,5 +203,5 @@ foreach(i;a){ } println(runtime.argv()); func(a,b,c,d="只有红茶可以吗"){ - println(a,' ',b,' ',c,' ',d); + println(a,' ',b,' ',c,' ',d,' true: ',true,' false: ',false); }(c:1919810,b:514,a:114); \ No newline at end of file