✨ add keyword support 'true' and 'false'
true is now number 1.0 false is number 0.0
This commit is contained in:
parent
8df02d25ad
commit
d03273b4e1
|
@ -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::=
|
||||
|
|
28
nasal.h
28
nasal.h
|
@ -11,6 +11,30 @@
|
|||
#include <cmath>
|
||||
#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 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;
|
||||
|
|
25
nasal_ast.h
25
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<string>& indent) const{
|
|||
std::cout<<ast_name[nd_type];
|
||||
if (nd_type==ast_str ||
|
||||
nd_type==ast_id ||
|
||||
nd_type==ast_bool ||
|
||||
nd_type==ast_default ||
|
||||
nd_type==ast_dynamic ||
|
||||
nd_type==ast_callh) {
|
||||
|
@ -199,18 +202,14 @@ void ast::print(u32 depth,bool last,std::vector<string>& 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<nd_child.size();++i) {
|
||||
#ifdef _WIN32
|
||||
indent.push_back(i==nd_child.size()-1?"+-":"|-");
|
||||
#else
|
||||
indent.push_back(i==nd_child.size()-1?"└─":"├─");
|
||||
#endif
|
||||
if (is_windows()) {
|
||||
indent.push_back(i==nd_child.size()-1?"+-":"|-");
|
||||
} else {
|
||||
indent.push_back(i==nd_child.size()-1?"└─":"├─");
|
||||
}
|
||||
nd_child[i].print(depth+1,i==nd_child.size()-1,indent);
|
||||
indent.pop_back();
|
||||
}
|
||||
|
|
|
@ -1005,13 +1005,13 @@ var builtin_dlcall(var* local,gc& ngc) {
|
|||
}
|
||||
|
||||
var builtin_platform(var* local,gc& ngc) {
|
||||
#if defined _WIN32 || defined _WIN64
|
||||
return ngc.newstr("windows");
|
||||
#elif defined __linux__
|
||||
return ngc.newstr("linux");
|
||||
#elif defined __APPLE__
|
||||
return ngc.newstr("macOS");
|
||||
#endif
|
||||
if (is_windows()) {
|
||||
return ngc.newstr("windows");
|
||||
} else if (is_linux()) {
|
||||
return ngc.newstr("linux");
|
||||
} else if (is_macos()) {
|
||||
return ngc.newstr("macOS");
|
||||
}
|
||||
return ngc.newstr("unknown");
|
||||
}
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@ private:
|
|||
void gen(u8,u32,u32);
|
||||
void num_gen(const ast&);
|
||||
void str_gen(const ast&);
|
||||
void bool_gen(const ast&);
|
||||
void vec_gen(const ast&);
|
||||
void hash_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());
|
||||
}
|
||||
|
||||
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) {
|
||||
for(auto& child:node.child()) {
|
||||
calc_gen(child);
|
||||
|
@ -804,7 +811,7 @@ void codegen::for_gen(const ast& node) {
|
|||
gen(op_pop,0,node[0].line());
|
||||
}
|
||||
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_call:
|
||||
case ast_neg:case ast_not:
|
||||
|
@ -870,7 +877,7 @@ void codegen::for_gen(const ast& node) {
|
|||
gen(op_pop,0,node[2].line());
|
||||
}
|
||||
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_call:
|
||||
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_str: str_gen(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_hash: hash_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) {
|
||||
for(auto& tmp:node.child()) {
|
||||
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_def:def_gen(tmp);break;
|
||||
case ast_multi_assign:multi_assign_gen(tmp);break;
|
||||
|
|
|
@ -145,7 +145,7 @@ void debugger::interact() {
|
|||
next=false;
|
||||
string cmd;
|
||||
stepinfo();
|
||||
while(1) {
|
||||
while(true) {
|
||||
std::cout<<">> ";
|
||||
std::getline(std::cin,cmd);
|
||||
auto res=parse(cmd);
|
||||
|
|
|
@ -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<string> 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+">");
|
||||
|
|
|
@ -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<token> toks;
|
||||
std::unordered_map<string,tok> typetbl {
|
||||
{"true" ,tok::tktrue },
|
||||
{"false" ,tok::tkfalse },
|
||||
{"for" ,tok::rfor },
|
||||
{"forindex",tok::forindex},
|
||||
{"foreach" ,tok::foreach },
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
Loading…
Reference in New Issue