change enum vm_type to enum class

This commit is contained in:
ValKmjolnir 2023-11-22 22:23:15 +08:00
parent c453cca0a6
commit be84388f5b
17 changed files with 400 additions and 390 deletions

View File

@ -66,7 +66,7 @@ void ghost_for_test_gc_marker(void* ptr, std::vector<var>* bfs_queue) {
}
var create_new_ghost(var* args, usize size, gc* ngc) {
var res = ngc->alloc(vm_obj);
var res = ngc->alloc(vm_type::vm_obj);
res.ghost().set(
ghost_for_test,
ghost_for_test_destructor,

View File

@ -6,14 +6,14 @@
namespace nasal {
var nas_vec2(var* args, usize size, gc* ngc) {
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(args[0]);
res.vec().elems.push_back(args[1]);
return res;
}
var nas_vec3(var* args, usize size, gc* ngc) {
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(args[0]);
res.vec().elems.push_back(args[1]);
res.vec().elems.push_back(args[2]);
@ -21,71 +21,71 @@ var nas_vec3(var* args, usize size, gc* ngc) {
}
var nas_vec2_add(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num()));
return res;
}
var nas_vec2_sub(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num()));
return res;
}
var nas_vec2_mult(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num()));
return res;
}
var nas_vec2_div(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num()));
return res;
}
var nas_vec2_neg(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=2)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(-v0[0].num()));
res.vec().elems.push_back(var::num(-v0[1].num()));
return res;
}
var nas_vec2_norm(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=2)
@ -93,14 +93,14 @@ var nas_vec2_norm(var* args, usize size, gc* ngc) {
auto x = v0[0].num();
auto y = v0[1].num();
auto t = std::sqrt(x*x+y*y);
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(x/t));
res.vec().elems.push_back(var::num(y/t));
return res;
}
var nas_vec2_len(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=2)
@ -111,7 +111,7 @@ var nas_vec2_len(var* args, usize size, gc* ngc) {
}
var nas_vec2_dot(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
@ -121,13 +121,13 @@ var nas_vec2_dot(var* args, usize size, gc* ngc) {
}
var nas_vec3_add(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()+v1[2].num()));
@ -135,13 +135,13 @@ var nas_vec3_add(var* args, usize size, gc* ngc) {
}
var nas_vec3_sub(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()-v1[2].num()));
@ -149,13 +149,13 @@ var nas_vec3_sub(var* args, usize size, gc* ngc) {
}
var nas_vec3_mult(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()*v1[2].num()));
@ -163,13 +163,13 @@ var nas_vec3_mult(var* args, usize size, gc* ngc) {
}
var nas_vec3_div(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num()));
res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()/v1[2].num()));
@ -177,12 +177,12 @@ var nas_vec3_div(var* args, usize size, gc* ngc) {
}
var nas_vec3_neg(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=3)
return nil;
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(-v0[0].num()));
res.vec().elems.push_back(var::num(-v0[1].num()));
res.vec().elems.push_back(var::num(-v0[2].num()));
@ -190,7 +190,7 @@ var nas_vec3_neg(var* args, usize size, gc* ngc) {
}
var nas_vec3_norm(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=3)
@ -199,7 +199,7 @@ var nas_vec3_norm(var* args, usize size, gc* ngc) {
auto y = v0[1].num();
auto z = v0[2].num();
auto t = std::sqrt(x*x+y*y+z*z);
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(x/t));
res.vec().elems.push_back(var::num(y/t));
res.vec().elems.push_back(var::num(z/t));
@ -207,7 +207,7 @@ var nas_vec3_norm(var* args, usize size, gc* ngc) {
}
var nas_vec3_len(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=3)
@ -219,13 +219,13 @@ var nas_vec3_len(var* args, usize size, gc* ngc) {
}
var nas_rotate_x(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=3)
return nil;
auto angle = args[1].num();
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()));
res.vec().elems.push_back(var::num(v0[2].num()*std::sin(angle)+v0[1].num()*std::cos(angle)));
res.vec().elems.push_back(var::num(v0[2].num()*std::cos(angle)-v0[1].num()*std::sin(angle)));
@ -233,13 +233,13 @@ var nas_rotate_x(var* args, usize size, gc* ngc) {
}
var nas_rotate_y(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=3)
return nil;
auto angle = args[1].num();
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[2].num()*std::sin(angle)));
res.vec().elems.push_back(var::num(v0[1].num()));
res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[2].num()*std::cos(angle)));
@ -247,13 +247,13 @@ var nas_rotate_y(var* args, usize size, gc* ngc) {
}
var nas_rotate_z(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
if (v0.size()!=3)
return nil;
auto angle = args[1].num();
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[1].num()*std::sin(angle)));
res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[1].num()*std::cos(angle)));
res.vec().elems.push_back(var::num(v0[2].num()));
@ -261,7 +261,7 @@ var nas_rotate_z(var* args, usize size, gc* ngc) {
}
var nas_vec3_dot(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
if (args[0].type!=vm_type::vm_vec || args[1].type!=vm_type::vm_vec)
return nil;
auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems;

View File

@ -33,14 +33,14 @@ static WSAmanager win;
namespace nasal {
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)
if (args[0].type!=vm_type::vm_num || args[1].type!=vm_type::vm_num || args[2].type!=vm_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(static_cast<double>(sd));
}
var nas_closesocket(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("closesocket", "\"sd\" should be number");
#ifdef _WIN32
return var::num(static_cast<double>(closesocket(args[0].num())));
@ -50,19 +50,19 @@ var nas_closesocket(var* args, usize size, gc* ngc) {
}
var nas_shutdown(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("shutdown", "\"sd\" must be a number");
if (args[1].type!=vm_num)
if (args[1].type!=vm_type::vm_num)
return nas_err("shutdown", "\"how\" must be a number");
return var::num(static_cast<double>(shutdown(args[0].num(), args[1].num())));
}
var nas_bind(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("bind", "\"sd\" muse be a number");
if (args[1].type!=vm_str)
if (args[1].type!=vm_type::vm_str)
return nas_err("bind", "\"ip\" should be a string including an ip with correct format");
if (args[2].type!=vm_num)
if (args[2].type!=vm_type::vm_num)
return nas_err("bind", "\"port\" must be a number");
sockaddr_in server;
memset(&server, 0, sizeof(sockaddr_in));
@ -77,19 +77,19 @@ var nas_bind(var* args, usize size, gc* ngc) {
}
var nas_listen(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("listen", "\"sd\" must be a number");
if (args[1].type!=vm_num)
if (args[1].type!=vm_type::vm_num)
return nas_err("listen", "\"backlog\" must be a number");
return var::num(static_cast<double>(listen(args[0].num(), args[1].num())));
}
var nas_connect(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("connect", "\"sd\" must be a number");
if (args[1].type!=vm_str)
if (args[1].type!=vm_type::vm_str)
return nas_err("connect", "\"hostname\" must be a string");
if (args[2].type!=vm_num)
if (args[2].type!=vm_type::vm_num)
return nas_err("connect", "\"port\" must be a number");
sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in));
@ -105,7 +105,7 @@ var nas_connect(var* args, usize size, gc* ngc) {
}
var nas_accept(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("accept", "\"sd\" must be a number");
sockaddr_in client;
int socklen = sizeof(sockaddr_in);
@ -122,7 +122,7 @@ var nas_accept(var* args, usize size, gc* ngc) {
reinterpret_cast<socklen_t*>(&socklen)
);
#endif
var res = ngc->temp = ngc->alloc(vm_hash);
var res = ngc->temp = ngc->alloc(vm_type::vm_hash);
auto& hash = res.hash().elems;
hash["sd"] = var::num(static_cast<double>(client_sd));
hash["ip"] = ngc->newstr(inet_ntoa(client.sin_addr));
@ -131,11 +131,11 @@ var nas_accept(var* args, usize size, gc* ngc) {
}
var nas_send(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("send", "\"sd\" must be a number");
if (args[1].type!=vm_str)
if (args[1].type!=vm_type::vm_str)
return nas_err("send", "\"buff\" must be a string");
if (args[2].type!=vm_num)
if (args[2].type!=vm_type::vm_num)
return nas_err("send", "\"flags\" muse be a number");
return var::num(static_cast<double>(send(
args[0].num(),
@ -146,15 +146,15 @@ var nas_send(var* args, usize size, gc* ngc) {
}
var nas_sendto(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("sendto", "\"sd\" must be a number");
if (args[1].type!=vm_str)
if (args[1].type!=vm_type::vm_str)
return nas_err("sendto", "\"hostname\" must be a string");
if (args[2].type!=vm_num)
if (args[2].type!=vm_type::vm_num)
return nas_err("sendto", "\"port\" must be a number");
if (args[3].type!=vm_str)
if (args[3].type!=vm_type::vm_str)
return nas_err("sendto", "\"buff\" must be a string");
if (args[4].type!=vm_num)
if (args[4].type!=vm_type::vm_num)
return nas_err("sendto", "\"flags\" must be a number");
sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in));
@ -173,15 +173,15 @@ var nas_sendto(var* args, usize size, gc* ngc) {
}
var nas_recv(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("recv", "\"sd\" must be a number");
if (args[1].type!=vm_num)
if (args[1].type!=vm_type::vm_num)
return nas_err("recv", "\"len\" must be a number");
if (args[1].num()<=0 || args[1].num()>16*1024*1024)
return nas_err("recv", "\"len\" out of range");
if (args[2].type!=vm_num)
if (args[2].type!=vm_type::vm_num)
return nas_err("recv", "\"flags\" muse be a number");
var res = ngc->temp = ngc->alloc(vm_hash);
var res = ngc->temp = ngc->alloc(vm_type::vm_hash);
auto& hash = res.hash().elems;
char* buf = new char[static_cast<int>(args[1].num())];
auto recvsize = recv(args[0].num(), buf, args[1].num(), args[2].num());
@ -194,17 +194,17 @@ var nas_recv(var* args, usize size, gc* ngc) {
}
var nas_recvfrom(var* args, usize size, gc* ngc) {
if (args[0].type!=vm_num)
if (args[0].type!=vm_type::vm_num)
return nas_err("recvfrom", "\"sd\" must be a number");
if (args[1].type!=vm_num)
if (args[1].type!=vm_type::vm_num)
return nas_err("recvfrom", "\"len\" must be a number");
if (args[1].num()<=0 || args[1].num()>16*1024*1024)
return nas_err("recvfrom", "\"len\" out of range");
if (args[2].type!=vm_num)
if (args[2].type!=vm_type::vm_num)
return nas_err("recvfrom", "\"flags\" muse be a number");
sockaddr_in addr;
int socklen = sizeof(sockaddr_in);
var res = ngc->temp = ngc->alloc(vm_hash);
var res = ngc->temp = ngc->alloc(vm_type::vm_hash);
auto& hash = res.hash().elems;
char* buf = new char[static_cast<int>(args[1].num()+1)];
#ifdef _WIN32

View File

@ -48,10 +48,10 @@ var builtin_fld(context* ctx, gc* ngc) {
auto str = local[1];
auto startbit = local[2];
auto length = local[3];
if (str.type!=vm_str || str.val.gcobj->unmutable) {
if (str.type!=vm_type::vm_str || str.val.gcobj->unmutable) {
return nas_err("bits::fld", "\"str\" must be mutable string");
}
if (startbit.type!=vm_num || length.type!=vm_num) {
if (startbit.type!=vm_type::vm_num || length.type!=vm_type::vm_num) {
return nas_err("bits::fld", "\"startbit\",\"len\" must be number");
}
u32 bit = static_cast<u32>(startbit.num());
@ -78,10 +78,10 @@ var builtin_sfld(context* ctx, gc* ngc) {
auto str = local[1];
auto startbit = local[2];
auto length = local[3];
if (str.type!=vm_str || str.val.gcobj->unmutable) {
if (str.type!=vm_type::vm_str || str.val.gcobj->unmutable) {
return nas_err("bits::sfld", "\"str\" must be mutable string");
}
if (startbit.type!=vm_num || length.type!=vm_num) {
if (startbit.type!=vm_type::vm_num || length.type!=vm_type::vm_num) {
return nas_err("bits::sfld", "\"startbit\",\"len\" must be number");
}
u32 bit = static_cast<u32>(startbit.num());
@ -112,10 +112,12 @@ var builtin_setfld(context* ctx, gc* ngc) {
auto startbit = local[2];
auto length = local[3];
auto value = local[4];
if (str.type!=vm_str || str.val.gcobj->unmutable) {
if (str.type!=vm_type::vm_str || str.val.gcobj->unmutable) {
return nas_err("bits::setfld", "\"str\" must be mutable string");
}
if (startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num) {
if (startbit.type!=vm_type::vm_num ||
length.type!=vm_type::vm_num ||
value.type!=vm_type::vm_num) {
return nas_err("bits::setfld",
"\"startbit\", \"len\", \"val\" must be number"
);
@ -139,10 +141,10 @@ var builtin_setfld(context* ctx, gc* ngc) {
var builtin_buf(context* ctx, gc* ngc) {
var length = ctx->localr[1];
if (length.type!=vm_num || length.num()<=0) {
if (length.type!=vm_type::vm_num || length.num()<=0) {
return nas_err("bits::buf", "\"len\" must be number greater than 0");
}
var str = ngc->alloc(vm_str);
var str = ngc->alloc(vm_type::vm_str);
auto& s = str.str();
s.resize(length.num(), '\0');
return str;

View File

@ -18,7 +18,7 @@ var builtin_cocreate(context* ctx, gc* ngc) {
// +-------------+
// ```
auto coroutine_function = ctx->localr[1];
if (coroutine_function.type!=vm_func) {
if (coroutine_function.type!=vm_type::vm_func) {
return nas_err(
"coroutine::create",
"must use a function to create coroutine"
@ -30,7 +30,7 @@ var builtin_cocreate(context* ctx, gc* ngc) {
"cannot create another coroutine in a coroutine"
);
}
auto coroutine_object = ngc->alloc(vm_co);
auto coroutine_object = ngc->alloc(vm_type::vm_co);
auto& coroutine = coroutine_object.co();
coroutine.ctx.pc = coroutine_function.func().entry-1;
@ -69,7 +69,7 @@ var builtin_coresume(context* ctx, gc* ngc) {
auto main_local_frame = ctx->localr;
auto coroutine_object = main_local_frame[1];
// return nil if is not a coroutine object or coroutine exited
if (coroutine_object.type!=vm_co ||
if (coroutine_object.type!=vm_type::vm_co ||
coroutine_object.co().status==nas_co::status::dead) {
return nil;
}
@ -80,7 +80,7 @@ var builtin_coresume(context* ctx, gc* ngc) {
// fetch coroutine's stack top and return
// then coroutine's stack top will catch this return value
// so the coroutine's stack top in fact is not changed
if (ngc->running_context->top[0].type==vm_ret) {
if (ngc->running_context->top[0].type==vm_type::vm_ret) {
// when first calling this coroutine, the stack top must be vm_ret
return ngc->running_context->top[0];
}
@ -114,7 +114,7 @@ var builtin_coyield(context* ctx, gc* ngc) {
var builtin_costatus(context* ctx, gc* ngc) {
auto coroutine_object = ctx->localr[1];
if (coroutine_object.type!=vm_co) {
if (coroutine_object.type!=vm_type::vm_co) {
return ngc->newstr("error");
}
switch(coroutine_object.co().status) {

View File

@ -15,7 +15,7 @@ void dynamic_library_destructor(void* pointer) {
var builtin_dlopen(context* ctx, gc* ngc) {
auto dlname = ctx->localr[1];
if (dlname.type!=vm_str) {
if (dlname.type!=vm_type::vm_str) {
return nas_err("dylib::dlopen", "\"libname\" must be string");
}
@ -42,8 +42,8 @@ var builtin_dlopen(context* ctx, gc* ngc) {
"cannot open dynamic lib <" + dlname.str() + ">"
);
}
auto return_hash = ngc->temp = ngc->alloc(vm_hash);
auto library_object = ngc->alloc(vm_obj);
auto return_hash = ngc->temp = ngc->alloc(vm_type::vm_hash);
auto library_object = ngc->alloc(vm_type::vm_obj);
library_object.ghost().set(
dynamic_library_type_name,
dynamic_library_destructor,
@ -73,7 +73,7 @@ var builtin_dlopen(context* ctx, gc* ngc) {
}
for(u32 i = 0; table[i].name; ++i) {
auto function_pointer = reinterpret_cast<void*>(table[i].fd);
auto function_object = ngc->alloc(vm_obj);
auto function_object = ngc->alloc(vm_type::vm_obj);
function_object.ghost().set(
function_address_type_name,
nullptr,

View File

@ -8,7 +8,7 @@ var builtin_logprint(context* ctx, gc* ngc) {
auto local = ctx->localr;
auto level = local[1];
auto elems = local[2];
if (elems.type!=vm_vec) {
if (elems.type!=vm_type::vm_vec) {
return nas_err("fg_env::logprint", "received argument is not vector.");
}
std::ofstream out("fgfs.log", std::ios::app);

View File

@ -10,7 +10,7 @@ void filehandle_destructor(void* ptr) {
var builtin_readfile(context* ctx, gc* ngc) {
auto filename = ctx->localr[1];
if (filename.type!=vm_str) {
if (filename.type!=vm_type::vm_str) {
return nas_err("io::readfile", "\"filename\" must be string");
}
std::ifstream in(filename.str(), std::ios::binary);
@ -25,7 +25,7 @@ var builtin_fout(context* ctx, gc* ngc) {
auto local = ctx->localr;
auto filename = local[1];
auto source = local[2];
if (filename.type!=vm_str) {
if (filename.type!=vm_type::vm_str) {
return nas_err("io::fout", "\"filename\" must be string");
}
std::ofstream out(filename.str());
@ -38,7 +38,7 @@ var builtin_fout(context* ctx, gc* ngc) {
var builtin_exists(context* ctx, gc* ngc) {
auto filename = ctx->localr[1];
if (filename.type!=vm_str) {
if (filename.type!=vm_type::vm_str) {
return zero;
}
return access(filename.str().c_str(), F_OK)!=-1? one:zero;
@ -48,17 +48,17 @@ var builtin_open(context* ctx, gc* ngc) {
auto local = ctx->localr;
auto name = local[1];
auto mode = local[2];
if (name.type!=vm_str) {
if (name.type!=vm_type::vm_str) {
return nas_err("io::open", "\"filename\" must be string");
}
if (mode.type!=vm_str) {
if (mode.type!=vm_type::vm_str) {
return nas_err("io::open", "\"mode\" must be string");
}
auto file_descriptor = fopen(name.str().c_str(), mode.str().c_str());
if (!file_descriptor) {
return nas_err("io::open", "failed to open file <" + name.str() + ">");
}
var return_object = ngc->alloc(vm_obj);
var return_object = ngc->alloc(vm_type::vm_obj);
return_object.ghost().set(
file_type_name, filehandle_destructor, nullptr, file_descriptor
);
@ -82,10 +82,10 @@ var builtin_read(context* ctx, gc* ngc) {
if (!file_descriptor.object_check(file_type_name)) {
return nas_err("io::read", "not a valid filehandle");
}
if (buffer.type!=vm_str || buffer.val.gcobj->unmutable) {
if (buffer.type!=vm_type::vm_str || buffer.val.gcobj->unmutable) {
return nas_err("io::read", "\"buf\" must be mutable string");
}
if (length.type!=vm_num) {
if (length.type!=vm_type::vm_num) {
return nas_err("io::read", "\"len\" must be number");
}
if (length.num()<=0 || length.num()>=(1<<30)) {
@ -112,7 +112,7 @@ var builtin_write(context* ctx, gc* ngc) {
if (!file_descriptor.object_check(file_type_name)) {
return nas_err("io::write", "not a valid filehandle");
}
if (source.type!=vm_str) {
if (source.type!=vm_type::vm_str) {
return nas_err("io::write", "\"str\" must be string");
}
return var::num(static_cast<f64>(fwrite(
@ -151,7 +151,7 @@ var builtin_readln(context* ctx, gc* ngc) {
if (!file_descriptor.object_check(file_type_name)) {
return nas_err("io::readln", "not a valid filehandle");
}
auto result = ngc->alloc(vm_str);
auto result = ngc->alloc(vm_type::vm_str);
char c;
while((c = fgetc(static_cast<FILE*>(file_descriptor.ghost().pointer)))!=EOF) {
if (c=='\r') {
@ -170,14 +170,14 @@ var builtin_readln(context* ctx, gc* ngc) {
var builtin_stat(context* ctx, gc* ngc) {
auto name = ctx->localr[1];
if (name.type!=vm_str) {
if (name.type!=vm_type::vm_str) {
return nas_err("io::stat", "\"filename\" must be string");
}
struct stat buffer;
if (stat(name.str().c_str(), &buffer)<0) {
return nas_err("io::stat", "failed to open file <" + name.str() + ">");
}
auto result = ngc->alloc(vm_vec);
auto result = ngc->alloc(vm_type::vm_vec);
result.vec().elems = {
var::num(static_cast<f64>(buffer.st_dev)),
var::num(static_cast<f64>(buffer.st_ino)),
@ -205,19 +205,19 @@ var builtin_eof(context* ctx, gc* ngc) {
}
var builtin_stdin(context* ctx, gc* ngc) {
auto file_descriptor = ngc->alloc(vm_obj);
auto file_descriptor = ngc->alloc(vm_type::vm_obj);
file_descriptor.ghost().set(file_type_name, nullptr, nullptr, stdin);
return file_descriptor;
}
var builtin_stdout(context* ctx, gc* ngc) {
auto file_descriptor = ngc->alloc(vm_obj);
auto file_descriptor = ngc->alloc(vm_type::vm_obj);
file_descriptor.ghost().set(file_type_name, nullptr, nullptr, stdout);
return file_descriptor;
}
var builtin_stderr(context* ctx, gc* ngc) {
auto file_descriptor = ngc->alloc(vm_obj);
auto file_descriptor = ngc->alloc(vm_type::vm_obj);
file_descriptor.ghost().set(file_type_name, nullptr, nullptr, stderr);
return file_descriptor;
}

View File

@ -5,7 +5,7 @@ namespace nasal {
var builtin_pow(context* ctx, gc* ngc) {
auto x = ctx->localr[1];
auto y = ctx->localr[2];
if (x.type!=vm_num || y.type!=vm_num) {
if (x.type!=vm_type::vm_num || y.type!=vm_type::vm_num) {
return var::num(std::nan(""));
}
return var::num(std::pow(x.num(), y.num()));
@ -13,43 +13,43 @@ var builtin_pow(context* ctx, gc* ngc) {
var builtin_sin(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
return var::num(val.type==vm_num? sin(val.num()):std::nan(""));
return var::num(val.type==vm_type::vm_num? sin(val.num()):std::nan(""));
}
var builtin_cos(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
return var::num(val.type==vm_num? cos(val.num()):std::nan(""));
return var::num(val.type==vm_type::vm_num? cos(val.num()):std::nan(""));
}
var builtin_tan(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
return var::num(val.type==vm_num? tan(val.num()):std::nan(""));
return var::num(val.type==vm_type::vm_num? tan(val.num()):std::nan(""));
}
var builtin_exp(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
return var::num(val.type==vm_num? exp(val.num()):std::nan(""));
return var::num(val.type==vm_type::vm_num? exp(val.num()):std::nan(""));
}
var builtin_lg(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
return var::num(val.type==vm_num? log(val.num())/log(10.0):std::nan(""));
return var::num(val.type==vm_type::vm_num? log(val.num())/log(10.0):std::nan(""));
}
var builtin_ln(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
return var::num(val.type==vm_num? log(val.num()):std::nan(""));
return var::num(val.type==vm_type::vm_num? log(val.num()):std::nan(""));
}
var builtin_sqrt(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
return var::num(val.type==vm_num? sqrt(val.num()):std::nan(""));
return var::num(val.type==vm_type::vm_num? sqrt(val.num()):std::nan(""));
}
var builtin_atan2(context* ctx, gc* ngc) {
auto x = ctx->localr[1];
auto y = ctx->localr[2];
if (x.type!=vm_num || y.type!=vm_num) {
if (x.type!=vm_type::vm_num || y.type!=vm_type::vm_num) {
return var::num(std::nan(""));
}
return var::num(atan2(y.num(), x.num()));
@ -57,7 +57,7 @@ var builtin_atan2(context* ctx, gc* ngc) {
var builtin_isnan(context* ctx, gc* ngc) {
auto x = ctx->localr[1];
return (x.type==vm_num && std::isnan(x.num()))? one:zero;
return (x.type==vm_type::vm_num && std::isnan(x.num()))? one:zero;
}
nasal_builtin_table math_lib_native[] = {

View File

@ -33,7 +33,7 @@ var builtin_append(context* ctx, gc* ngc) {
auto local = ctx->localr;
var vec = local[1];
var elem = local[2];
if (vec.type!=vm_vec) {
if (vec.type!=vm_type::vm_vec) {
return nas_err("append", "\"vec\" must be vector");
}
auto& v = vec.vec().elems;
@ -47,10 +47,10 @@ var builtin_setsize(context* ctx, gc* ngc) {
auto local = ctx->localr;
var vec = local[1];
var size = local[2];
if (vec.type!=vm_vec) {
if (vec.type!=vm_type::vm_vec) {
return nas_err("setsize", "\"vec\" must be vector");
}
if (size.type!=vm_num || size.num()<0) {
if (size.type!=vm_type::vm_num || size.num()<0) {
return nil;
}
vec.vec().elems.resize(static_cast<i64>(size.num()), nil);
@ -59,7 +59,7 @@ var builtin_setsize(context* ctx, gc* ngc) {
var builtin_system(context* ctx, gc* ngc) {
auto str = ctx->localr[1];
if (str.type!=vm_str) {
if (str.type!=vm_type::vm_str) {
return var::num(-1);
}
return var::num(static_cast<f64>(system(str.str().c_str())));
@ -68,8 +68,8 @@ var builtin_system(context* ctx, gc* ngc) {
var builtin_input(context* ctx, gc* ngc) {
auto local = ctx->localr;
var end = local[1];
var ret = ngc->alloc(vm_str);
if (end.type!=vm_str || end.str().length()>1 || !end.str().length()) {
var ret = ngc->alloc(vm_type::vm_str);
if (end.type!=vm_type::vm_str || end.str().length()>1 || !end.str().length()) {
std::cin >> ret.str();
} else {
std::getline(std::cin, ret.str(), end.str()[0]);
@ -81,17 +81,17 @@ var builtin_split(context* ctx, gc* ngc) {
auto local = ctx->localr;
var delimeter = local[1];
var str = local[2];
if (delimeter.type!=vm_str) {
if (delimeter.type!=vm_type::vm_str) {
return nas_err("split", "\"separator\" must be string");
}
if (str.type!=vm_str) {
if (str.type!=vm_type::vm_str) {
return nas_err("split", "\"str\" must be string");
}
const auto& deli = delimeter.str();
const auto& s = str.str();
// avoid being sweeped
auto res = ngc->temp = ngc->alloc(vm_vec);
auto res = ngc->temp = ngc->alloc(vm_type::vm_vec);
auto& vec = res.vec().elems;
if (!deli.length()) {
@ -119,10 +119,10 @@ var builtin_split(context* ctx, gc* ngc) {
var builtin_rand(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
if (val.type!=vm_num && val.type!=vm_nil) {
if (val.type!=vm_type::vm_num && val.type!=vm_type::vm_nil) {
return nas_err("rand", "\"seed\" must be nil or number");
}
if (val.type==vm_num) {
if (val.type==vm_type::vm_num) {
srand(static_cast<u32>(val.num()));
return nil;
}
@ -137,7 +137,7 @@ var builtin_id(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
std::stringstream ss;
ss << "0";
if (val.type>vm_num) {
if (val.type>vm_type::vm_num) {
ss << "x" << std::hex;
ss << reinterpret_cast<u64>(val.val.gcobj) << std::dec;
}
@ -146,7 +146,7 @@ var builtin_id(context* ctx, gc* ngc) {
var builtin_int(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
if (val.type!=vm_num && val.type!=vm_str) {
if (val.type!=vm_type::vm_num && val.type!=vm_type::vm_str) {
return nil;
}
return var::num(static_cast<f64>(static_cast<i32>(val.to_num())));
@ -164,10 +164,10 @@ var builtin_ceil(context* ctx, gc* ngc) {
var builtin_num(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
if (val.type==vm_num) {
if (val.type==vm_type::vm_num) {
return val;
}
if (val.type!=vm_str) {
if (val.type!=vm_type::vm_str) {
return nil;
}
auto res = val.to_num();
@ -179,7 +179,7 @@ var builtin_num(context* ctx, gc* ngc) {
var builtin_pop(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
if (val.type!=vm_vec) {
if (val.type!=vm_type::vm_vec) {
return nas_err("pop", "\"vec\" must be vector");
}
auto& vec = val.vec().elems;
@ -199,18 +199,18 @@ var builtin_size(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
f64 num = 0;
switch(val.type) {
case vm_num: num = val.num(); break;
case vm_str: num = val.str().length(); break;
case vm_vec: num = val.vec().size(); break;
case vm_hash: num = val.hash().size(); break;
case vm_map: num = val.map().mapper.size(); break;
case vm_type::vm_num: num = val.num(); break;
case vm_type::vm_str: num = val.str().length(); break;
case vm_type::vm_vec: num = val.vec().size(); break;
case vm_type::vm_hash: num = val.hash().size(); break;
case vm_type::vm_map: num = val.map().mapper.size(); break;
}
return var::num(num);
}
var builtin_time(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
if (val.type!=vm_num) {
if (val.type!=vm_type::vm_num) {
return nas_err("time", "\"begin\" must be number");
}
auto begin = static_cast<time_t>(val.num());
@ -221,7 +221,7 @@ var builtin_contains(context* ctx, gc* ngc) {
auto local = ctx->localr;
var hash = local[1];
var key = local[2];
if (hash.type!=vm_hash || key.type!=vm_str) {
if (hash.type!=vm_type::vm_hash || key.type!=vm_type::vm_str) {
return zero;
}
return hash.hash().elems.count(key.str())? one:zero;
@ -231,10 +231,10 @@ var builtin_delete(context* ctx, gc* ngc) {
auto local = ctx->localr;
var hash = local[1];
var key = local[2];
if (hash.type!=vm_hash) {
if (hash.type!=vm_type::vm_hash) {
return nas_err("delete", "\"hash\" must be hash");
}
if (key.type!=vm_str) {
if (key.type!=vm_type::vm_str) {
return nil;
}
if (hash.hash().elems.count(key.str())) {
@ -245,13 +245,13 @@ var builtin_delete(context* ctx, gc* ngc) {
var builtin_keys(context* ctx, gc* ngc) {
auto hash = ctx->localr[1];
if (hash.type!=vm_hash && hash.type!=vm_map) {
if (hash.type!=vm_type::vm_hash && hash.type!=vm_type::vm_map) {
return nas_err("keys", "\"hash\" must be hash");
}
// avoid being sweeped
auto res = ngc->temp = ngc->alloc(vm_vec);
auto res = ngc->temp = ngc->alloc(vm_type::vm_vec);
auto& vec = res.vec().elems;
if (hash.type==vm_hash) {
if (hash.type==vm_type::vm_hash) {
for(const auto& iter : hash.hash().elems) {
vec.push_back(ngc->newstr(iter.first));
}
@ -281,16 +281,16 @@ var builtin_find(context* ctx, gc* ngc) {
var builtin_type(context* ctx, gc* ngc) {
switch(ctx->localr[1].type) {
case vm_none: return ngc->newstr("undefined");
case vm_nil: return ngc->newstr("nil");
case vm_num: return ngc->newstr("num");
case vm_str: return ngc->newstr("str");
case vm_vec: return ngc->newstr("vec");
case vm_hash: return ngc->newstr("hash");
case vm_func: return ngc->newstr("func");
case vm_obj: return ngc->newstr("obj");
case vm_co: return ngc->newstr("coroutine");
case vm_map: return ngc->newstr("namespace");
case vm_type::vm_none: return ngc->newstr("undefined");
case vm_type::vm_nil: return ngc->newstr("nil");
case vm_type::vm_num: return ngc->newstr("num");
case vm_type::vm_str: return ngc->newstr("str");
case vm_type::vm_vec: return ngc->newstr("vec");
case vm_type::vm_hash: return ngc->newstr("hash");
case vm_type::vm_func: return ngc->newstr("func");
case vm_type::vm_obj: return ngc->newstr("obj");
case vm_type::vm_co: return ngc->newstr("coroutine");
case vm_type::vm_map: return ngc->newstr("namespace");
}
return nil;
}
@ -300,13 +300,13 @@ var builtin_substr(context* ctx, gc* ngc) {
var str = local[1];
var beg = local[2];
var len = local[3];
if (str.type!=vm_str) {
if (str.type!=vm_type::vm_str) {
return nas_err("substr", "\"str\" must be string");
}
if (beg.type!=vm_num || beg.num()<0) {
if (beg.type!=vm_type::vm_num || beg.num()<0) {
return nas_err("substr", "\"begin\" should be number >= 0");
}
if (len.type!=vm_num || len.num()<0) {
if (len.type!=vm_type::vm_num || len.num()<0) {
return nas_err("substr", "\"length\" should be number >= 0");
}
auto begin = static_cast<usize>(beg.num());
@ -322,7 +322,7 @@ var builtin_streq(context* ctx, gc* ngc) {
var a = local[1];
var b = local[2];
return var::num(static_cast<f64>(
(a.type!=vm_str || b.type!=vm_str)? 0:(a.str()==b.str())
(a.type!=vm_type::vm_str || b.type!=vm_type::vm_str)? 0:(a.str()==b.str())
));
}
@ -330,10 +330,10 @@ var builtin_left(context* ctx, gc* ngc) {
auto local = ctx->localr;
var str = local[1];
var len = local[2];
if (str.type!=vm_str) {
if (str.type!=vm_type::vm_str) {
return nas_err("left", "\"string\" must be string");
}
if (len.type!=vm_num) {
if (len.type!=vm_type::vm_num) {
return nas_err("left", "\"length\" must be number");
}
if (len.num()<0) {
@ -346,10 +346,10 @@ var builtin_right(context* ctx, gc* ngc) {
auto local = ctx->localr;
var str = local[1];
var len = local[2];
if (str.type!=vm_str) {
if (str.type!=vm_type::vm_str) {
return nas_err("right", "\"string\" must be string");
}
if (len.type!=vm_num) {
if (len.type!=vm_type::vm_num) {
return nas_err("right", "\"length\" must be number");
}
i32 length = static_cast<i32>(len.num());
@ -367,7 +367,7 @@ var builtin_cmp(context* ctx, gc* ngc) {
auto local = ctx->localr;
var a = local[1];
var b = local[2];
if (a.type!=vm_str || b.type!=vm_str) {
if (a.type!=vm_type::vm_str || b.type!=vm_type::vm_str) {
return nas_err("cmp", "\"a\" and \"b\" must be string");
}
return var::num(static_cast<f64>(strcmp(
@ -410,12 +410,12 @@ var builtin_char(context* ctx, gc* ngc) {
var builtin_values(context* ctx, gc* ngc) {
auto hash = ctx->localr[1];
if (hash.type!=vm_hash && hash.type!=vm_map) {
if (hash.type!=vm_type::vm_hash && hash.type!=vm_type::vm_map) {
return nas_err("values", "\"hash\" must be hash or namespace");
}
auto vec = ngc->alloc(vm_vec);
auto vec = ngc->alloc(vm_type::vm_vec);
auto& v = vec.vec().elems;
if (hash.type==vm_hash) {
if (hash.type==vm_type::vm_hash) {
for(auto& i : hash.hash().elems) {
v.push_back(i.second);
}
@ -429,7 +429,7 @@ var builtin_values(context* ctx, gc* ngc) {
var builtin_sleep(context* ctx, gc* ngc) {
auto val = ctx->localr[1];
if (val.type!=vm_num) {
if (val.type!=vm_type::vm_num) {
return nil;
}
#if defined(_WIN32) && !defined(_GLIBCXX_HAS_GTHREADS)
@ -561,7 +561,7 @@ std::string md5(const std::string& src) {
var builtin_md5(context* ctx, gc* ngc) {
auto str = ctx->localr[1];
if (str.type!=vm_str) {
if (str.type!=vm_type::vm_str) {
return nas_err("md5", "\"str\" must be string");
}
return ngc->newstr(md5(str.str()));
@ -576,31 +576,31 @@ var builtin_millisec(context* ctx, gc* ngc) {
var builtin_gcextend(context* ctx, gc* ngc) {
auto type = ctx->localr[1];
if (type.type!=vm_str) {
if (type.type!=vm_type::vm_str) {
return nil;
}
const auto& s = type.str();
if (s=="str") {
ngc->extend(vm_str);
ngc->extend(vm_type::vm_str);
} else if (s=="vec") {
ngc->extend(vm_vec);
ngc->extend(vm_type::vm_vec);
} else if (s=="hash") {
ngc->extend(vm_hash);
ngc->extend(vm_type::vm_hash);
} else if (s=="func") {
ngc->extend(vm_func);
ngc->extend(vm_type::vm_func);
} else if (s=="upval") {
ngc->extend(vm_upval);
ngc->extend(vm_type::vm_upval);
} else if (s=="obj") {
ngc->extend(vm_obj);
ngc->extend(vm_type::vm_obj);
} else if (s=="co") {
ngc->extend(vm_co);
ngc->extend(vm_type::vm_co);
}
return nil;
}
var builtin_gcinfo(context* ctx, gc* ngc) {
auto den = std::chrono::high_resolution_clock::duration::period::den;
var res = ngc->alloc(vm_hash);
var res = ngc->alloc(vm_type::vm_hash);
double total = 0;
for(u32 i = 0; i<gc_type_size; ++i) {
@ -634,7 +634,7 @@ var builtin_logtime(context* ctx, gc* ngc) {
var builtin_ghosttype(context* ctx, gc* ngc) {
auto arg = ctx->localr[1];
if (arg.type!=vm_obj) {
if (arg.type!=vm_type::vm_obj) {
return nas_err("ghosttype", "this is not a ghost object.");
}
const auto& name = arg.ghost().get_ghost_name();

View File

@ -38,7 +38,7 @@ void gc::mark() {
while(!bfs.empty()) {
var value = bfs.back();
bfs.pop_back();
if (value.type<=vm_num ||
if (value.type<=vm_type::vm_num ||
value.val.gcobj->mark!=nas_val::gc_status::uncollected) {
continue;
}
@ -50,7 +50,7 @@ void gc::concurrent_mark(std::vector<var>& vec, usize begin, usize end) {
std::vector<var> bfs;
for(auto i = begin; i<end; ++i) {
var value = vec[i];
if (value.type<=vm_num ||
if (value.type<=vm_type::vm_num ||
value.val.gcobj->mark!=nas_val::gc_status::uncollected) {
continue;
}
@ -59,7 +59,7 @@ void gc::concurrent_mark(std::vector<var>& vec, usize begin, usize end) {
while(!bfs.empty()) {
var value = bfs.back();
bfs.pop_back();
if (value.type<=vm_num ||
if (value.type<=vm_type::vm_num ||
value.val.gcobj->mark!=nas_val::gc_status::uncollected) {
continue;
}
@ -71,13 +71,13 @@ void gc::mark_context_root(std::vector<var>& bfs_queue) {
// scan global
for(usize i = 0; i<main_context_global_size; ++i) {
auto& val = main_context_global[i];
if (val.type>vm_num) {
if (val.type>vm_type::vm_num) {
bfs_queue.push_back(val);
}
}
// scan now running context, this context maybe related to coroutine or main
for(var* i = running_context->stack; i<=running_context->top; ++i) {
if (i->type>vm_num) {
if (i->type>vm_type::vm_num) {
bfs_queue.push_back(*i);
}
}
@ -91,7 +91,7 @@ void gc::mark_context_root(std::vector<var>& bfs_queue) {
// coroutine is running, so scan main process stack from mctx
for(var* i = main_context.stack; i<=main_context.top; ++i) {
if (i->type>vm_num) {
if (i->type>vm_type::vm_num) {
bfs_queue.push_back(*i);
}
}
@ -102,20 +102,20 @@ void gc::mark_context_root(std::vector<var>& bfs_queue) {
void gc::mark_var(std::vector<var>& bfs_queue, var& value) {
value.val.gcobj->mark = nas_val::gc_status::found;
switch(value.type) {
case vm_vec: mark_vec(bfs_queue, value.vec()); break;
case vm_hash: mark_hash(bfs_queue, value.hash()); break;
case vm_func: mark_func(bfs_queue, value.func()); break;
case vm_upval: mark_upval(bfs_queue, value.upval()); break;
case vm_obj: mark_ghost(bfs_queue, value.ghost()); break;
case vm_co: mark_co(bfs_queue, value.co()); break;
case vm_map: mark_map(bfs_queue, value.map()); break;
case vm_type::vm_vec: mark_vec(bfs_queue, value.vec()); break;
case vm_type::vm_hash: mark_hash(bfs_queue, value.hash()); break;
case vm_type::vm_func: mark_func(bfs_queue, value.func()); break;
case vm_type::vm_upval: mark_upval(bfs_queue, value.upval()); break;
case vm_type::vm_obj: mark_ghost(bfs_queue, value.ghost()); break;
case vm_type::vm_co: mark_co(bfs_queue, value.co()); break;
case vm_type::vm_map: mark_map(bfs_queue, value.map()); break;
default: break;
}
}
void gc::mark_vec(std::vector<var>& bfs_queue, nas_vec& vec) {
for(auto& i : vec.elems) {
if (i.type>vm_num) {
if (i.type>vm_type::vm_num) {
bfs_queue.push_back(i);
}
}
@ -123,7 +123,7 @@ void gc::mark_vec(std::vector<var>& bfs_queue, nas_vec& vec) {
void gc::mark_hash(std::vector<var>& bfs_queue, nas_hash& hash) {
for(auto& i : hash.elems) {
if (i.second.type>vm_num) {
if (i.second.type>vm_type::vm_num) {
bfs_queue.push_back(i.second);
}
}
@ -131,7 +131,7 @@ void gc::mark_hash(std::vector<var>& bfs_queue, nas_hash& hash) {
void gc::mark_func(std::vector<var>& bfs_queue, nas_func& function) {
for(auto& i : function.local) {
if (i.type>vm_num) {
if (i.type>vm_type::vm_num) {
bfs_queue.push_back(i);
}
}
@ -142,7 +142,7 @@ void gc::mark_func(std::vector<var>& bfs_queue, nas_func& function) {
void gc::mark_upval(std::vector<var>& bfs_queue, nas_upval& upval) {
for(auto& i : upval.elems) {
if (i.type>vm_num) {
if (i.type>vm_type::vm_num) {
bfs_queue.push_back(i);
}
}
@ -159,7 +159,7 @@ void gc::mark_co(std::vector<var>& bfs_queue, nas_co& co) {
bfs_queue.push_back(co.ctx.funcr);
bfs_queue.push_back(co.ctx.upvalr);
for(var* i = co.ctx.stack; i<=co.ctx.top; ++i) {
if (i->type>vm_num) {
if (i->type>vm_type::vm_num) {
bfs_queue.push_back(*i);
}
}
@ -167,7 +167,7 @@ void gc::mark_co(std::vector<var>& bfs_queue, nas_co& co) {
void gc::mark_map(std::vector<var>& bfs_queue, nas_map& mp) {
for(const auto& i : mp.mapper) {
if (i.second->type>vm_num) {
if (i.second->type>vm_type::vm_num) {
bfs_queue.push_back(*i.second);
}
}
@ -177,7 +177,7 @@ void gc::sweep() {
for(auto i : memory) {
if (i->mark==nas_val::gc_status::uncollected) {
i->clear();
unused[i->type-vm_str].push_back(i);
unused[static_cast<u8>(i->type)-static_cast<u8>(vm_type::vm_str)].push_back(i);
i->mark = nas_val::gc_status::collected;
} else if (i->mark==nas_val::gc_status::found) {
i->mark = nas_val::gc_status::uncollected;
@ -185,8 +185,8 @@ void gc::sweep() {
}
}
void gc::extend(u8 type) {
const u8 index = type-vm_str;
void gc::extend(const vm_type type) {
const u8 index = static_cast<u8>(type)-static_cast<u8>(vm_type::vm_str);
size[index] += incr[index];
for(u32 i = 0; i<incr[index]; ++i) {
@ -218,10 +218,10 @@ void gc::init(
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]) {
if (strs[i].type==vm_type::vm_str && strs[i].str()==constant_strings[i]) {
continue;
}
strs[i] = var::gcobj(new nas_val(vm_str));
strs[i] = var::gcobj(new nas_val(vm_type::vm_str));
strs[i].val.gcobj->unmutable = 1;
strs[i].str() = constant_strings[i];
}
@ -230,10 +230,10 @@ void gc::init(
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]) {
if (env_argv[i].type==vm_type::vm_str && env_argv[i].str()==argv[i]) {
continue;
}
env_argv[i] = var::gcobj(new nas_val(vm_str));
env_argv[i] = var::gcobj(new nas_val(vm_type::vm_str));
env_argv[i].val.gcobj->unmutable = 1;
env_argv[i].str() = argv[i];
}
@ -344,8 +344,8 @@ void gc::info() const {
std::clog << last_line << "\n";
}
var gc::alloc(u8 type) {
const u8 index = type-vm_str;
var gc::alloc(const vm_type type) {
const u8 index = static_cast<u8>(type)-static_cast<u8>(vm_type::vm_str);
++acnt[index];
if (unused[index].empty()) {
++gcnt[index];

View File

@ -84,29 +84,29 @@ private:
void sweep();
public:
void extend(u8);
void extend(const vm_type);
void init(const std::vector<std::string>&, const std::vector<std::string>&);
void clear();
void info() const;
var alloc(const u8);
var alloc(const vm_type);
void context_change(nas_co*);
void context_reserve();
public:
var newstr(char c) {
var s = alloc(vm_str);
var s = alloc(vm_type::vm_str);
s.str() = c;
return s;
}
var newstr(const char* buff) {
var s = alloc(vm_str);
var s = alloc(vm_type::vm_str);
s.str() = std::string(buff);
return s;
}
var newstr(const std::string& buff) {
var s = alloc(vm_str);
var s = alloc(vm_type::vm_str);
s.str() = buff;
return s;
}

View File

@ -44,14 +44,14 @@ var nas_hash::get_value(const std::string& key) {
}
var ret = var::none();
var val = elems.at("parents");
if (val.type!=vm_vec) {
if (val.type!=vm_type::vm_vec) {
return ret;
}
for(auto& i : val.vec().elems) {
if (i.type==vm_hash) {
if (i.type==vm_type::vm_hash) {
ret = i.hash().get_value(key);
}
if (ret.type!=vm_none) {
if (ret.type!=vm_type::vm_none) {
return ret;
}
}
@ -66,11 +66,11 @@ var* nas_hash::get_memory(const std::string& key) {
}
var* addr = nullptr;
var val = elems.at("parents");
if (val.type!=vm_vec) {
if (val.type!=vm_type::vm_vec) {
return addr;
}
for(auto& i : val.vec().elems) {
if (i.type==vm_hash) {
if (i.type==vm_type::vm_hash) {
addr = i.hash().get_memory(key);
}
if (addr) {
@ -195,57 +195,57 @@ std::ostream& operator<<(std::ostream& out, nas_map& mp) {
return out;
}
nas_val::nas_val(u8 val_type) {
nas_val::nas_val(vm_type val_type) {
mark = gc_status::collected;
type = val_type;
unmutable = 0;
switch(val_type) {
case vm_str: ptr.str = new std::string; break;
case vm_vec: ptr.vec = new nas_vec; break;
case vm_hash: ptr.hash = new nas_hash; break;
case vm_func: ptr.func = new nas_func; break;
case vm_upval: ptr.upval = new nas_upval; break;
case vm_obj: ptr.obj = new nas_ghost; break;
case vm_co: ptr.co = new nas_co; break;
case vm_map: ptr.map = new nas_map; break;
case vm_type::vm_str: ptr.str = new std::string; break;
case vm_type::vm_vec: ptr.vec = new nas_vec; break;
case vm_type::vm_hash: ptr.hash = new nas_hash; break;
case vm_type::vm_func: ptr.func = new nas_func; break;
case vm_type::vm_upval: ptr.upval = new nas_upval; break;
case vm_type::vm_obj: ptr.obj = new nas_ghost; break;
case vm_type::vm_co: ptr.co = new nas_co; break;
case vm_type::vm_map: ptr.map = new nas_map; break;
}
}
nas_val::~nas_val() {
switch(type) {
case vm_str: delete ptr.str; break;
case vm_vec: delete ptr.vec; break;
case vm_hash: delete ptr.hash; break;
case vm_func: delete ptr.func; break;
case vm_upval:delete ptr.upval; break;
case vm_obj: delete ptr.obj; break;
case vm_co: delete ptr.co; break;
case vm_map: delete ptr.map; break;
case vm_type::vm_str: delete ptr.str; break;
case vm_type::vm_vec: delete ptr.vec; break;
case vm_type::vm_hash: delete ptr.hash; break;
case vm_type::vm_func: delete ptr.func; break;
case vm_type::vm_upval:delete ptr.upval; break;
case vm_type::vm_obj: delete ptr.obj; break;
case vm_type::vm_co: delete ptr.co; break;
case vm_type::vm_map: delete ptr.map; break;
}
type=vm_nil;
type = vm_type::vm_nil;
}
void nas_val::clear() {
switch(type) {
case vm_str: ptr.str->clear(); break;
case vm_vec: ptr.vec->elems.clear(); break;
case vm_hash: ptr.hash->elems.clear(); break;
case vm_func: ptr.func->clear(); break;
case vm_upval:ptr.upval->clear(); break;
case vm_obj: ptr.obj->clear(); break;
case vm_co: ptr.co->clear(); break;
case vm_map: ptr.map->clear(); break;
case vm_type::vm_str: ptr.str->clear(); break;
case vm_type::vm_vec: ptr.vec->elems.clear(); break;
case vm_type::vm_hash: ptr.hash->elems.clear(); break;
case vm_type::vm_func: ptr.func->clear(); break;
case vm_type::vm_upval:ptr.upval->clear(); break;
case vm_type::vm_obj: ptr.obj->clear(); break;
case vm_type::vm_co: ptr.co->clear(); break;
case vm_type::vm_map: ptr.map->clear(); break;
}
}
f64 var::to_num() {
return type!=vm_str? val.num:str2num(str().c_str());
return type!=vm_type::vm_str? val.num:str2num(str().c_str());
}
std::string var::to_str() {
if (type==vm_str) {
if (type==vm_type::vm_str) {
return str();
} else if (type==vm_num) {
} else if (type==vm_type::vm_num) {
std::string tmp = std::to_string(num());
tmp.erase(tmp.find_last_not_of('0')+1, std::string::npos);
tmp.erase(tmp.find_last_not_of('.')+1, std::string::npos);
@ -256,42 +256,42 @@ std::string var::to_str() {
std::ostream& operator<<(std::ostream& out, var& ref) {
switch(ref.type) {
case vm_none: out << "undefined"; break;
case vm_nil: out << "nil"; break;
case vm_num: out << ref.val.num; break;
case vm_str: out << ref.str(); break;
case vm_vec: out << ref.vec(); break;
case vm_hash: out << ref.hash(); break;
case vm_func: out << "func(..) {..}"; break;
case vm_obj: out << ref.ghost(); break;
case vm_co: out << ref.co(); break;
case vm_map: out << ref.map(); break;
case vm_type::vm_none: out << "undefined"; break;
case vm_type::vm_nil: out << "nil"; break;
case vm_type::vm_num: out << ref.val.num; break;
case vm_type::vm_str: out << ref.str(); break;
case vm_type::vm_vec: out << ref.vec(); break;
case vm_type::vm_hash: out << ref.hash(); break;
case vm_type::vm_func: out << "func(..) {..}"; break;
case vm_type::vm_obj: out << ref.ghost(); break;
case vm_type::vm_co: out << ref.co(); break;
case vm_type::vm_map: out << ref.map(); break;
}
return out;
}
bool var::object_check(const std::string& name) {
return type==vm_obj && ghost().type_name==name && ghost().pointer;
return type==vm_type::vm_obj && ghost().type_name==name && ghost().pointer;
}
var var::none() {
return {vm_none, static_cast<u32>(0)};
return {vm_type::vm_none, static_cast<u32>(0)};
}
var var::nil() {
return {vm_nil, static_cast<u32>(0)};
return {vm_type::vm_nil, static_cast<u32>(0)};
}
var var::ret(u32 pc) {
return {vm_ret, pc};
return {vm_type::vm_ret, pc};
}
var var::cnt(i64 n) {
return {vm_cnt, n};
return {vm_type::vm_cnt, n};
}
var var::num(f64 n) {
return {vm_num, n};
return {vm_type::vm_num, n};
}
var var::gcobj(nas_val* p) {
@ -299,7 +299,7 @@ var var::gcobj(nas_val* p) {
}
var var::addr(var* p) {
return {vm_addr, p};
return {vm_type::vm_addr, p};
}
var* var::addr() {

View File

@ -7,7 +7,7 @@
namespace nasal {
enum vm_type:u8 {
enum class vm_type: u8 {
/* none-gc object */
vm_none = 0, // error type
vm_cnt, // counter for forindex/foreach loop
@ -29,7 +29,9 @@ enum vm_type:u8 {
};
// size of gc object type
const u32 gc_type_size = vm_type_size_max-vm_str;
const u32 gc_type_size =
static_cast<u32>(vm_type::vm_type_size_max) -
static_cast<u32>(vm_type::vm_str);
// basic types
struct nas_vec; // vector
@ -45,7 +47,7 @@ struct nas_val; // nas_val includes gc-managed types
struct var {
public:
u8 type = vm_none;
vm_type type = vm_type::vm_none;
union {
u32 ret;
i64 cnt;
@ -55,11 +57,11 @@ public:
} val;
private:
var(u8 t, u32 pc) {type = t; val.ret = pc;}
var(u8 t, i64 ct) {type = t; val.cnt = ct;}
var(u8 t, f64 n) {type = t; val.num = n;}
var(u8 t, var* p) {type = t; val.addr = p;}
var(u8 t, nas_val* p) {type = t; val.gcobj = p;}
var(vm_type t, u32 pc) {type = t; val.ret = pc;}
var(vm_type t, i64 ct) {type = t; val.cnt = ct;}
var(vm_type t, f64 n) {type = t; val.num = n;}
var(vm_type t, var* p) {type = t; val.addr = p;}
var(vm_type t, nas_val* p) {type = t; val.gcobj = p;}
public:
var() = default;
@ -237,7 +239,7 @@ struct nas_val {
};
gc_status mark;
u8 type; // value type
vm_type type; // value type
u8 unmutable; // used to mark if a string is unmutable
union {
std::string* str;
@ -250,7 +252,7 @@ struct nas_val {
nas_map* map;
} ptr;
nas_val(u8);
nas_val(vm_type);
~nas_val();
void clear();
};

View File

@ -31,14 +31,14 @@ void vm::init(
ngc.init(strs, argv);
/* init vm globals */
auto map_instance = ngc.alloc(vm_map);
auto map_instance = ngc.alloc(vm_type::vm_map);
global[global_symbol.at("globals")] = map_instance;
for(const auto& i : global_symbol) {
map_instance.map().mapper[i.first] = global+i.second;
}
/* init vm arg */
auto arg_instance = ngc.alloc(vm_vec);
auto arg_instance = ngc.alloc(vm_type::vm_vec);
global[global_symbol.at("arg")] = arg_instance;
arg_instance.vec().elems = ngc.env_argv;
}
@ -67,39 +67,40 @@ void vm::context_and_global_init() {
void vm::value_info(var& val) {
const auto p = reinterpret_cast<u64>(val.val.gcobj);
switch(val.type) {
case vm_none: std::clog << "| null |"; break;
case vm_ret: std::clog << "| pc | 0x" << std::hex
case vm_type::vm_none: std::clog << "| null |"; break;
case vm_type::vm_ret: std::clog << "| pc | 0x" << std::hex
<< val.ret() << std::dec; break;
case vm_addr: std::clog << "| addr | 0x" << std::hex
case vm_type::vm_addr: std::clog << "| addr | 0x" << std::hex
<< reinterpret_cast<u64>(val.addr())
<< std::dec; break;
case vm_cnt: std::clog << "| cnt | " << val.cnt(); break;
case vm_nil: std::clog << "| nil |"; break;
case vm_num: std::clog << "| num | " << val.num(); break;
case vm_str: std::clog << "| str | <0x" << std::hex << p
case vm_type::vm_cnt: std::clog << "| cnt | " << val.cnt(); break;
case vm_type::vm_nil: std::clog << "| nil |"; break;
case vm_type::vm_num: std::clog << "| num | " << val.num(); break;
case vm_type::vm_str: std::clog << "| str | <0x" << std::hex << p
<< "> " << rawstr(val.str(), 16)
<< std::dec; break;
case vm_func: std::clog << "| func | <0x" << std::hex << p
case vm_type::vm_func: std::clog << "| func | <0x" << std::hex << p
<< "> entry:0x" << val.func().entry
<< std::dec; break;
case vm_upval:std::clog << "| upval| <0x" << std::hex << p
case vm_type::vm_upval:std::clog << "| upval| <0x" << std::hex << p
<< std::dec << "> [" << val.upval().size
<< " val]"; break;
case vm_vec: std::clog << "| vec | <0x" << std::hex << p
case vm_type::vm_vec: std::clog << "| vec | <0x" << std::hex << p
<< std::dec << "> [" << val.vec().size()
<< " val]"; break;
case vm_hash: std::clog << "| hash | <0x" << std::hex << p
case vm_type::vm_hash: std::clog << "| hash | <0x" << std::hex << p
<< std::dec << "> {" << val.hash().size()
<< " val}"; break;
case vm_obj: std::clog << "| obj | <0x" << std::hex << p
case vm_type::vm_obj: std::clog << "| obj | <0x" << std::hex << p
<< "> obj:0x"
<< reinterpret_cast<u64>(val.ghost().pointer)
<< std::dec; break;
case vm_co: std::clog << "| co | <0x" << std::hex << p
case vm_type::vm_co: std::clog << "| co | <0x" << std::hex << p
<< std::dec << "> coroutine"; break;
case vm_map: std::clog << "| nmspc| <0x" << std::hex << p
case vm_type::vm_map: std::clog << "| nmspc| <0x" << std::hex << p
<< std::dec << "> namespace ["
<< val.map().mapper.size() << " val]"; break;
<< val.map().mapper.size()
<< " val]"; break;
default: std::clog << "| err | <0x" << std::hex << p
<< std::dec << "> unknown object"; break;
}
@ -138,7 +139,9 @@ void vm::function_call_trace() {
// generate trace back
std::stack<const nas_func*> functions;
for(var* i = bottom; i<=top; ++i) {
if (i->type==vm_func && i-1>=bottom && (i-1)->type==vm_ret) {
if (i->type==vm_type::vm_func &&
i-1>=bottom &&
(i-1)->type==vm_type::vm_ret) {
functions.push(&i->func());
}
}
@ -176,7 +179,7 @@ void vm::trace_back() {
// generate trace back
std::stack<u32> ret;
for(var* i = ctx.stack; i<=ctx.top; ++i) {
if (i->type==vm_ret && i->ret()!=0) {
if (i->type==vm_type::vm_ret && i->ret()!=0) {
ret.push(i->ret());
}
}
@ -236,7 +239,7 @@ void vm::register_info() {
}
void vm::global_state() {
if (!global_size || global[0].type==vm_none) {
if (!global_size || global[0].type==vm_type::vm_none) {
return;
}
std::clog << "\nglobal (0x" << std::hex
@ -266,7 +269,7 @@ void vm::local_state() {
}
void vm::upvalue_state() {
if (ctx.funcr.type==vm_nil || ctx.funcr.func().upval.empty()) {
if (ctx.funcr.type==vm_type::vm_nil || ctx.funcr.func().upval.empty()) {
return;
}
std::clog << "\nupvalue\n";
@ -326,7 +329,7 @@ std::string vm::report_special_call_lack_arguments(
argument_list[i.second-1] = i.first;
}
for(const auto& key : argument_list) {
if (local[func.keys.at(key)].type==vm_none) {
if (local[func.keys.at(key)].type==vm_type::vm_none) {
result += key + ", ";
} else {
result += key + "[get], ";
@ -366,20 +369,20 @@ std::string vm::report_out_of_range(f64 index, usize real_size) const {
std::string vm::type_name_string(const var& value) const {
switch(value.type) {
case vm_none: return "none";
case vm_cnt: return "counter";
case vm_addr: return "address";
case vm_ret: return "program counter";
case vm_nil: return "nil";
case vm_num: return "number";
case vm_str: return "string";
case vm_vec: return "vector";
case vm_hash: return "hash";
case vm_func: return "function";
case vm_upval: return "upvalue";
case vm_obj: return "ghost type";
case vm_co: return "coroutine";
case vm_map: return "namespace";
case vm_type::vm_none: return "none";
case vm_type::vm_cnt: return "counter";
case vm_type::vm_addr: return "address";
case vm_type::vm_ret: return "program counter";
case vm_type::vm_nil: return "nil";
case vm_type::vm_num: return "number";
case vm_type::vm_str: return "string";
case vm_type::vm_vec: return "vector";
case vm_type::vm_hash: return "hash";
case vm_type::vm_func: return "function";
case vm_type::vm_upval: return "upvalue";
case vm_type::vm_obj: return "ghost type";
case vm_type::vm_co: return "coroutine";
case vm_type::vm_map: return "namespace";
}
return "unknown";
}

View File

@ -195,9 +195,9 @@ public:
};
inline bool vm::cond(var& val) {
if (val.type==vm_num) {
if (val.type==vm_type::vm_num) {
return val.num();
} else if (val.type==vm_str) {
} else if (val.type==vm_type::vm_str) {
const f64 num = str2num(val.str().c_str());
return std::isnan(num)? !val.str().empty():num;
}
@ -242,7 +242,7 @@ inline void vm::o_pstr() {
}
inline void vm::o_newv() {
var newv = ngc.alloc(vm_vec);
var newv = ngc.alloc(vm_type::vm_vec);
auto& vec = newv.vec().elems;
vec.resize(imm[ctx.pc]);
// use top-=imm[pc]-1 here will cause error if imm[pc] is 0
@ -254,11 +254,11 @@ inline void vm::o_newv() {
}
inline void vm::o_newh() {
(++ctx.top)[0] = ngc.alloc(vm_hash);
(++ctx.top)[0] = ngc.alloc(vm_type::vm_hash);
}
inline void vm::o_newf() {
(++ctx.top)[0] = ngc.alloc(vm_func);
(++ctx.top)[0] = ngc.alloc(vm_type::vm_func);
auto& func = ctx.top[0].func();
func.entry = imm[ctx.pc];
func.parameter_size = 1;
@ -268,7 +268,9 @@ inline void vm::o_newf() {
func.upval = ctx.funcr.func().upval;
// function created in the same local scope shares one closure
// so this size & stk setting has no problem
var upval = (ctx.upvalr.type==vm_nil)? ngc.alloc(vm_upval):ctx.upvalr;
var upval = (ctx.upvalr.type==vm_type::vm_nil)?
ngc.alloc(vm_type::vm_upval):
ctx.upvalr;
upval.upval().size = ctx.funcr.func().local_size;
upval.upval().stack_frame_offset = ctx.localr;
func.upval.push_back(upval);
@ -303,9 +305,9 @@ inline void vm::o_dyn() {
inline void vm::o_lnot() {
var val = ctx.top[0];
switch(val.type) {
case vm_nil: ctx.top[0] = one; break;
case vm_num: ctx.top[0] = val.num()? zero:one; break;
case vm_str: {
case vm_type::vm_nil: ctx.top[0] = one; break;
case vm_type::vm_num: ctx.top[0] = val.num()? zero:one; break;
case vm_type::vm_str: {
const f64 num = str2num(val.str().c_str());
if (std::isnan(num)) {
ctx.top[0] = var::num(static_cast<f64>(val.str().empty()));
@ -361,8 +363,8 @@ inline void vm::o_mul() {op_calc(*);}
inline void vm::o_div() {op_calc(/);}
inline void vm::o_lnk() {
// concat two vectors into one
if (ctx.top[-1].type==vm_vec && ctx.top[0].type==vm_vec) {
ngc.temp = ngc.alloc(vm_vec);
if (ctx.top[-1].type==vm_type::vm_vec && ctx.top[0].type==vm_type::vm_vec) {
ngc.temp = ngc.alloc(vm_type::vm_vec);
for(auto i : ctx.top[-1].vec().elems) {
ngc.temp.vec().elems.push_back(i);
}
@ -496,12 +498,12 @@ inline void vm::o_meq() {
inline void vm::o_eq() {
var val2 = ctx.top[0];
var val1 = (--ctx.top)[0];
if (val1.type==vm_nil && val2.type==vm_nil) {
if (val1.type==vm_type::vm_nil && val2.type==vm_type::vm_nil) {
ctx.top[0] = one;
} else if (val1.type==vm_str && val2.type==vm_str) {
} else if (val1.type==vm_type::vm_str && val2.type==vm_type::vm_str) {
ctx.top[0] = (val1.str()==val2.str())? one:zero;
} else if ((val1.type==vm_num || val2.type==vm_num)
&& val1.type!=vm_nil && val2.type!=vm_nil) {
} else if ((val1.type==vm_type::vm_num || val2.type==vm_type::vm_num)
&& val1.type!=vm_type::vm_nil && val2.type!=vm_type::vm_nil) {
ctx.top[0] = (val1.to_num()==val2.to_num())? one:zero;
} else {
ctx.top[0] = (val1==val2)? one:zero;
@ -511,12 +513,12 @@ inline void vm::o_eq() {
inline void vm::o_neq() {
var val2 = ctx.top[0];
var val1 = (--ctx.top)[0];
if (val1.type==vm_nil && val2.type==vm_nil) {
if (val1.type==vm_type::vm_nil && val2.type==vm_type::vm_nil) {
ctx.top[0] = zero;
} else if (val1.type==vm_str && val2.type==vm_str) {
} else if (val1.type==vm_type::vm_str && val2.type==vm_type::vm_str) {
ctx.top[0] = (val1.str()!=val2.str())? one:zero;
} else if ((val1.type==vm_num || val2.type==vm_num)
&& val1.type!=vm_nil && val2.type!=vm_nil) {
} else if ((val1.type==vm_type::vm_num || val2.type==vm_type::vm_num)
&& val1.type!=vm_type::vm_nil && val2.type!=vm_type::vm_nil) {
ctx.top[0] = (val1.to_num()!=val2.to_num())? one:zero;
} else {
ctx.top[0] = (val1!=val2)? one:zero;
@ -565,7 +567,7 @@ inline void vm::o_jf() {
}
inline void vm::o_cnt() {
if (ctx.top[0].type!=vm_vec) {
if (ctx.top[0].type!=vm_type::vm_vec) {
die("must use vector in forindex/foreach but get "+
type_name_string(ctx.top[0])
);
@ -611,25 +613,25 @@ inline void vm::o_upval() {
inline void vm::o_callv() {
var val = ctx.top[0];
var vec = (--ctx.top)[0];
if (vec.type==vm_vec) {
if (vec.type==vm_type::vm_vec) {
ctx.top[0] = vec.vec().get_value(val.to_num());
if (ctx.top[0].type==vm_none) {
if (ctx.top[0].type==vm_type::vm_none) {
die(report_out_of_range(val.to_num(), vec.vec().size()));
return;
}
} else if (vec.type==vm_hash) {
if (val.type!=vm_str) {
} else if (vec.type==vm_type::vm_hash) {
if (val.type!=vm_type::vm_str) {
die("must use string as the key but get "+type_name_string(val));
return;
}
ctx.top[0] = vec.hash().get_value(val.str());
if (ctx.top[0].type==vm_none) {
if (ctx.top[0].type==vm_type::vm_none) {
die(report_key_not_found(val.str(), vec.hash()));
return;
} else if (ctx.top[0].type==vm_func) {
} else if (ctx.top[0].type==vm_type::vm_func) {
ctx.top[0].func().local[0] = val; // 'me'
}
} else if (vec.type==vm_str) {
} else if (vec.type==vm_type::vm_str) {
const auto& str = vec.str();
i32 num = val.to_num();
i32 len = str.length();
@ -640,13 +642,13 @@ inline void vm::o_callv() {
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) {
} else if (vec.type==vm_type::vm_map) {
if (val.type!=vm_type::vm_str) {
die("must use string as the key but get "+type_name_string(val));
return;
}
ctx.top[0] = vec.map().get_value(val.str());
if (ctx.top[0].type==vm_none) {
if (ctx.top[0].type==vm_type::vm_none) {
die("cannot find symbol \""+val.str()+"\"");
return;
}
@ -658,13 +660,13 @@ inline void vm::o_callv() {
inline void vm::o_callvi() {
var val = ctx.top[0];
if (val.type!=vm_vec) {
if (val.type!=vm_type::vm_vec) {
die("must use a vector but get "+type_name_string(val));
return;
}
// cannot use operator[],because this may cause overflow
(++ctx.top)[0] = val.vec().get_value(imm[ctx.pc]);
if (ctx.top[0].type==vm_none) {
if (ctx.top[0].type==vm_type::vm_none) {
die(report_out_of_range(imm[ctx.pc], val.vec().size()));
return;
}
@ -672,22 +674,22 @@ inline void vm::o_callvi() {
inline void vm::o_callh() {
var val = ctx.top[0];
if (val.type!=vm_hash && val.type!=vm_map) {
if (val.type!=vm_type::vm_hash && val.type!=vm_type::vm_map) {
die("must call a hash but get "+type_name_string(val));
return;
}
const auto& str = const_string[imm[ctx.pc]];
if (val.type==vm_hash) {
if (val.type==vm_type::vm_hash) {
ctx.top[0] = val.hash().get_value(str);
} else {
ctx.top[0] = val.map().get_value(str);
}
if (ctx.top[0].type==vm_none) {
val.type==vm_hash?
if (ctx.top[0].type==vm_type::vm_none) {
val.type==vm_type::vm_hash?
die(report_key_not_found(str, val.hash())):
die("cannot find symbol \"" + str + "\"");
return;
} else if (ctx.top[0].type==vm_func) {
} else if (ctx.top[0].type==vm_type::vm_func) {
ctx.top[0].func().local[0] = val; // 'me'
}
}
@ -695,7 +697,7 @@ inline void vm::o_callh() {
inline void vm::o_callfv() {
const u32 argc = imm[ctx.pc]; // arguments counter
var* local = ctx.top-argc+1; // arguments begin address
if (local[-1].type!=vm_func) {
if (local[-1].type!=vm_type::vm_func) {
die("must call a function but get "+type_name_string(local[-1]));
return;
}
@ -713,7 +715,7 @@ inline void vm::o_callfv() {
}
// parameter size is func->psize-1, 1 is reserved for "me"
const u32 parameter_size = func.parameter_size-1;
if (argc<parameter_size && func.local[argc+1].type==vm_none) {
if (argc<parameter_size && func.local[argc+1].type==vm_type::vm_none) {
die(report_lack_arguments(argc, func));
return;
}
@ -722,13 +724,13 @@ inline void vm::o_callfv() {
var dynamic = nil;
if (func.dynamic_parameter_index>=0) {
// load dynamic argument
dynamic = ngc.alloc(vm_vec);
dynamic = ngc.alloc(vm_type::vm_vec);
for(u32 i = parameter_size; i<argc; ++i) {
dynamic.vec().elems.push_back(local[i]);
}
} else if (parameter_size<argc) {
// load arguments to default dynamic argument "arg", located at stack+1
dynamic = ngc.alloc(vm_vec);
dynamic = ngc.alloc(vm_type::vm_vec);
for(u32 i = parameter_size; i<argc; ++i) {
dynamic.vec().elems.push_back(local[i]);
}
@ -764,7 +766,7 @@ inline void vm::o_callfv() {
inline void vm::o_callfh() {
const auto& hash = ctx.top[0].hash().elems;
if (ctx.top[-1].type!=vm_func) {
if (ctx.top[-1].type!=vm_type::vm_func) {
die("must call a function but get "+type_name_string(ctx.top[-1]));
return;
}
@ -797,7 +799,7 @@ inline void vm::o_callfh() {
const auto& key = i.first;
if (hash.count(key)) {
local[i.second] = hash.at(key);
} else if (local[i.second].type==vm_none) {
} else if (local[i.second].type==vm_type::vm_none) {
lack_arguments_flag = true;
}
}
@ -829,7 +831,7 @@ inline void vm::o_callb() {
ctx.top[0] = result;
// if get none, this means errors occurred when calling this native function
if (ctx.top[0].type==vm_none) {
if (ctx.top[0].type==vm_type::vm_none) {
die("error occurred in native function");
return;
}
@ -841,8 +843,8 @@ inline void vm::o_slcbeg() {
// +--------------+
// | resource_vec | <-- top[-1]
// +--------------+
(++ctx.top)[0] = ngc.alloc(vm_vec);
if (ctx.top[-1].type!=vm_vec) {
(++ctx.top)[0] = ngc.alloc(vm_type::vm_vec);
if (ctx.top[-1].type!=vm_type::vm_vec) {
die("must slice a vector but get "+type_name_string(ctx.top[-1]));
return;
}
@ -856,7 +858,7 @@ inline void vm::o_slcend() {
inline void vm::o_slc() {
var val = (ctx.top--)[0];
var res = ctx.top[-1].vec().get_value(val.to_num());
if (res.type==vm_none) {
if (res.type==vm_type::vm_none) {
die(report_out_of_range(val.to_num(), ctx.top[-1].vec().size()));
return;
}
@ -869,16 +871,17 @@ inline void vm::o_slc2() {
const auto& ref = ctx.top[-1].vec().elems;
auto& aim = ctx.top[0].vec().elems;
u8 type1 = val1.type,type2=val2.type;
vm_type type1 = val1.type;
vm_type type2 = val2.type;
i32 num1 = val1.to_num();
i32 num2 = val2.to_num();
i32 size = ref.size();
if (type1==vm_nil && type2==vm_nil) {
if (type1==vm_type::vm_nil && type2==vm_type::vm_nil) {
num1 = 0;
num2 = size-1;
} else if (type1==vm_nil && type2!=vm_nil) {
} else if (type1==vm_type::vm_nil && type2!=vm_type::vm_nil) {
num1 = num2<0? -size:0;
} else if (type1!=vm_nil && type2==vm_nil) {
} else if (type1!=vm_type::vm_nil && type2==vm_type::vm_nil) {
num2 = num1<0? -1:size-1;
}
@ -923,14 +926,14 @@ inline void vm::o_mupval() {
inline void vm::o_mcallv() {
var val = ctx.top[0]; // index
var vec = (--ctx.top)[0]; // mcall vector, reserved on stack to avoid gc
if (vec.type==vm_vec) {
if (vec.type==vm_type::vm_vec) {
ctx.memr = vec.vec().get_memory(val.to_num());
if (!ctx.memr) {
die(report_out_of_range(val.to_num(), vec.vec().size()));
return;
}
} else if (vec.type==vm_hash) { // do mcallh but use the mcallv way
if (val.type!=vm_str) {
} else if (vec.type==vm_type::vm_hash) { // do mcallh but use the mcallv way
if (val.type!=vm_type::vm_str) {
die("must use string as the key but get "+type_name_string(val));
return;
}
@ -941,8 +944,8 @@ inline void vm::o_mcallv() {
ref.elems[str] = nil;
ctx.memr = ref.get_memory(str);
}
} else if (vec.type==vm_map) {
if (val.type!=vm_str) {
} else if (vec.type==vm_type::vm_map) {
if (val.type!=vm_type::vm_str) {
die("must use string as the key but get "+type_name_string(val));
return;
}
@ -960,12 +963,12 @@ inline void vm::o_mcallv() {
inline void vm::o_mcallh() {
var hash = ctx.top[0]; // mcall hash, reserved on stack to avoid gc
if (hash.type!=vm_hash && hash.type!=vm_map) {
if (hash.type!=vm_type::vm_hash && hash.type!=vm_type::vm_map) {
die("must call a hash/namespace but get "+type_name_string(hash));
return;
}
const auto& str = const_string[imm[ctx.pc]];
if (hash.type==vm_map) {
if (hash.type==vm_type::vm_map) {
ctx.memr = hash.map().get_memory(str);
if (!ctx.memr) {
die("cannot find symbol \"" + str + "\"");
@ -1010,7 +1013,7 @@ inline void vm::o_ret() {
ctx.top[0] = ret; // rewrite func with returned value
// synchronize upvalue
if (up.type==vm_upval) {
if (up.type==vm_type::vm_upval) {
auto& upval = up.upval();
auto size = func.func().local_size;
upval.on_stack = false;

View File

@ -15,7 +15,7 @@ void dir_entry_destructor(void* ptr) {
var builtin_pipe(context* ctx, gc* ngc) {
#ifndef _WIN32
i32 fd[2];
var res = ngc->alloc(vm_vec);
var res = ngc->alloc(vm_type::vm_vec);
if (pipe(fd)==-1) {
return nas_err("unix::pipe", "failed to create pipe");
}
@ -40,13 +40,13 @@ var builtin_fork(context* ctx, gc* ngc) {
var builtin_waitpid(context* ctx, gc* ngc) {
auto pid = ctx->localr[1];
auto nohang = ctx->localr[2];
if (pid.type!=vm_num || nohang.type!=vm_num) {
if (pid.type!=vm_type::vm_num || nohang.type!=vm_type::vm_num) {
return nas_err("unix::waitpid", "pid and nohang must be number");
}
#ifndef _WIN32
i32 ret_pid, status;
ret_pid = waitpid(pid.num(), &status, nohang.num()==0? 0:WNOHANG);
var vec = ngc->alloc(vm_vec);
var vec = ngc->alloc(vm_type::vm_vec);
vec.vec().elems.push_back(var::num(static_cast<f64>(ret_pid)));
vec.vec().elems.push_back(var::num(static_cast<f64>(status)));
return vec;
@ -56,7 +56,7 @@ var builtin_waitpid(context* ctx, gc* ngc) {
var builtin_opendir(context* ctx, gc* ngc) {
auto path = ctx->localr[1];
if (path.type!=vm_str) {
if (path.type!=vm_type::vm_str) {
return nas_err("unix::opendir", "\"path\" must be string");
}
#ifdef _MSC_VER
@ -72,7 +72,7 @@ var builtin_opendir(context* ctx, gc* ngc) {
return nas_err("unix::opendir", "cannot open dir <"+path.str()+">");
}
#endif
var ret = ngc->alloc(vm_obj);
var ret = ngc->alloc(vm_type::vm_obj);
ret.ghost().set(dir_type_name, dir_entry_destructor, nullptr, p);
return ret;
}
@ -105,14 +105,14 @@ var builtin_closedir(context* ctx, gc* ngc) {
var builtin_chdir(context* ctx, gc* ngc) {
auto path = ctx->localr[1];
if (path.type!=vm_str) {
if (path.type!=vm_type::vm_str) {
return var::num(-1.0);
}
return var::num(static_cast<f64>(chdir(path.str().c_str())));
}
var builtin_environ(context* ctx, gc* ngc) {
var res = ngc->temp = ngc->alloc(vm_vec);
var res = ngc->temp = ngc->alloc(vm_type::vm_vec);
auto& vec = res.vec().elems;
for(char** env = environ; *env; ++env) {
vec.push_back(ngc->newstr(*env));
@ -131,7 +131,7 @@ var builtin_getcwd(context* ctx, gc* ngc) {
var builtin_getenv(context* ctx, gc* ngc) {
auto envvar = ctx->localr[1];
if (envvar.type!=vm_str) {
if (envvar.type!=vm_type::vm_str) {
return nas_err("unix::getenv", "\"envvar\" must be string");
}
char* res = getenv(envvar.str().c_str());