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 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( res.ghost().set(
ghost_for_test, ghost_for_test,
ghost_for_test_destructor, ghost_for_test_destructor,

View File

@ -6,14 +6,14 @@
namespace nasal { namespace nasal {
var nas_vec2(var* args, usize size, gc* ngc) { 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[0]);
res.vec().elems.push_back(args[1]); res.vec().elems.push_back(args[1]);
return res; return res;
} }
var nas_vec3(var* args, usize size, gc* ngc) { 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[0]);
res.vec().elems.push_back(args[1]); res.vec().elems.push_back(args[1]);
res.vec().elems.push_back(args[2]); 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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2) if (v0.size()!=2 || v1.size()!=2)
return nil; 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[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[1].num()+v1[1].num()));
return res; return res;
} }
var nas_vec2_sub(var* args, usize size, gc* ngc) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2) if (v0.size()!=2 || v1.size()!=2)
return nil; 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[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[1].num()-v1[1].num()));
return res; return res;
} }
var nas_vec2_mult(var* args, usize size, gc* ngc) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2) if (v0.size()!=2 || v1.size()!=2)
return nil; 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[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[1].num()*v1[1].num()));
return res; return res;
} }
var nas_vec2_div(var* args, usize size, gc* ngc) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=2 || v1.size()!=2) if (v0.size()!=2 || v1.size()!=2)
return nil; 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[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[1].num()/v1[1].num()));
return res; return res;
} }
var nas_vec2_neg(var* args, usize size, gc* ngc) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=2) if (v0.size()!=2)
return nil; 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[0].num()));
res.vec().elems.push_back(var::num(-v0[1].num())); res.vec().elems.push_back(var::num(-v0[1].num()));
return res; return res;
} }
var nas_vec2_norm(var* args, usize size, gc* ngc) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=2) if (v0.size()!=2)
@ -93,14 +93,14 @@ var nas_vec2_norm(var* args, usize size, gc* ngc) {
auto x = v0[0].num(); auto x = v0[0].num();
auto y = v0[1].num(); auto y = v0[1].num();
auto t = std::sqrt(x*x+y*y); 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(x/t));
res.vec().elems.push_back(var::num(y/t)); res.vec().elems.push_back(var::num(y/t));
return res; return res;
} }
var nas_vec2_len(var* args, usize size, gc* ngc) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=2) 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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3) if (v0.size()!=3 || v1.size()!=3)
return nil; 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[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[1].num()+v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()+v1[2].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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3) if (v0.size()!=3 || v1.size()!=3)
return nil; 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[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[1].num()-v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()-v1[2].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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3) if (v0.size()!=3 || v1.size()!=3)
return nil; 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[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[1].num()*v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()*v1[2].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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;
if (v0.size()!=3 || v1.size()!=3) if (v0.size()!=3 || v1.size()!=3)
return nil; 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[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[1].num()/v1[1].num()));
res.vec().elems.push_back(var::num(v0[2].num()/v1[2].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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=3) if (v0.size()!=3)
return nil; 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[0].num()));
res.vec().elems.push_back(var::num(-v0[1].num())); res.vec().elems.push_back(var::num(-v0[1].num()));
res.vec().elems.push_back(var::num(-v0[2].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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=3) if (v0.size()!=3)
@ -199,7 +199,7 @@ var nas_vec3_norm(var* args, usize size, gc* ngc) {
auto y = v0[1].num(); auto y = v0[1].num();
auto z = v0[2].num(); auto z = v0[2].num();
auto t = std::sqrt(x*x+y*y+z*z); 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(x/t));
res.vec().elems.push_back(var::num(y/t)); res.vec().elems.push_back(var::num(y/t));
res.vec().elems.push_back(var::num(z/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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=3) 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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=3) if (v0.size()!=3)
return nil; return nil;
auto angle = args[1].num(); 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[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::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))); 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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=3) if (v0.size()!=3)
return nil; return nil;
auto angle = args[1].num(); 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[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[1].num()));
res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[2].num()*std::cos(angle))); 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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
if (v0.size()!=3) if (v0.size()!=3)
return nil; return nil;
auto angle = args[1].num(); 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::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[0].num()*std::sin(angle)+v0[1].num()*std::cos(angle)));
res.vec().elems.push_back(var::num(v0[2].num())); 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) { 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; return nil;
auto& v0 = args[0].vec().elems; auto& v0 = args[0].vec().elems;
auto& v1 = args[1].vec().elems; auto& v1 = args[1].vec().elems;

View File

@ -33,14 +33,14 @@ static WSAmanager win;
namespace nasal { namespace nasal {
var nas_socket(var* args, usize size, gc* ngc) { 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"); return nas_err("socket", "\"af\", \"type\", \"protocol\" should be number");
int sd = socket(args[0].num(), args[1].num(), args[2].num()); int sd = socket(args[0].num(), args[1].num(), args[2].num());
return var::num(static_cast<double>(sd)); return var::num(static_cast<double>(sd));
} }
var nas_closesocket(var* args, usize size, gc* ngc) { 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"); return nas_err("closesocket", "\"sd\" should be number");
#ifdef _WIN32 #ifdef _WIN32
return var::num(static_cast<double>(closesocket(args[0].num()))); 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) { 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"); 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 nas_err("shutdown", "\"how\" must be a number");
return var::num(static_cast<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) { 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"); 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"); 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"); return nas_err("bind", "\"port\" must be a number");
sockaddr_in server; sockaddr_in server;
memset(&server, 0, sizeof(sockaddr_in)); 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) { 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"); 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 nas_err("listen", "\"backlog\" must be a number");
return var::num(static_cast<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) { 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"); 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"); 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"); return nas_err("connect", "\"port\" must be a number");
sockaddr_in addr; sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in)); 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) { 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"); return nas_err("accept", "\"sd\" must be a number");
sockaddr_in client; sockaddr_in client;
int socklen = sizeof(sockaddr_in); int socklen = sizeof(sockaddr_in);
@ -122,7 +122,7 @@ var nas_accept(var* args, usize size, gc* ngc) {
reinterpret_cast<socklen_t*>(&socklen) reinterpret_cast<socklen_t*>(&socklen)
); );
#endif #endif
var res = ngc->temp = ngc->alloc(vm_hash); var res = ngc->temp = ngc->alloc(vm_type::vm_hash);
auto& hash = res.hash().elems; auto& hash = res.hash().elems;
hash["sd"] = var::num(static_cast<double>(client_sd)); hash["sd"] = var::num(static_cast<double>(client_sd));
hash["ip"] = ngc->newstr(inet_ntoa(client.sin_addr)); 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) { 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"); 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"); 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 nas_err("send", "\"flags\" muse be a number");
return var::num(static_cast<double>(send( return var::num(static_cast<double>(send(
args[0].num(), 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) { 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"); 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"); 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"); 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"); 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"); return nas_err("sendto", "\"flags\" must be a number");
sockaddr_in addr; sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in)); 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) { 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"); 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"); return nas_err("recv", "\"len\" must be a number");
if (args[1].num()<=0 || args[1].num()>16*1024*1024) if (args[1].num()<=0 || args[1].num()>16*1024*1024)
return nas_err("recv", "\"len\" out of range"); 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"); 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; auto& hash = res.hash().elems;
char* buf = new char[static_cast<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()); 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) { 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"); 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"); return nas_err("recvfrom", "\"len\" must be a number");
if (args[1].num()<=0 || args[1].num()>16*1024*1024) if (args[1].num()<=0 || args[1].num()>16*1024*1024)
return nas_err("recvfrom", "\"len\" out of range"); 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"); return nas_err("recvfrom", "\"flags\" muse be a number");
sockaddr_in addr; sockaddr_in addr;
int socklen = sizeof(sockaddr_in); 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; auto& hash = res.hash().elems;
char* buf = new char[static_cast<int>(args[1].num()+1)]; char* buf = new char[static_cast<int>(args[1].num()+1)];
#ifdef _WIN32 #ifdef _WIN32

