add keyword support 'true' and 'false'

true is now number 1.0

false is number 0.0
This commit is contained in:
ValKmjolnir 2023-01-16 17:44:56 +08:00
parent 8df02d25ad
commit d03273b4e1
11 changed files with 95 additions and 51 deletions

View File

@ -10,6 +10,7 @@ nil ::= nil;
id ::= identifier; id ::= identifier;
number::= number; number::= number;
string::= string; string::= string;
bool ::= true | false;
vector::= vector::=
'[' {calculation ','} ']' '[' {calculation ','} ']'
; ;
@ -68,6 +69,7 @@ scalar::=
|number |number
|string |string
|nil |nil
|bool
|'(' calculation ')' {call_scalar} |'(' calculation ')' {call_scalar}
; ;
call_scalar::= call_scalar::=

28
nasal.h
View File

@ -11,6 +11,30 @@
#include <cmath> #include <cmath>
#include <vector> #include <vector>
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 i32=std::int32_t;
using i64=std::int64_t; using i64=std::int64_t;
using u8=std::uint8_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 rawstr(const string& str,const usize maxlen=0) {
string ret(""); string ret("");
for(auto i:str) { for(auto i:str) {
#ifdef _WIN32
// windows doesn't output unicode normally, so we output the hex // windows doesn't output unicode normally, so we output the hex
if (i<=0) { if (is_windows() && i<=0) {
ret+="\\x"+chrhex(i); ret+="\\x"+chrhex(i);
continue; continue;
} }
#endif
switch(i) { switch(i) {
case '\0': ret+="\\0"; break; case '\0': ret+="\\0"; break;
case '\a': ret+="\\a"; break; case '\a': ret+="\\a"; break;

View File

@ -14,6 +14,7 @@ enum ast_node:u32 {
ast_num, // number, basic value type ast_num, // number, basic value type
ast_str, // string, basic value type ast_str, // string, basic value type
ast_id, // identifier ast_id, // identifier
ast_bool, // bools
ast_func, // func keyword ast_func, // func keyword
ast_hash, // hash, basic value type ast_hash, // hash, basic value type
ast_vec, // vector, basic value type ast_vec, // vector, basic value type
@ -71,10 +72,11 @@ const char* ast_name[]={
"AbstractSyntaxTreeRoot", "AbstractSyntaxTreeRoot",
"CodeBlock", "CodeBlock",
"FileIndex", "FileIndex",
"LiteralNil", "NilLiteral",
"LiteralNumber", "NumberLiteral",
"LiteralString", "StringLiteral",
"Identifier", "Identifier",
"BoolLiteral",
"Function", "Function",
"HashMap", "HashMap",
"Vector", "Vector",
@ -188,6 +190,7 @@ void ast::print(u32 depth,bool last,std::vector<string>& indent) const{
std::cout<<ast_name[nd_type]; std::cout<<ast_name[nd_type];
if (nd_type==ast_str || if (nd_type==ast_str ||
nd_type==ast_id || nd_type==ast_id ||
nd_type==ast_bool ||
nd_type==ast_default || nd_type==ast_default ||
nd_type==ast_dynamic || nd_type==ast_dynamic ||
nd_type==ast_callh) { nd_type==ast_callh) {
@ -199,18 +202,14 @@ void ast::print(u32 depth,bool last,std::vector<string>& indent) const{
if (last && depth) { if (last && depth) {
indent.back()=" "; indent.back()=" ";
} else if (!last && depth) { } else if (!last && depth) {
#ifdef _WIN32 indent.back()=is_windows()? "| ":"";
indent.back()="| ";
#else
indent.back()="";
#endif
} }
for(u32 i=0;i<nd_child.size();++i) { for(u32 i=0;i<nd_child.size();++i) {
#ifdef _WIN32 if (is_windows()) {
indent.push_back(i==nd_child.size()-1?"+-":"|-"); indent.push_back(i==nd_child.size()-1?"+-":"|-");
#else } else {
indent.push_back(i==nd_child.size()-1?"└─":"├─"); indent.push_back(i==nd_child.size()-1?"└─":"├─");
#endif }
nd_child[i].print(depth+1,i==nd_child.size()-1,indent); nd_child[i].print(depth+1,i==nd_child.size()-1,indent);
indent.pop_back(); indent.pop_back();
} }

View File

@ -1005,13 +1005,13 @@ var builtin_dlcall(var* local,gc& ngc) {
} }
var builtin_platform(var* local,gc& ngc) { var builtin_platform(var* local,gc& ngc) {
#if defined _WIN32 || defined _WIN64 if (is_windows()) {
return ngc.newstr("windows"); return ngc.newstr("windows");
#elif defined __linux__ } else if (is_linux()) {
return ngc.newstr("linux"); return ngc.newstr("linux");
#elif defined __APPLE__ } else if (is_macos()) {
return ngc.newstr("macOS"); return ngc.newstr("macOS");
#endif }
return ngc.newstr("unknown"); return ngc.newstr("unknown");
} }

View File

@ -230,6 +230,7 @@ private:
void gen(u8,u32,u32); void gen(u8,u32,u32);
void num_gen(const ast&); void num_gen(const ast&);
void str_gen(const ast&); void str_gen(const ast&);
void bool_gen(const ast&);
void vec_gen(const ast&); void vec_gen(const ast&);
void hash_gen(const ast&); void hash_gen(const ast&);
void func_gen(const ast&); void func_gen(const ast&);
@ -390,6 +391,12 @@ void codegen::str_gen(const ast& node) {
gen(op_pstr,str_table[node.str()],node.line()); gen(op_pstr,str_table[node.str()],node.line());
} }
void codegen::bool_gen(const ast& node) {
f64 num=node.str()=="true"?1:0;
regist_num(num);
gen(op_pnum,num_table[num],node.line());
}
void codegen::vec_gen(const ast& node) { void codegen::vec_gen(const ast& node) {
for(auto& child:node.child()) { for(auto& child:node.child()) {
calc_gen(child); calc_gen(child);
@ -804,7 +811,7 @@ void codegen::for_gen(const ast& node) {
gen(op_pop,0,node[0].line()); gen(op_pop,0,node[0].line());
} }
break; break;
case ast_nil:case ast_num:case ast_str:break; case ast_nil:case ast_num:case ast_str:case ast_bool:break;
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_not: case ast_neg:case ast_not:
@ -870,7 +877,7 @@ void codegen::for_gen(const ast& node) {
gen(op_pop,0,node[2].line()); gen(op_pop,0,node[2].line());
} }
break; break;
case ast_nil:case ast_num:case ast_str:break; case ast_nil:case ast_num:case ast_str:case ast_bool:break;
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_not: case ast_neg:case ast_not:
@ -1029,6 +1036,7 @@ void codegen::calc_gen(const ast& node) {
case ast_num: num_gen(node); break; case ast_num: num_gen(node); break;
case ast_str: str_gen(node); break; case ast_str: str_gen(node); break;
case ast_id: call_id(node); break; case ast_id: call_id(node); break;
case ast_bool: bool_gen(node); break;
case ast_vec: vec_gen(node); break; case ast_vec: vec_gen(node); break;
case ast_hash: hash_gen(node); break; case ast_hash: hash_gen(node); break;
case ast_func: func_gen(node); break; case ast_func: func_gen(node); break;
@ -1122,7 +1130,11 @@ void codegen::calc_gen(const ast& node) {
void codegen::block_gen(const ast& node) { void codegen::block_gen(const ast& node) {
for(auto& tmp:node.child()) { for(auto& tmp:node.child()) {
switch(tmp.type()) { switch(tmp.type()) {
case ast_null:case ast_nil:case ast_num:case ast_str:break; case ast_null:
case ast_nil:
case ast_num:
case ast_str:
case ast_bool:break;
case ast_file:fileindex=tmp.num();break; // special node type in main block case ast_file:fileindex=tmp.num();break; // special node type in main block
case ast_def:def_gen(tmp);break; case ast_def:def_gen(tmp);break;
case ast_multi_assign:multi_assign_gen(tmp);break; case ast_multi_assign:multi_assign_gen(tmp);break;

View File

@ -145,7 +145,7 @@ void debugger::interact() {
next=false; next=false;
string cmd; string cmd;
stepinfo(); stepinfo();
while(1) { while(true) {
std::cout<<">> "; std::cout<<">> ";
std::getline(std::cin,cmd); std::getline(std::cin,cmd);
auto res=parse(cmd); auto res=parse(cmd);

View File

@ -39,11 +39,7 @@ public:
}; };
linker::linker(error& e):show_path(false),lib_loaded(false),err(e) { linker::linker(error& e):show_path(false),lib_loaded(false),err(e) {
#ifdef _WIN32 char sep=is_windows()? ';':':';
char sep=';';
#else
char sep=':';
#endif
string PATH=getenv("PATH"); string PATH=getenv("PATH");
usize last=0,pos=PATH.find(sep,0); usize last=0,pos=PATH.find(sep,0);
while(pos!=string::npos) { while(pos!=string::npos) {
@ -77,11 +73,7 @@ string linker::path(const ast& node) {
string linker::findf(const string& fname) { string linker::findf(const string& fname) {
std::vector<string> fpath={fname}; std::vector<string> fpath={fname};
for(auto&p:envpath) { for(auto&p:envpath) {
#ifdef _WIN32 fpath.push_back(p+(is_windows()? "\\":"/")+fname);
fpath.push_back(p+"\\"+fname);
#else
fpath.push_back(p+"/"+fname);
#endif
} }
for(auto& i:fpath) { for(auto& i:fpath) {
if (access(i.c_str(),F_OK)!=-1) { if (access(i.c_str(),F_OK)!=-1) {
@ -89,11 +81,7 @@ string linker::findf(const string& fname) {
} }
} }
if (fname=="lib.nas") { if (fname=="lib.nas") {
#ifdef _WIN32 return is_windows()? findf("stl\\lib.nas"):findf("stl/lib.nas");
return findf("stl\\lib.nas");
#else
return findf("stl/lib.nas");
#endif
} }
if (!show_path) { if (!show_path) {
err.err("link","cannot find file <"+fname+">"); err.err("link","cannot find file <"+fname+">");

View File

@ -18,6 +18,8 @@ enum class tok:u32 {
num, // number literal num, // number literal
str, // string literal str, // string literal
id, // identifier id, // identifier
tktrue, // keyword true
tkfalse, // keyword false
rfor, // loop keyword for rfor, // loop keyword for
forindex, // loop keyword forindex forindex, // loop keyword forindex
foreach, // loop keyword foreach foreach, // loop keyword foreach
@ -88,6 +90,8 @@ private:
error& err; error& err;
std::vector<token> toks; std::vector<token> toks;
std::unordered_map<string,tok> typetbl { std::unordered_map<string,tok> typetbl {
{"true" ,tok::tktrue },
{"false" ,tok::tkfalse },
{"for" ,tok::rfor }, {"for" ,tok::rfor },
{"forindex",tok::forindex}, {"forindex",tok::forindex},
{"foreach" ,tok::foreach }, {"foreach" ,tok::foreach },

View File

@ -116,6 +116,7 @@ private:
ast num(); ast num();
ast str(); ast str();
ast id(); ast id();
ast bools();
ast vec(); ast vec();
ast hash(); ast hash();
ast pair(); ast pair();
@ -337,13 +338,24 @@ ast parse::id() {
return node; 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() { ast parse::vec() {
// panic set for this token is not ',' // panic set for this token is not ','
// this is the FIRST set of calculation // this is the FIRST set of calculation
// array end with tok::null=0 // array end with tok::null=0
const tok panic[]={ const tok panic[]={
tok::id,tok::str,tok::num, tok::id,tok::str,tok::num,tok::tktrue,
tok::opnot,tok::sub,tok::tknil, tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
tok::func,tok::var,tok::lcurve, tok::func,tok::var,tok::lcurve,
tok::lbrace,tok::lbracket,tok::null tok::lbrace,tok::lbracket,tok::null
}; };
@ -460,6 +472,8 @@ ast parse::expr()
case tok::num: case tok::num:
case tok::str: case tok::str:
case tok::id: case tok::id:
case tok::tktrue:
case tok::tkfalse:
case tok::func: case tok::func:
case tok::lbracket: case tok::lbracket:
case tok::lbrace: case tok::lbrace:
@ -621,6 +635,8 @@ ast parse::scalar() {
node=str(); node=str();
} else if (lookahead(tok::id)) { } else if (lookahead(tok::id)) {
node=id(); node=id();
} else if (lookahead(tok::tktrue) || lookahead(tok::tkfalse)) {
node=bools();
} else if (lookahead(tok::func)) { } else if (lookahead(tok::func)) {
node=func(); node=func();
} else if (lookahead(tok::lbracket)) { } else if (lookahead(tok::lbracket)) {
@ -677,8 +693,8 @@ ast parse::callv() {
// this is the FIRST set of subvec // this is the FIRST set of subvec
// array end with tok::null=0 // array end with tok::null=0
const tok panic[]={ const tok panic[]={
tok::id,tok::str,tok::num, tok::id,tok::str,tok::num,tok::tktrue,
tok::opnot,tok::sub,tok::tknil, tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
tok::func,tok::var,tok::lcurve, tok::func,tok::var,tok::lcurve,
tok::lbrace,tok::lbracket,tok::colon, tok::lbrace,tok::lbracket,tok::colon,
tok::null tok::null
@ -707,8 +723,8 @@ ast parse::callf() {
// this is the FIRST set of calculation/hashmember // this is the FIRST set of calculation/hashmember
// array end with tok::null=0 // array end with tok::null=0
const tok panic[]={ const tok panic[]={
tok::id,tok::str,tok::num, tok::id,tok::str,tok::num,tok::tktrue,
tok::opnot,tok::sub,tok::tknil, tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
tok::func,tok::var,tok::lcurve, tok::func,tok::var,tok::lcurve,
tok::lbrace,tok::lbracket,tok::null tok::lbrace,tok::lbracket,tok::null
}; };
@ -798,8 +814,8 @@ ast parse::multi_id() {
ast parse::multi_scalar() { ast parse::multi_scalar() {
// if check_call_memory is true,we will check if value called here can reach a memory space // if check_call_memory is true,we will check if value called here can reach a memory space
const tok panic[]={ const tok panic[]={
tok::id,tok::str,tok::num, tok::id,tok::str,tok::num,tok::tktrue,
tok::opnot,tok::sub,tok::tknil, tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
tok::func,tok::var,tok::lcurve, tok::func,tok::var,tok::lcurve,
tok::lbrace,tok::lbracket,tok::null tok::lbrace,tok::lbracket,tok::null
}; };

View File

@ -51,6 +51,7 @@ z.funcc(); #//f is called
println(z.funcccall); #//func(..){..} println(z.funcccall); #//func(..){..}
z2.listt2[3].hashh.funcc(); #//f is called z2.listt2[3].hashh.funcc(); #//f is called
println(y1[f2()][w]); #//hello println(y1[f2()][w]); #//hello
println(true,' ',false); #//1 0
# ValKmjolnir # ValKmjolnir

View File

@ -203,5 +203,5 @@ foreach(i;a){
} }
println(runtime.argv()); println(runtime.argv());
func(a,b,c,d="只有红茶可以吗"){ 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); }(c:1919810,b:514,a:114);