✨ `str()` can be used on complex types
This commit is contained in:
parent
230848a6e1
commit
ef09946fd6
|
@ -163,13 +163,11 @@ public:
|
||||||
next(true), fsize(0),
|
next(true), fsize(0),
|
||||||
break_file_index(0), break_line(0),
|
break_file_index(0), break_line(0),
|
||||||
do_operand_count(false) {}
|
do_operand_count(false) {}
|
||||||
void run(
|
void run(const codegen&,
|
||||||
const codegen&,
|
const linker&,
|
||||||
const linker&,
|
const std::vector<std::string>&,
|
||||||
const std::vector<std::string>&,
|
bool,
|
||||||
bool,
|
bool);
|
||||||
bool
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,8 +120,9 @@ void error::warn(const std::string& stage, const std::string& info) {
|
||||||
std::clog << orange << stage << ": " << white << info << reset << "\n\n";
|
std::clog << orange << stage << ": " << white << info << reset << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void error::err(
|
void error::err(const std::string& stage,
|
||||||
const std::string& stage, const span& loc, const std::string& info) {
|
const span& loc,
|
||||||
|
const std::string& info) {
|
||||||
// load error occurred file into string lines
|
// load error occurred file into string lines
|
||||||
load(loc.file);
|
load(loc.file);
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,8 @@ std::string linker::get_path(expr* node) {
|
||||||
return content->get_content();
|
return content->get_content();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string linker::find_real_file_path(
|
std::string linker::find_real_file_path(const std::string& filename,
|
||||||
const std::string& filename, const span& location) {
|
const span& location) {
|
||||||
// first add file name itself into the file path
|
// first add file name itself into the file path
|
||||||
std::vector<fs::path> path_list = {filename};
|
std::vector<fs::path> path_list = {filename};
|
||||||
|
|
||||||
|
|
|
@ -254,11 +254,11 @@ vector_expr* 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::tktrue,
|
tok::id, tok::str, tok::num, tok::tktrue,
|
||||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
tok::tkfalse, tok::opnot, tok::sub, tok::tknil,
|
||||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
tok::func, tok::var, tok::lcurve, tok::floater,
|
||||||
tok::lbrace,tok::lbracket,tok::null
|
tok::lbrace, tok::lbracket, tok::null
|
||||||
};
|
};
|
||||||
auto node = new vector_expr(toks[ptr].loc);
|
auto node = new vector_expr(toks[ptr].loc);
|
||||||
match(tok::lbracket);
|
match(tok::lbracket);
|
||||||
|
@ -713,11 +713,11 @@ call_vector* parse::callv() {
|
||||||
// panic set for this token is not ','
|
// panic set for this token is not ','
|
||||||
// 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::tktrue,
|
tok::id, tok::str, tok::num, tok::tktrue,
|
||||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
tok::tkfalse, tok::opnot, tok::sub, tok::tknil,
|
||||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
tok::func, tok::var, tok::lcurve, tok::floater,
|
||||||
tok::lbrace,tok::lbracket,tok::colon,tok::null
|
tok::lbrace, tok::lbracket, tok::colon, tok::null
|
||||||
};
|
};
|
||||||
auto node = new call_vector(toks[ptr].loc);
|
auto node = new call_vector(toks[ptr].loc);
|
||||||
match(tok::lbracket);
|
match(tok::lbracket);
|
||||||
|
@ -743,11 +743,11 @@ call_function* parse::callf() {
|
||||||
// panic set for this token is not ','
|
// panic set for this token is not ','
|
||||||
// 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::tktrue,
|
tok::id, tok::str,tok::num, tok::tktrue,
|
||||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
tok::tkfalse, tok::opnot, tok::sub, tok::tknil,
|
||||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
tok::func, tok::var, tok::lcurve, tok::floater,
|
||||||
tok::lbrace,tok::lbracket,tok::null
|
tok::lbrace, tok::lbracket, tok::null
|
||||||
};
|
};
|
||||||
auto node = new call_function(toks[ptr].loc);
|
auto node = new call_function(toks[ptr].loc);
|
||||||
bool special_call=check_special_call();
|
bool special_call=check_special_call();
|
||||||
|
@ -802,7 +802,7 @@ expr* parse::definition() {
|
||||||
}
|
}
|
||||||
|
|
||||||
multi_identifier* parse::incurve_def() {
|
multi_identifier* parse::incurve_def() {
|
||||||
const auto& loc=toks[ptr].loc;
|
const auto& loc = toks[ptr].loc;
|
||||||
match(tok::lcurve);
|
match(tok::lcurve);
|
||||||
match(tok::var);
|
match(tok::var);
|
||||||
auto node = multi_id();
|
auto node = multi_id();
|
||||||
|
@ -813,7 +813,7 @@ multi_identifier* parse::incurve_def() {
|
||||||
}
|
}
|
||||||
|
|
||||||
multi_identifier* parse::outcurve_def() {
|
multi_identifier* parse::outcurve_def() {
|
||||||
const auto& loc=toks[ptr].loc;
|
const auto& loc = toks[ptr].loc;
|
||||||
match(tok::lcurve);
|
match(tok::lcurve);
|
||||||
auto node = multi_id();
|
auto node = multi_id();
|
||||||
update_location(node);
|
update_location(node);
|
||||||
|
@ -840,12 +840,13 @@ multi_identifier* parse::multi_id() {
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple_expr* parse::multi_scalar() {
|
tuple_expr* 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,
|
||||||
const tok panic[]={
|
// we will check if value called here can reach a memory space
|
||||||
tok::id,tok::str,tok::num,tok::tktrue,
|
const tok panic[] = {
|
||||||
tok::tkfalse,tok::opnot,tok::sub,tok::tknil,
|
tok::id, tok::str,tok::num, tok::tktrue,
|
||||||
tok::func,tok::var,tok::lcurve,tok::floater,
|
tok::tkfalse, tok::opnot, tok::sub, tok::tknil,
|
||||||
tok::lbrace,tok::lbracket,tok::null
|
tok::func, tok::var, tok::lcurve, tok::floater,
|
||||||
|
tok::lbrace, tok::lbracket, tok::null
|
||||||
};
|
};
|
||||||
auto node = new tuple_expr(toks[ptr].loc);
|
auto node = new tuple_expr(toks[ptr].loc);
|
||||||
match(tok::lcurve);
|
match(tok::lcurve);
|
||||||
|
|
|
@ -98,6 +98,30 @@ std::ostream& operator<<(std::ostream& out, nas_hash& hash) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, nas_func& func) {
|
||||||
|
out << "func(";
|
||||||
|
|
||||||
|
std::vector<std::string> argument_list = {};
|
||||||
|
argument_list.resize(func.keys.size());
|
||||||
|
for(const auto& key : func.keys) {
|
||||||
|
argument_list[key.second-1] = key.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const auto& key : argument_list) {
|
||||||
|
out << key;
|
||||||
|
if (key != argument_list.back()) {
|
||||||
|
out << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (func.dynamic_parameter_index>=0) {
|
||||||
|
out << (argument_list.size()? ", ":"");
|
||||||
|
out << func.dynamic_parameter_name << "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
out << ") {..}";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
void nas_func::clear() {
|
void nas_func::clear() {
|
||||||
dynamic_parameter_index = -1;
|
dynamic_parameter_index = -1;
|
||||||
local.clear();
|
local.clear();
|
||||||
|
@ -256,21 +280,24 @@ std::string var::to_str() {
|
||||||
tmp.erase(tmp.find_last_not_of('.')+1, std::string::npos);
|
tmp.erase(tmp.find_last_not_of('.')+1, std::string::npos);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << *this;
|
||||||
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, var& ref) {
|
std::ostream& operator<<(std::ostream& out, var& ref) {
|
||||||
switch(ref.type) {
|
switch(ref.type) {
|
||||||
case vm_type::vm_none: out << "undefined"; break;
|
case vm_type::vm_none: out << "undefined"; break;
|
||||||
case vm_type::vm_nil: out << "nil"; break;
|
case vm_type::vm_nil: out << "nil"; break;
|
||||||
case vm_type::vm_num: out << ref.val.num; break;
|
case vm_type::vm_num: out << ref.val.num; break;
|
||||||
case vm_type::vm_str: out << ref.str(); break;
|
case vm_type::vm_str: out << ref.str(); break;
|
||||||
case vm_type::vm_vec: out << ref.vec(); break;
|
case vm_type::vm_vec: out << ref.vec(); break;
|
||||||
case vm_type::vm_hash: out << ref.hash(); break;
|
case vm_type::vm_hash: out << ref.hash(); break;
|
||||||
case vm_type::vm_func: out << "func(..) {..}"; break;
|
case vm_type::vm_func: out << ref.func(); break;
|
||||||
case vm_type::vm_ghost: out << ref.ghost(); break;
|
case vm_type::vm_ghost: out << ref.ghost(); break;
|
||||||
case vm_type::vm_co: out << ref.co(); break;
|
case vm_type::vm_co: out << ref.co(); break;
|
||||||
case vm_type::vm_map: out << ref.map(); break;
|
case vm_type::vm_map: out << ref.map(); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
|
|
@ -15,6 +15,7 @@ enum class vm_type: u8 {
|
||||||
vm_ret, // return addres(program counter)
|
vm_ret, // return addres(program counter)
|
||||||
vm_nil, // nil
|
vm_nil, // nil
|
||||||
vm_num, // number
|
vm_num, // number
|
||||||
|
|
||||||
/* gc object */
|
/* gc object */
|
||||||
vm_str, // string
|
vm_str, // string
|
||||||
vm_vec, // vector
|
vm_vec, // vector
|
||||||
|
@ -24,6 +25,7 @@ enum class vm_type: u8 {
|
||||||
vm_ghost, // ghost type
|
vm_ghost, // ghost type
|
||||||
vm_co, // coroutine
|
vm_co, // coroutine
|
||||||
vm_map, // for globals and namespaces
|
vm_map, // for globals and namespaces
|
||||||
|
|
||||||
/* mark type range */
|
/* mark type range */
|
||||||
vm_type_size_max
|
vm_type_size_max
|
||||||
};
|
};
|
||||||
|
@ -153,9 +155,13 @@ struct nas_func {
|
||||||
// parameter table, u32 begins from 1
|
// parameter table, u32 begins from 1
|
||||||
std::unordered_map<std::string, u32> keys;
|
std::unordered_map<std::string, u32> keys;
|
||||||
|
|
||||||
|
// dynamic parameter name
|
||||||
|
std::string dynamic_parameter_name;
|
||||||
|
|
||||||
nas_func():
|
nas_func():
|
||||||
dynamic_parameter_index(-1), entry(0),
|
dynamic_parameter_index(-1), entry(0),
|
||||||
parameter_size(0), local_size(0) {}
|
parameter_size(0), local_size(0),
|
||||||
|
dynamic_parameter_name("") {}
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -277,6 +283,7 @@ struct nas_val {
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream&, nas_vec&);
|
std::ostream& operator<<(std::ostream&, nas_vec&);
|
||||||
std::ostream& operator<<(std::ostream&, nas_hash&);
|
std::ostream& operator<<(std::ostream&, nas_hash&);
|
||||||
|
std::ostream& operator<<(std::ostream&, nas_func&);
|
||||||
std::ostream& operator<<(std::ostream&, nas_map&);
|
std::ostream& operator<<(std::ostream&, nas_map&);
|
||||||
std::ostream& operator<<(std::ostream&, const nas_ghost&);
|
std::ostream& operator<<(std::ostream&, const nas_ghost&);
|
||||||
std::ostream& operator<<(std::ostream&, const nas_co&);
|
std::ostream& operator<<(std::ostream&, const nas_co&);
|
||||||
|
|
|
@ -311,6 +311,7 @@ inline void vm::o_deft() {
|
||||||
|
|
||||||
inline void vm::o_dyn() {
|
inline void vm::o_dyn() {
|
||||||
ctx.top[0].func().dynamic_parameter_index = imm[ctx.pc];
|
ctx.top[0].func().dynamic_parameter_index = imm[ctx.pc];
|
||||||
|
ctx.top[0].func().dynamic_parameter_name = const_string[imm[ctx.pc]];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void vm::o_lnot() {
|
inline void vm::o_lnot() {
|
||||||
|
|
Loading…
Reference in New Issue