Merge pull request #29 from ValKmjolnir/develop
⚡ improve codegen and repl output
This commit is contained in:
commit
982c5750ef
|
@ -83,16 +83,16 @@ public:
|
|||
noecho_input this_window;
|
||||
|
||||
var nas_getch(var* args, usize size, gc* ngc) {
|
||||
return var::num((double)this_window.noecho_getch());
|
||||
return var::num(static_cast<double>(this_window.noecho_getch()));
|
||||
}
|
||||
|
||||
var nas_kbhit(var* args, usize size, gc* ngc) {
|
||||
return var::num((double)this_window.noecho_kbhit());
|
||||
return var::num(static_cast<double>(this_window.noecho_kbhit()));
|
||||
}
|
||||
|
||||
var nas_noblock(var* args, usize size, gc* ngc) {
|
||||
if (this_window.noecho_kbhit()) {
|
||||
return var::num((double)this_window.noecho_getch());
|
||||
return var::num(static_cast<double>(this_window.noecho_getch()));
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
|
|
@ -34,16 +34,16 @@ var nas_socket(var* args, usize size, gc* ngc) {
|
|||
if (args[0].type!=vm_num || args[1].type!=vm_num || args[2].type!=vm_num)
|
||||
return nas_err("socket", "\"af\", \"type\", \"protocol\" should be number");
|
||||
int sd = socket(args[0].num(), args[1].num(), args[2].num());
|
||||
return var::num((double)sd);
|
||||
return var::num(static_cast<double>(sd));
|
||||
}
|
||||
|
||||
var nas_closesocket(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_num)
|
||||
return nas_err("closesocket", "\"sd\" should be number");
|
||||
#ifdef _WIN32
|
||||
return var::num((double)closesocket(args[0].num()));
|
||||
return var::num(static_cast<double>(closesocket(args[0].num())));
|
||||
#else
|
||||
return var::num((double)close(args[0].num()));
|
||||
return var::num(static_cast<double>(close(args[0].num())));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ var nas_shutdown(var* args, usize size, gc* ngc) {
|
|||
return nas_err("shutdown", "\"sd\" must be a number");
|
||||
if (args[1].type!=vm_num)
|
||||
return nas_err("shutdown", "\"how\" must be a number");
|
||||
return var::num((double)shutdown(args[0].num(), args[1].num()));
|
||||
return var::num(static_cast<double>(shutdown(args[0].num(), args[1].num())));
|
||||
}
|
||||
|
||||
var nas_bind(var* args, usize size, gc* ngc) {
|
||||
|
@ -67,7 +67,11 @@ var nas_bind(var* args, usize size, gc* ngc) {
|
|||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = inet_addr(args[1].str().c_str());
|
||||
server.sin_port = htons(args[2].num());
|
||||
return var::num((double)bind(args[0].num(), (sockaddr*)&server, sizeof(server)));
|
||||
return var::num(static_cast<double>(bind(
|
||||
args[0].num(),
|
||||
(sockaddr*)&server,
|
||||
sizeof(server)
|
||||
)));
|
||||
}
|
||||
|
||||
var nas_listen(var* args, usize size, gc* ngc) {
|
||||
|
@ -75,7 +79,7 @@ var nas_listen(var* args, usize size, gc* ngc) {
|
|||
return nas_err("listen", "\"sd\" must be a number");
|
||||
if (args[1].type!=vm_num)
|
||||
return nas_err("listen", "\"backlog\" must be a number");
|
||||
return var::num((double)listen(args[0].num(), args[1].num()));
|
||||
return var::num(static_cast<double>(listen(args[0].num(), args[1].num())));
|
||||
}
|
||||
|
||||
var nas_connect(var* args, usize size, gc* ngc) {
|
||||
|
@ -91,11 +95,11 @@ var nas_connect(var* args, usize size, gc* ngc) {
|
|||
addr.sin_port = htons(args[2].num());
|
||||
hostent* entry = gethostbyname(args[1].str().c_str());
|
||||
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
||||
return var::num((double)connect(
|
||||
return var::num(static_cast<double>(connect(
|
||||
args[0].num(),
|
||||
(sockaddr*)&addr,
|
||||
sizeof(sockaddr_in)
|
||||
));
|
||||
)));
|
||||
}
|
||||
|
||||
var nas_accept(var* args, usize size, gc* ngc) {
|
||||
|
@ -110,7 +114,7 @@ var nas_accept(var* args, usize size, gc* ngc) {
|
|||
#endif
|
||||
var res=ngc->temp = ngc->alloc(vm_hash);
|
||||
auto& hash = res.hash().elems;
|
||||
hash["sd"] = var::num((double)client_sd);
|
||||
hash["sd"] = var::num(static_cast<double>(client_sd));
|
||||
hash["ip"] = ngc->newstr(inet_ntoa(client.sin_addr));
|
||||
ngc->temp = nil;
|
||||
return res;
|
||||
|
@ -123,12 +127,12 @@ var nas_send(var* args, usize size, gc* ngc) {
|
|||
return nas_err("send", "\"buff\" must be a string");
|
||||
if (args[2].type!=vm_num)
|
||||
return nas_err("send", "\"flags\" muse be a number");
|
||||
return var::num((double)send(
|
||||
return var::num(static_cast<double>(send(
|
||||
args[0].num(),
|
||||
args[1].str().c_str(),
|
||||
args[1].str().length(),
|
||||
args[2].num()
|
||||
));
|
||||
)));
|
||||
}
|
||||
|
||||
var nas_sendto(var* args, usize size, gc* ngc) {
|
||||
|
@ -148,14 +152,14 @@ var nas_sendto(var* args, usize size, gc* ngc) {
|
|||
addr.sin_port = htons(args[2].num());
|
||||
hostent* entry = gethostbyname(args[1].str().c_str());
|
||||
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
||||
return var::num((double)sendto(
|
||||
return var::num(static_cast<double>(sendto(
|
||||
args[0].num(),
|
||||
args[3].str().c_str(),
|
||||
args[3].str().length(),
|
||||
args[4].num(),
|
||||
(sockaddr*)&addr,
|
||||
sizeof(sockaddr_in)
|
||||
));
|
||||
)));
|
||||
}
|
||||
|
||||
var nas_recv(var* args, usize size, gc* ngc) {
|
||||
|
@ -169,9 +173,9 @@ var nas_recv(var* args, usize size, gc* ngc) {
|
|||
return nas_err("recv", "\"flags\" muse be a number");
|
||||
var res = ngc->temp = ngc->alloc(vm_hash);
|
||||
auto& hash = res.hash().elems;
|
||||
char* buf = new char[(int)args[1].num()];
|
||||
char* buf = new char[static_cast<int>(args[1].num())];
|
||||
auto recvsize = recv(args[0].num(), buf,args[1].num(), args[2].num());
|
||||
hash["size"] = var::num((double)recvsize);
|
||||
hash["size"] = var::num(static_cast<double>(recvsize));
|
||||
buf[recvsize>=0? recvsize:0] = 0;
|
||||
hash["str"] = ngc->newstr(buf);
|
||||
delete[] buf;
|
||||
|
@ -192,7 +196,7 @@ var nas_recvfrom(var* args, usize size, gc* ngc) {
|
|||
int socklen = sizeof(sockaddr_in);
|
||||
var res = ngc->temp = ngc->alloc(vm_hash);
|
||||
auto& hash = res.hash().elems;
|
||||
char* buf = new char[(int)args[1].num()+1];
|
||||
char* buf = new char[static_cast<int>(args[1].num()+1)];
|
||||
#ifdef _WIN32
|
||||
auto recvsize = recvfrom(
|
||||
args[0].num(),
|
||||
|
@ -212,7 +216,7 @@ var nas_recvfrom(var* args, usize size, gc* ngc) {
|
|||
(socklen_t*)&socklen
|
||||
);
|
||||
#endif
|
||||
hash["size"] = var::num((double)recvsize);
|
||||
hash["size"] = var::num(static_cast<double>(recvsize));
|
||||
buf[recvsize>=0? recvsize:0] = 0;
|
||||
hash["str"] = ngc->newstr(buf);
|
||||
delete[] buf;
|
||||
|
|
|
@ -139,7 +139,7 @@ void execute(
|
|||
}
|
||||
|
||||
// code generator gets parser's ast and import file list to generate code
|
||||
gen.compile(parse, ld).chkerr();
|
||||
gen.compile(parse, ld, false).chkerr();
|
||||
if (cmd&VM_CODE) {
|
||||
gen.print(std::cout);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ protected:
|
|||
public:
|
||||
expr(const span& location, expr_type node_type):
|
||||
nd_loc(location), nd_type(node_type) {}
|
||||
~expr() = default;
|
||||
virtual ~expr() = default;
|
||||
void set_begin(u32 line, u32 column) {
|
||||
nd_loc.begin_line = line;
|
||||
nd_loc.begin_column = column;
|
||||
|
@ -81,7 +81,7 @@ class call:public expr {
|
|||
public:
|
||||
call(const span& location, expr_type node_type):
|
||||
expr(location, node_type) {}
|
||||
~call() = default;
|
||||
virtual ~call() = default;
|
||||
virtual void accept(ast_visitor*);
|
||||
};
|
||||
|
||||
|
@ -89,7 +89,7 @@ class null_expr:public expr {
|
|||
public:
|
||||
null_expr(const span& location):
|
||||
expr(location, expr_type::ast_null) {}
|
||||
~null_expr() = default;
|
||||
~null_expr() override = default;
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -97,7 +97,7 @@ class nil_expr:public expr {
|
|||
public:
|
||||
nil_expr(const span& location):
|
||||
expr(location, expr_type::ast_nil) {}
|
||||
~nil_expr() = default;
|
||||
~nil_expr() override = default;
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -108,7 +108,7 @@ private:
|
|||
public:
|
||||
number_literal(const span& location, const f64 num):
|
||||
expr(location, expr_type::ast_num), number(num) {}
|
||||
~number_literal() = default;
|
||||
~number_literal() override = default;
|
||||
f64 get_number() const {return number;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
@ -120,7 +120,7 @@ private:
|
|||
public:
|
||||
string_literal(const span& location, const std::string& str):
|
||||
expr(location, expr_type::ast_str), content(str) {}
|
||||
~string_literal() = default;
|
||||
~string_literal() override = default;
|
||||
const std::string get_content() const {return content;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
@ -132,8 +132,8 @@ private:
|
|||
public:
|
||||
identifier(const span& location, const std::string& str):
|
||||
expr(location, expr_type::ast_id), name(str) {}
|
||||
~identifier() = default;
|
||||
const std::string get_name() const {return name;}
|
||||
~identifier() override = default;
|
||||
const std::string& get_name() const {return name;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -144,7 +144,7 @@ private:
|
|||
public:
|
||||
bool_literal(const span& location, const bool bool_flag):
|
||||
expr(location, expr_type::ast_bool), flag(bool_flag) {}
|
||||
~bool_literal() = default;
|
||||
~bool_literal() override = default;
|
||||
bool get_flag() const {return flag;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
@ -156,7 +156,7 @@ private:
|
|||
public:
|
||||
vector_expr(const span& location):
|
||||
expr(location, expr_type::ast_vec) {}
|
||||
~vector_expr();
|
||||
~vector_expr() override;
|
||||
void add_element(expr* node) {elements.push_back(node);}
|
||||
std::vector<expr*>& get_elements() {return elements;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
@ -169,7 +169,7 @@ private:
|
|||
public:
|
||||
hash_expr(const span& location):
|
||||
expr(location, expr_type::ast_hash) {}
|
||||
~hash_expr();
|
||||
~hash_expr() override;
|
||||
void add_member(hash_pair* node) {members.push_back(node);}
|
||||
std::vector<hash_pair*>& get_members() {return members;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
@ -184,7 +184,7 @@ public:
|
|||
hash_pair(const span& location):
|
||||
expr(location, expr_type::ast_pair),
|
||||
value(nullptr) {}
|
||||
~hash_pair();
|
||||
~hash_pair() override;
|
||||
void set_name(const std::string& field_name) {name = field_name;}
|
||||
void set_value(expr* node) {value = node;}
|
||||
const std::string& get_name() const {return name;}
|
||||
|
@ -201,7 +201,7 @@ public:
|
|||
function(const span& location):
|
||||
expr(location, expr_type::ast_func),
|
||||
block(nullptr) {}
|
||||
~function();
|
||||
~function() override;
|
||||
void add_parameter(parameter* node) {parameter_list.push_back(node);}
|
||||
void set_code_block(code_block* node) {block = node;}
|
||||
std::vector<parameter*>& get_parameter_list() {return parameter_list;}
|
||||
|
@ -216,7 +216,7 @@ private:
|
|||
public:
|
||||
code_block(const span& location):
|
||||
expr(location, expr_type::ast_block) {}
|
||||
~code_block();
|
||||
~code_block() override;
|
||||
void add_expression(expr* node) {expressions.push_back(node);}
|
||||
std::vector<expr*>& get_expressions() {return expressions;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
@ -239,7 +239,7 @@ public:
|
|||
parameter(const span& location):
|
||||
expr(location, expr_type::ast_param),
|
||||
name(""), default_value(nullptr) {}
|
||||
~parameter();
|
||||
~parameter() override;
|
||||
void set_parameter_type(param_type pt) {type = pt;}
|
||||
void set_parameter_name(const std::string& pname) {name = pname;}
|
||||
void set_default_value(expr* node) {default_value = node;}
|
||||
|
@ -259,7 +259,7 @@ public:
|
|||
ternary_operator(const span& location):
|
||||
expr(location, expr_type::ast_ternary),
|
||||
condition(nullptr), left(nullptr), right(nullptr) {}
|
||||
~ternary_operator();
|
||||
~ternary_operator() override;
|
||||
void set_condition(expr* node) {condition = node;}
|
||||
void set_left(expr* node) {left = node;}
|
||||
void set_right(expr* node) {right = node;}
|
||||
|
@ -303,7 +303,7 @@ public:
|
|||
left(nullptr), right(nullptr),
|
||||
optimized_const_number(nullptr),
|
||||
optimized_const_string(nullptr) {}
|
||||
~binary_operator();
|
||||
~binary_operator() override;
|
||||
void set_operator_type(binary_type operator_type) {type = operator_type;}
|
||||
void set_left(expr* node) {left = node;}
|
||||
void set_right(expr* node) {right = node;}
|
||||
|
@ -334,7 +334,7 @@ public:
|
|||
unary_operator(const span& location):
|
||||
expr(location, expr_type::ast_unary),
|
||||
value(nullptr), optimized_number(nullptr) {}
|
||||
~unary_operator();
|
||||
~unary_operator() override;
|
||||
void set_operator_type(unary_type operator_type) {type = operator_type;}
|
||||
void set_value(expr* node) {value = node;}
|
||||
void set_optimized_number(number_literal* node) {optimized_number = node;}
|
||||
|
@ -353,7 +353,7 @@ public:
|
|||
call_expr(const span& location):
|
||||
expr(location, expr_type::ast_call),
|
||||
first(nullptr) {}
|
||||
~call_expr();
|
||||
~call_expr() override;
|
||||
void set_first(expr* node) {first = node;}
|
||||
void add_call(call* node) {calls.push_back(node);}
|
||||
expr* get_first() {return first;}
|
||||
|
@ -369,7 +369,7 @@ public:
|
|||
call_hash(const span& location, const std::string& name):
|
||||
call(location, expr_type::ast_callh),
|
||||
field(name) {}
|
||||
~call_hash() = default;
|
||||
~call_hash() override = default;
|
||||
const std::string& get_field() const {return field;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
@ -381,7 +381,7 @@ private:
|
|||
public:
|
||||
call_vector(const span& location):
|
||||
call(location, expr_type::ast_callv) {}
|
||||
~call_vector();
|
||||
~call_vector() override;
|
||||
void add_slice(slice_vector* node) {calls.push_back(node);}
|
||||
std::vector<slice_vector*>& get_slices() {return calls;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
@ -394,7 +394,7 @@ private:
|
|||
public:
|
||||
call_function(const span& location):
|
||||
call(location, expr_type::ast_callf) {}
|
||||
~call_function();
|
||||
~call_function() override;
|
||||
void add_argument(expr* node) {args.push_back(node);}
|
||||
std::vector<expr*>& get_argument() {return args;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
@ -409,7 +409,7 @@ public:
|
|||
slice_vector(const span& location):
|
||||
expr(location, expr_type::ast_subvec),
|
||||
begin(nullptr), end(nullptr) {}
|
||||
~slice_vector();
|
||||
~slice_vector() override;
|
||||
void set_begin(expr* node) {begin = node;}
|
||||
void set_end(expr* node) {end = node;}
|
||||
expr* get_begin() {return begin;}
|
||||
|
@ -429,7 +429,7 @@ public:
|
|||
expr(location, expr_type::ast_def),
|
||||
variable_name(nullptr), variables(nullptr),
|
||||
tuple(nullptr), value(nullptr) {}
|
||||
~definition_expr();
|
||||
~definition_expr() override;
|
||||
void set_identifier(identifier* node) {variable_name = node;}
|
||||
void set_multi_define(multi_identifier* node) {variables = node;}
|
||||
void set_tuple(tuple_expr* node) {tuple = node;}
|
||||
|
@ -464,7 +464,7 @@ public:
|
|||
assignment_expr(const span& location):
|
||||
expr(location, expr_type::ast_assign),
|
||||
left(nullptr), right(nullptr) {}
|
||||
~assignment_expr();
|
||||
~assignment_expr() override;
|
||||
void set_assignment_type(assign_type operator_type) {type = operator_type;}
|
||||
void set_left(expr* node) {left = node;}
|
||||
void set_right(expr* node) {right = node;}
|
||||
|
@ -481,7 +481,7 @@ private:
|
|||
public:
|
||||
multi_identifier(const span& location):
|
||||
expr(location, expr_type::ast_multi_id) {}
|
||||
~multi_identifier();
|
||||
~multi_identifier() override;
|
||||
void add_var(identifier* node) {variables.push_back(node);}
|
||||
std::vector<identifier*>& get_variables() {return variables;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
@ -494,7 +494,7 @@ private:
|
|||
public:
|
||||
tuple_expr(const span& location):
|
||||
expr(location, expr_type::ast_tuple) {}
|
||||
~tuple_expr();
|
||||
~tuple_expr() override;
|
||||
void add_element(expr* node) {elements.push_back(node);}
|
||||
std::vector<expr*>& get_elements() {return elements;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
@ -509,7 +509,7 @@ public:
|
|||
multi_assign(const span& location):
|
||||
expr(location, expr_type::ast_multi_assign),
|
||||
tuple(nullptr), value(nullptr) {}
|
||||
~multi_assign();
|
||||
~multi_assign() override;
|
||||
void set_tuple(tuple_expr* node) {tuple = node;}
|
||||
void set_value(expr* node) {value = node;}
|
||||
tuple_expr* get_tuple() {return tuple;}
|
||||
|
@ -526,7 +526,7 @@ public:
|
|||
while_expr(const span& location):
|
||||
expr(location, expr_type::ast_while),
|
||||
condition(nullptr), block(nullptr) {}
|
||||
~while_expr();
|
||||
~while_expr() override;
|
||||
void set_condition(expr* node) {condition = node;}
|
||||
void set_code_block (code_block* node) {block = node;}
|
||||
expr* get_condition() {return condition;}
|
||||
|
@ -546,7 +546,7 @@ public:
|
|||
expr(location, expr_type::ast_for),
|
||||
initializing(nullptr), condition(nullptr),
|
||||
step(nullptr), block(nullptr) {}
|
||||
~for_expr();
|
||||
~for_expr() override;
|
||||
void set_initial(expr* node) {initializing = node;}
|
||||
void set_condition(expr* node) {condition = node;}
|
||||
void set_step(expr* node) {step = node;}
|
||||
|
@ -567,7 +567,7 @@ public:
|
|||
iter_expr(const span& location):
|
||||
expr(location, expr_type::ast_iter),
|
||||
name(nullptr), call(nullptr) {}
|
||||
~iter_expr();
|
||||
~iter_expr() override;
|
||||
void set_name(identifier* node) {name = node;}
|
||||
void set_call(call_expr* node) {call = node;}
|
||||
identifier* get_name() {return name;}
|
||||
|
@ -593,7 +593,7 @@ public:
|
|||
expr(location, expr_type::ast_forei),
|
||||
type(forei_loop_type::foreach), iterator(nullptr),
|
||||
vector_node(nullptr), block(nullptr) {}
|
||||
~forei_expr();
|
||||
~forei_expr() override;
|
||||
void set_loop_type(forei_loop_type ft) {type = ft;}
|
||||
void set_iterator(iter_expr* node) {iterator = node;}
|
||||
void set_value(expr* node) {vector_node = node;}
|
||||
|
@ -615,7 +615,7 @@ public:
|
|||
condition_expr(const span& location):
|
||||
expr(location, expr_type::ast_cond),
|
||||
if_stmt(nullptr), else_stmt(nullptr) {}
|
||||
~condition_expr();
|
||||
~condition_expr() override;
|
||||
void set_if_statement(if_expr* node) {if_stmt = node;}
|
||||
void add_elsif_statement(if_expr* node) {elsif_stmt.push_back(node);}
|
||||
void set_else_statement(if_expr* node) {else_stmt = node;}
|
||||
|
@ -634,7 +634,7 @@ public:
|
|||
if_expr(const span& location):
|
||||
expr(location, expr_type::ast_if),
|
||||
condition(nullptr), block(nullptr) {}
|
||||
~if_expr();
|
||||
~if_expr() override;
|
||||
void set_condition(expr* node) {condition = node;}
|
||||
void set_code_block(code_block* node) {block = node;}
|
||||
expr* get_condition() {return condition;}
|
||||
|
@ -646,7 +646,7 @@ class continue_expr:public expr {
|
|||
public:
|
||||
continue_expr(const span& location):
|
||||
expr(location, expr_type::ast_continue) {}
|
||||
~continue_expr() = default;
|
||||
~continue_expr() override = default;
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -666,7 +666,7 @@ public:
|
|||
return_expr(const span& location):
|
||||
expr(location, expr_type::ast_ret),
|
||||
value(nullptr) {}
|
||||
~return_expr();
|
||||
~return_expr() override;
|
||||
void set_value(expr* node) {value = node;}
|
||||
expr* get_value() {return value;}
|
||||
void accept(ast_visitor*) override;
|
||||
|
|
|
@ -307,7 +307,9 @@ var builtin_substr(var* local, gc& ngc) {
|
|||
var builtin_streq(var* local, gc& ngc) {
|
||||
var a = local[1];
|
||||
var b = local[2];
|
||||
return var::num(f64((a.type!=vm_str || b.type!=vm_str)? 0:(a.str()==b.str())));
|
||||
return var::num(static_cast<f64>(
|
||||
(a.type!=vm_str || b.type!=vm_str)? 0:(a.str()==b.str())
|
||||
));
|
||||
}
|
||||
|
||||
var builtin_left(var* local, gc& ngc) {
|
||||
|
@ -410,9 +412,11 @@ var builtin_sleep(var* local, gc& ngc) {
|
|||
#if defined(_WIN32) && !defined(_GLIBCXX_HAS_GTHREADS)
|
||||
// mingw-w64 win32 thread model has no std::this_thread
|
||||
// also msvc will use this
|
||||
Sleep(i64(val.num()*1e3));
|
||||
Sleep(static_cast<i64>(val.num()*1e3));
|
||||
#else
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(i64(val.num()*1e6)));
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::microseconds(static_cast<i64>(val.num()*1e6))
|
||||
);
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
|
@ -469,7 +473,7 @@ std::string md5(const std::string& src) {
|
|||
usize buffsize = num<<4;
|
||||
buff.resize(buffsize,0);
|
||||
for(usize i = 0; i<src.length(); i++) {
|
||||
buff[i>>2] |= ((u8)src[i])<<((i&0x3)<<3);
|
||||
buff[i>>2] |= (static_cast<u8>(src[i]))<<((i&0x3)<<3);
|
||||
}
|
||||
buff[src.length()>>2] |= 0x80<<(((src.length()%4))<<3);
|
||||
buff[buffsize-2] = (src.length()<<3)&0xffffffff;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,9 @@ class codegen {
|
|||
private:
|
||||
error err;
|
||||
|
||||
//
|
||||
bool need_repl_output;
|
||||
|
||||
// file mapper for file -> index
|
||||
std::unordered_map<std::string, usize> file_map;
|
||||
void init_file_map(const std::vector<std::string>&);
|
||||
|
@ -79,11 +82,11 @@ private:
|
|||
void regist_str(const std::string&);
|
||||
void find_symbol(code_block*);
|
||||
void add_symbol(const std::string&);
|
||||
i32 local_find(const std::string&);
|
||||
i32 global_find(const std::string&);
|
||||
i32 upvalue_find(const std::string&);
|
||||
i32 local_symbol_find(const std::string&);
|
||||
i32 global_symbol_find(const std::string&);
|
||||
i32 upvalue_symbol_find(const std::string&);
|
||||
|
||||
void gen(u8, u32, const span&);
|
||||
void emit(u8, u32, const span&);
|
||||
|
||||
void num_gen(number_literal*);
|
||||
void str_gen(string_literal*);
|
||||
|
@ -104,6 +107,8 @@ private:
|
|||
void single_def(definition_expr*);
|
||||
void def_gen(definition_expr*);
|
||||
void assignment_expression(assignment_expr*);
|
||||
void gen_assignment_equal_statement(assignment_expr*);
|
||||
void replace_left_assignment_with_load(const span&);
|
||||
void assignment_statement(assignment_expr*);
|
||||
void multi_assign_gen(multi_assign*);
|
||||
void cond_gen(condition_expr*);
|
||||
|
@ -119,6 +124,7 @@ private:
|
|||
void binary_gen(binary_operator*);
|
||||
void trino_gen(ternary_operator*);
|
||||
void calc_gen(expr*);
|
||||
void repl_mode_info_output_gen(expr*);
|
||||
void block_gen(code_block*);
|
||||
void ret_gen(return_expr*);
|
||||
|
||||
|
@ -134,7 +140,7 @@ public:
|
|||
|
||||
public:
|
||||
codegen() = default;
|
||||
const error& compile(parse&, linker&);
|
||||
const error& compile(parse&, linker&, bool);
|
||||
void print(std::ostream&);
|
||||
void symbol_dump(std::ostream&) const;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@ class dbg:public vm {
|
|||
private:
|
||||
typedef void (dbg::*nasal_vm_func)();
|
||||
const nasal_vm_func operand_function[op_ret + 1] = {
|
||||
nullptr, &dbg::o_intg,
|
||||
nullptr, &dbg::o_repl,
|
||||
&dbg::o_intl, &dbg::o_loadg,
|
||||
&dbg::o_loadl, &dbg::o_loadu,
|
||||
&dbg::o_pnum, &dbg::o_pnil,
|
||||
|
|
|
@ -536,7 +536,9 @@ void gc::extend(u8 type) {
|
|||
}
|
||||
|
||||
void gc::init(
|
||||
const std::vector<std::string>& s, const std::vector<std::string>& argv) {
|
||||
const std::vector<std::string>& constant_strings,
|
||||
const std::vector<std::string>& argv
|
||||
) {
|
||||
// initialize counters
|
||||
worktime = 0;
|
||||
for(u8 i = 0; i<gc_type_size; ++i) {
|
||||
|
@ -547,16 +549,24 @@ void gc::init(
|
|||
cort = nullptr;
|
||||
|
||||
// init constant strings
|
||||
strs.resize(s.size());
|
||||
strs.resize(constant_strings.size());
|
||||
for(u32 i = 0; i<strs.size(); ++i) {
|
||||
// incremental initialization, avoid memory leak in repl mode
|
||||
if (strs[i].type==vm_str && strs[i].str()==constant_strings[i]) {
|
||||
continue;
|
||||
}
|
||||
strs[i] = var::gcobj(new nas_val(vm_str));
|
||||
strs[i].val.gcobj->unmut = 1;
|
||||
strs[i].str() = s[i];
|
||||
strs[i].str() = constant_strings[i];
|
||||
}
|
||||
|
||||
// record arguments
|
||||
env_argv.resize(argv.size());
|
||||
for(usize i = 0; i<argv.size(); ++i) {
|
||||
// incremental initialization, avoid memory leak in repl mode
|
||||
if (env_argv[i].type==vm_str && env_argv[i].str()==argv[i]) {
|
||||
continue;
|
||||
}
|
||||
env_argv[i] = var::gcobj(new nas_val(vm_str));
|
||||
env_argv[i].val.gcobj->unmut = 1;
|
||||
env_argv[i].str() = argv[i];
|
||||
|
|
|
@ -66,7 +66,7 @@ struct nas_val; // nas_val includes gc-managed types
|
|||
|
||||
struct var {
|
||||
public:
|
||||
u8 type;
|
||||
u8 type = vm_none;
|
||||
union {
|
||||
u32 ret;
|
||||
i64 cnt;
|
||||
|
|
|
@ -183,7 +183,7 @@ f64 str2num(const char* str) {
|
|||
|
||||
i32 utf8_hdchk(const char head) {
|
||||
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4
|
||||
const u8 c = (u8)head;
|
||||
const auto c = static_cast<u8>(head);
|
||||
if ((c>>5)==0x06) { // 110x xxxx (10xx xxxx)^1
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace nasal {
|
||||
|
||||
const char* opname[] = {
|
||||
"exit ", "intg ", "intl ", "loadg ",
|
||||
"exit ", "repl ", "intl ", "loadg ",
|
||||
"loadl ", "loadu ", "pnum ", "pnil ",
|
||||
"pstr ", "newv ", "newh ", "newf ",
|
||||
"happ ", "para ", "def ", "dyn ",
|
||||
|
@ -81,7 +81,7 @@ void codestream::dump(std::ostream& out) const {
|
|||
out << hex << "0x" << num << dec
|
||||
<< " (" << nums[num] << ")"; break;
|
||||
case op_callvi: case op_newv:
|
||||
case op_callfv: case op_intg:
|
||||
case op_callfv: case op_repl:
|
||||
case op_intl: case op_findex:
|
||||
case op_feach: case op_newf:
|
||||
case op_jmp: case op_jt:
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace nasal {
|
|||
|
||||
enum op_code_type:u8 {
|
||||
op_exit, // stop the virtual machine
|
||||
op_intg, // init global scope
|
||||
op_repl, // in repl mode: print value on stack top
|
||||
op_intl, // local scope size
|
||||
op_loadg, // load global value
|
||||
op_loadl, // load local value
|
||||
|
|
|
@ -150,11 +150,7 @@ public:
|
|||
|
||||
public:
|
||||
parse(): ptr(0), in_func(0), in_loop(0), toks(nullptr), root(nullptr) {}
|
||||
~parse() {
|
||||
if (root) {
|
||||
delete root;
|
||||
}
|
||||
}
|
||||
~parse() {delete root;}
|
||||
const error& compile(const lexer&);
|
||||
static void easter_egg();
|
||||
};
|
||||
|
|
|
@ -55,7 +55,7 @@ void vm::context_and_global_init() {
|
|||
ctx.canary = ctx.stack+STACK_DEPTH-1;
|
||||
|
||||
/* nothing is on stack */
|
||||
ctx.top = ctx.stack;
|
||||
ctx.top = ctx.stack - 1;
|
||||
|
||||
/* clear main stack and global */
|
||||
for(u32 i = 0; i<STACK_DEPTH; ++i) {
|
||||
|
@ -259,7 +259,7 @@ void vm::run(
|
|||
#ifndef _MSC_VER
|
||||
// using labels as values/computed goto
|
||||
const void* oprs[] = {
|
||||
&&vmexit, &&intg, &&intl, &&loadg,
|
||||
&&vmexit, &&repl, &&intl, &&loadg,
|
||||
&&loadl, &&loadu, &&pnum, &&pnil,
|
||||
&&pstr, &&newv, &&newh, &&newf,
|
||||
&&happ, &¶, &&deft, &&dyn,
|
||||
|
@ -292,7 +292,7 @@ void vm::run(
|
|||
#else
|
||||
typedef void (vm::*nafunc)();
|
||||
const nafunc oprs[] = {
|
||||
nullptr, &vm::o_intg,
|
||||
nullptr, &vm::o_repl,
|
||||
&vm::o_intl, &vm::o_loadg,
|
||||
&vm::o_loadl, &vm::o_loadu,
|
||||
&vm::o_pnum, &vm::o_pnil,
|
||||
|
@ -376,7 +376,7 @@ vmexit:
|
|||
goto *code[++ctx.pc];\
|
||||
}
|
||||
|
||||
intg: exec_nodie(o_intg ); // +imm[pc] (detected at codegen)
|
||||
repl: exec_nodie(o_repl ); // 0
|
||||
intl: exec_nodie(o_intl ); // -0
|
||||
loadg: exec_nodie(o_loadg ); // -1
|
||||
loadl: exec_nodie(o_loadl ); // -1
|
||||
|
|
|
@ -41,6 +41,7 @@ protected:
|
|||
/* variables for repl mode */
|
||||
bool is_repl_mode = false;
|
||||
bool first_exec_flag = true;
|
||||
bool allow_repl_output = false;
|
||||
|
||||
/* vm initializing function */
|
||||
void init(
|
||||
|
@ -70,7 +71,7 @@ protected:
|
|||
inline bool cond(var&);
|
||||
|
||||
/* vm operands */
|
||||
inline void o_intg();
|
||||
inline void o_repl();
|
||||
inline void o_intl();
|
||||
inline void o_loadg();
|
||||
inline void o_loadl();
|
||||
|
@ -180,6 +181,8 @@ public:
|
|||
void set_detail_report_info(bool flag) {verbose = flag;}
|
||||
/* set repl mode flag */
|
||||
void set_repl_mode_flag(bool flag) {is_repl_mode = flag;}
|
||||
/* set repl output flag */
|
||||
void set_allow_repl_output_flag(bool flag) {allow_repl_output = flag;}
|
||||
};
|
||||
|
||||
inline bool vm::cond(var& val) {
|
||||
|
@ -192,11 +195,11 @@ inline bool vm::cond(var& val) {
|
|||
return false;
|
||||
}
|
||||
|
||||
inline void vm::o_intg() {
|
||||
// global values store on stack
|
||||
// ctx.top += imm[ctx.pc];
|
||||
// point to the top
|
||||
--ctx.top;
|
||||
inline void vm::o_repl() {
|
||||
// reserved for repl mode stack top value output
|
||||
if (allow_repl_output) {
|
||||
std::cout << ctx.top[0] << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
inline void vm::o_intl() {
|
||||
|
@ -301,9 +304,7 @@ inline void vm::o_lnot() {
|
|||
ctx.top[0] = num? zero:one;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
die("incorrect value type");
|
||||
return;
|
||||
default: die("incorrect value type"); return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,22 +318,25 @@ inline void vm::o_bnot() {
|
|||
|
||||
inline void vm::o_btor() {
|
||||
ctx.top[-1] = var::num(
|
||||
static_cast<int32_t>(ctx.top[-1].tonum())|
|
||||
static_cast<int32_t>(ctx.top[0].tonum()));
|
||||
static_cast<i32>(ctx.top[-1].tonum())|
|
||||
static_cast<i32>(ctx.top[0].tonum())
|
||||
);
|
||||
--ctx.top;
|
||||
}
|
||||
|
||||
inline void vm::o_btxor() {
|
||||
ctx.top[-1] = var::num(
|
||||
static_cast<int32_t>(ctx.top[-1].tonum())^
|
||||
static_cast<int32_t>(ctx.top[0].tonum()));
|
||||
static_cast<i32>(ctx.top[-1].tonum())^
|
||||
static_cast<i32>(ctx.top[0].tonum())
|
||||
);
|
||||
--ctx.top;
|
||||
}
|
||||
|
||||
inline void vm::o_btand() {
|
||||
ctx.top[-1] = var::num(
|
||||
static_cast<int32_t>(ctx.top[-1].tonum())&
|
||||
static_cast<int32_t>(ctx.top[0].tonum()));
|
||||
static_cast<i32>(ctx.top[-1].tonum())&
|
||||
static_cast<i32>(ctx.top[0].tonum())
|
||||
);
|
||||
--ctx.top;
|
||||
}
|
||||
|
||||
|
@ -388,25 +392,36 @@ inline void vm::o_subeq() {op_calc_eq(-);}
|
|||
inline void vm::o_muleq() {op_calc_eq(*);}
|
||||
inline void vm::o_diveq() {op_calc_eq(/);}
|
||||
inline void vm::o_lnkeq() {
|
||||
ctx.top[-1] = ctx.memr[0] = ngc.newstr(ctx.memr[0].tostr()+ctx.top[-1].tostr());
|
||||
ctx.top[-1] = ctx.memr[0] = ngc.newstr(
|
||||
ctx.memr[0].tostr()+ctx.top[-1].tostr()
|
||||
);
|
||||
ctx.memr = nullptr;
|
||||
ctx.top -= imm[ctx.pc]+1;
|
||||
}
|
||||
|
||||
inline void vm::o_bandeq() {
|
||||
ctx.top[-1] = ctx.memr[0] = var::num(i32(ctx.memr[0].tonum())&i32(ctx.top[-1].tonum()));
|
||||
ctx.top[-1] = ctx.memr[0] = var::num(
|
||||
static_cast<i32>(ctx.memr[0].tonum())&
|
||||
static_cast<i32>(ctx.top[-1].tonum())
|
||||
);
|
||||
ctx.memr = nullptr;
|
||||
ctx.top -= imm[ctx.pc]+1;
|
||||
}
|
||||
|
||||
inline void vm::o_boreq() {
|
||||
ctx.top[-1] = ctx.memr[0] = var::num(i32(ctx.memr[0].tonum())|i32(ctx.top[-1].tonum()));
|
||||
ctx.top[-1] = ctx.memr[0] = var::num(
|
||||
static_cast<i32>(ctx.memr[0].tonum())|
|
||||
static_cast<i32>(ctx.top[-1].tonum())
|
||||
);
|
||||
ctx.memr = nullptr;
|
||||
ctx.top -= imm[ctx.pc]+1;
|
||||
}
|
||||
|
||||
inline void vm::o_bxoreq() {
|
||||
ctx.top[-1] = ctx.memr[0] = var::num(i32(ctx.memr[0].tonum())^i32(ctx.top[-1].tonum()));
|
||||
ctx.top[-1] = ctx.memr[0] = var::num(
|
||||
static_cast<i32>(ctx.memr[0].tonum())^
|
||||
static_cast<i32>(ctx.top[-1].tonum())
|
||||
);
|
||||
ctx.memr = nullptr;
|
||||
ctx.top -= imm[ctx.pc]+1;
|
||||
}
|
||||
|
@ -439,7 +454,9 @@ inline void vm::o_subecp() {op_calc_eq_const_and_pop(-);}
|
|||
inline void vm::o_mulecp() {op_calc_eq_const_and_pop(*);}
|
||||
inline void vm::o_divecp() {op_calc_eq_const_and_pop(/);}
|
||||
inline void vm::o_lnkecp() {
|
||||
ctx.top[0] = ctx.memr[0] = ngc.newstr(ctx.memr[0].tostr()+cstr[imm[ctx.pc]]);
|
||||
ctx.top[0] = ctx.memr[0] = ngc.newstr(
|
||||
ctx.memr[0].tostr()+cstr[imm[ctx.pc]]
|
||||
);
|
||||
ctx.memr = nullptr;
|
||||
--ctx.top;
|
||||
}
|
||||
|
@ -597,7 +614,9 @@ inline void vm::o_callv() {
|
|||
die("out of range:"+std::to_string(val.tonum()));
|
||||
return;
|
||||
}
|
||||
ctx.top[0] = var::num(f64((u8)str[num>=0? num:num+len]));
|
||||
ctx.top[0] = var::num(
|
||||
static_cast<f64>(static_cast<u8>(str[num>=0? num:num+len]))
|
||||
);
|
||||
} else if (vec.type==vm_map) {
|
||||
if (val.type!=vm_str) {
|
||||
die("must use string as the key");
|
||||
|
|
|
@ -32,11 +32,11 @@ void optimizer::const_number(
|
|||
case binary_operator::binary_type::grt: res = left>right; break;
|
||||
case binary_operator::binary_type::geq: res = left>=right; break;
|
||||
case binary_operator::binary_type::bitwise_or:
|
||||
res = i32(left)|i32(right); break;
|
||||
res = static_cast<i32>(left)|static_cast<i32>(right); break;
|
||||
case binary_operator::binary_type::bitwise_xor:
|
||||
res = i32(left)^i32(right); break;
|
||||
res = static_cast<i32>(left)^static_cast<i32>(right); break;
|
||||
case binary_operator::binary_type::bitwise_and:
|
||||
res = i32(left)&i32(right); break;
|
||||
res = static_cast<i32>(left)&static_cast<i32>(right); break;
|
||||
default: return;
|
||||
}
|
||||
if (std::isinf(res) || std::isnan(res)) {
|
||||
|
@ -51,9 +51,12 @@ void optimizer::const_number(
|
|||
number_literal* value_node) {
|
||||
auto res = value_node->get_number();
|
||||
switch(node->get_operator_type()) {
|
||||
case unary_operator::unary_type::negative: res = -res; break;
|
||||
case unary_operator::unary_type::bitwise_not: res = ~i32(res); break;
|
||||
case unary_operator::unary_type::logical_not: res = !res; break;
|
||||
case unary_operator::unary_type::negative:
|
||||
res = -res; break;
|
||||
case unary_operator::unary_type::bitwise_not:
|
||||
res = ~static_cast<i32>(res); break;
|
||||
case unary_operator::unary_type::logical_not:
|
||||
res = !res; break;
|
||||
}
|
||||
if (std::isinf(res) || std::isnan(res)) {
|
||||
return;
|
||||
|
|
34
src/repl.cpp
34
src/repl.cpp
|
@ -9,6 +9,16 @@
|
|||
namespace nasal {
|
||||
namespace repl {
|
||||
|
||||
void repl::add_command_history(const std::string& history) {
|
||||
if (command_history.size() && command_history.back()==history) {
|
||||
return;
|
||||
}
|
||||
command_history.push_back(history);
|
||||
if (command_history.size()>1000) {
|
||||
command_history.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
std::string repl::readline(std::string prompt = ">>> ") {
|
||||
auto line = std::string("");
|
||||
std::cout << prompt;
|
||||
|
@ -51,6 +61,7 @@ bool repl::check_need_more_input() {
|
|||
}
|
||||
|
||||
auto line = readline("... ");
|
||||
add_command_history(line);
|
||||
source.back() += "\n" + line;
|
||||
}
|
||||
return true;
|
||||
|
@ -66,16 +77,12 @@ void repl::help() {
|
|||
}
|
||||
|
||||
bool repl::run() {
|
||||
using clk = std::chrono::high_resolution_clock;
|
||||
const auto den = clk::duration::period::den;
|
||||
|
||||
auto nasal_lexer = std::unique_ptr<lexer>(new lexer);
|
||||
auto nasal_parser = std::unique_ptr<parse>(new parse);
|
||||
auto nasal_linker = std::unique_ptr<linker>(new linker);
|
||||
auto nasal_opt = std::unique_ptr<optimizer>(new optimizer);
|
||||
auto nasal_codegen = std::unique_ptr<codegen>(new codegen);
|
||||
|
||||
auto start = clk::now();
|
||||
update_temp_file();
|
||||
if (nasal_lexer->scan("<nasal-repl>").geterr()) {
|
||||
return false;
|
||||
|
@ -89,25 +96,25 @@ bool repl::run() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// nasal_opt->do_optimization(nasal_parser->tree());
|
||||
if (nasal_codegen->compile(*nasal_parser, *nasal_linker).geterr()) {
|
||||
nasal_opt->do_optimization(nasal_parser->tree());
|
||||
if (nasal_codegen->compile(*nasal_parser, *nasal_linker, true).geterr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto end = clk::now();
|
||||
std::clog << "[compile time: " << (end-start).count()*1000.0/den << " ms]\n";
|
||||
|
||||
// TODO: gc init stage in this run may cause memory leak,
|
||||
// because constant strings will be generated again.
|
||||
// but we could not delete old strings, they maybe still on stack.
|
||||
runtime.run(*nasal_codegen, *nasal_linker, {});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void repl::execute() {
|
||||
source = {};
|
||||
// mark we are in repl mode
|
||||
info::instance()->in_repl_mode = true;
|
||||
std::cout << "[nasal-repl] Initializating enviroment...\n";
|
||||
// run on pass for initializing basic modules, without output
|
||||
run();
|
||||
// allow output now
|
||||
runtime.set_allow_repl_output_flag(true);
|
||||
std::cout << "[nasal-repl] Initialization complete.\n\n";
|
||||
|
||||
std::cout << "Nasal REPL interpreter(experimental).\n";
|
||||
help();
|
||||
|
@ -117,6 +124,7 @@ void repl::execute() {
|
|||
if (!line.length()) {
|
||||
continue;
|
||||
}
|
||||
add_command_history(line);
|
||||
|
||||
if (line == ".e" || line == ".exit") {
|
||||
break;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <deque>
|
||||
|
||||
namespace nasal {
|
||||
namespace repl {
|
||||
|
@ -27,9 +28,11 @@ struct info {
|
|||
class repl {
|
||||
private:
|
||||
std::vector<std::string> source;
|
||||
std::deque<std::string> command_history;
|
||||
vm runtime;
|
||||
|
||||
private:
|
||||
void add_command_history(const std::string&);
|
||||
std::string readline(std::string);
|
||||
bool check_need_more_input();
|
||||
void update_temp_file();
|
||||
|
@ -42,6 +45,8 @@ public:
|
|||
runtime.set_repl_mode_flag(true);
|
||||
// no detail report info
|
||||
runtime.set_detail_report_info(false);
|
||||
// set empty history
|
||||
command_history = {""};
|
||||
}
|
||||
void execute();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# utils.nas
|
||||
# 2023 by ValKmjolnir
|
||||
|
||||
var times_trigger = func(times, count) {
|
||||
return math.mod(times, count)==0;
|
||||
}
|
Loading…
Reference in New Issue