View File

@ -48,10 +48,10 @@ var builtin_fld(context* ctx, gc* ngc) {
auto str = local[1]; auto str = local[1];
auto startbit = local[2]; auto startbit = local[2];
auto length = local[3]; 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"); 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"); return nas_err("bits::fld", "\"startbit\",\"len\" must be number");
} }
u32 bit = static_cast<u32>(startbit.num()); u32 bit = static_cast<u32>(startbit.num());
@ -78,10 +78,10 @@ var builtin_sfld(context* ctx, gc* ngc) {
auto str = local[1]; auto str = local[1];
auto startbit = local[2]; auto startbit = local[2];
auto length = local[3]; 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"); 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"); return nas_err("bits::sfld", "\"startbit\",\"len\" must be number");
} }
u32 bit = static_cast<u32>(startbit.num()); u32 bit = static_cast<u32>(startbit.num());
@ -112,10 +112,12 @@ var builtin_setfld(context* ctx, gc* ngc) {
auto startbit = local[2]; auto startbit = local[2];
auto length = local[3]; auto length = local[3];
auto value = local[4]; 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"); 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", return nas_err("bits::setfld",
"\"startbit\", \"len\", \"val\" must be number" "\"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 builtin_buf(context* ctx, gc* ngc) {
var length = ctx->localr[1]; 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"); 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(); auto& s = str.str();
s.resize(length.num(), '\0'); s.resize(length.num(), '\0');
return str; return str;

View File

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

View File

@ -15,7 +15,7 @@ void dynamic_library_destructor(void* pointer) {
var builtin_dlopen(context* ctx, gc* ngc) { var builtin_dlopen(context* ctx, gc* ngc) {
auto dlname = ctx->localr[1]; 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"); 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() + ">" "cannot open dynamic lib <" + dlname.str() + ">"
); );
} }
auto return_hash = ngc->temp = ngc->alloc(vm_hash); auto return_hash = ngc->temp = ngc->alloc(vm_type::vm_hash);
auto library_object = ngc->alloc(vm_obj); auto library_object = ngc->alloc(vm_type::vm_obj);
library_object.ghost().set( library_object.ghost().set(
dynamic_library_type_name, dynamic_library_type_name,
dynamic_library_destructor, dynamic_library_destructor,
@ -73,7 +73,7 @@ var builtin_dlopen(context* ctx, gc* ngc) {
} }
for(u32 i = 0; table[i].name; ++i) { for(u32 i = 0; table[i].name; ++i) {
auto function_pointer = reinterpret_cast<void*>(table[i].fd); 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_object.ghost().set(
function_address_type_name, function_address_type_name,
nullptr, nullptr,

View File

@ -8,7 +8,7 @@ var builtin_logprint(context* ctx, gc* ngc) {
auto local = ctx->localr; auto local = ctx->localr;
auto level = local[1]; auto level = local[1];
auto elems = local[2]; 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."); return nas_err("fg_env::logprint", "received argument is not vector.");
} }
std::ofstream out("fgfs.log", std::ios::app); 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) { var builtin_readfile(context* ctx, gc* ngc) {
auto filename = ctx->localr[1]; 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"); return nas_err("io::readfile", "\"filename\" must be string");
} }
std::ifstream in(filename.str(), std::ios::binary); std::ifstream in(filename.str(), std::ios::binary);
@ -25,7 +25,7 @@ var builtin_fout(context* ctx, gc* ngc) {
auto local = ctx->localr; auto local = ctx->localr;
auto filename = local[1]; auto filename = local[1];
auto source = local[2]; 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"); return nas_err("io::fout", "\"filename\" must be string");
} }
std::ofstream out(filename.str()); std::ofstream out(filename.str());
@ -38,7 +38,7 @@ var builtin_fout(context* ctx, gc* ngc) {
var builtin_exists(context* ctx, gc* ngc) { var builtin_exists(context* ctx, gc* ngc) {
auto filename = ctx->localr[1]; auto filename = ctx->localr[1];
if (filename.type!=vm_str) { if (filename.type!=vm_type::vm_str) {
return zero; return zero;
} }
return access(filename.str().c_str(), F_OK)!=-1? one: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 local = ctx->localr;
auto name = local[1]; auto name = local[1];
auto mode = local[2]; 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"); 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"); return nas_err("io::open", "\"mode\" must be string");
} }
auto file_descriptor = fopen(name.str().c_str(), mode.str().c_str()); auto file_descriptor = fopen(name.str().c_str(), mode.str().c_str());
if (!file_descriptor) { if (!file_descriptor) {
return nas_err("io::open", "failed to open file <" + name.str() + ">"); 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( return_object.ghost().set(
file_type_name, filehandle_destructor, nullptr, file_descriptor 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)) { if (!file_descriptor.object_check(file_type_name)) {
return nas_err("io::read", "not a valid filehandle"); 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"); 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"); return nas_err("io::read", "\"len\" must be number");
} }
if (length.num()<=0 || length.num()>=(1<<30)) { 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)) { if (!file_descriptor.object_check(file_type_name)) {
return nas_err("io::write", "not a valid filehandle"); 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 nas_err("io::write", "\"str\" must be string");
} }
return var::num(static_cast<f64>(fwrite( 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)) { if (!file_descriptor.object_check(file_type_name)) {
return nas_err("io::readln", "not a valid filehandle"); 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; char c;
while((c = fgetc(static_cast<FILE*>(file_descriptor.ghost().pointer)))!=EOF) { while((c = fgetc(static_cast<FILE*>(file_descriptor.ghost().pointer)))!=EOF) {
if (c=='\r') { if (c=='\r') {
@ -170,14 +170,14 @@ var builtin_readln(context* ctx, gc* ngc) {
var builtin_stat(context* ctx, gc* ngc) { var builtin_stat(context* ctx, gc* ngc) {
auto name = ctx->localr[1]; 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"); return nas_err("io::stat", "\"filename\" must be string");
} }
struct stat buffer; struct stat buffer;
if (stat(name.str().c_str(), &buffer)<0) { if (stat(name.str().c_str(), &buffer)<0) {
return nas_err("io::stat", "failed to open file <" + name.str() + ">"); 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 = { result.vec().elems = {
var::num(static_cast<f64>(buffer.st_dev)), var::num(static_cast<f64>(buffer.st_dev)),
var::num(static_cast<f64>(buffer.st_ino)), 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) { 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); file_descriptor.ghost().set(file_type_name, nullptr, nullptr, stdin);
return file_descriptor; return file_descriptor;
} }
var builtin_stdout(context* ctx, gc* ngc) { 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); file_descriptor.ghost().set(file_type_name, nullptr, nullptr, stdout);
return file_descriptor; return file_descriptor;
} }
var builtin_stderr(context* ctx, gc* ngc) { 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); file_descriptor.ghost().set(file_type_name, nullptr, nullptr, stderr);
return file_descriptor; return file_descriptor;
} }

View File

@ -5,7 +5,7 @@ namespace nasal {
var builtin_pow(context* ctx, gc* ngc) { var builtin_pow(context* ctx, gc* ngc) {
auto x = ctx->localr[1]; auto x = ctx->localr[1];
auto y = ctx->localr[2]; 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::nan(""));
} }
return var::num(std::pow(x.num(), y.num())); 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) { var builtin_sin(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; 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) { var builtin_cos(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; 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) { var builtin_tan(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; 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) { var builtin_exp(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; 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) { var builtin_lg(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; 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) { var builtin_ln(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; 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) { var builtin_sqrt(context* ctx, gc* ngc) {
auto val = ctx->localr[1]; 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) { var builtin_atan2(context* ctx, gc* ngc) {
auto x = ctx->localr[1]; auto x = ctx->localr[1];
auto y = ctx->localr[2]; 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::nan(""));
} }
return var::num(atan2(y.num(), x.num())); 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) { var builtin_isnan(context* ctx, gc* ngc) {
auto x = ctx->localr[1]; 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[] = { nasal_builtin_table math_lib_native[] = {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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