Merge pull request #28 from ValKmjolnir/develop
✨ finish simple repl interpreter (experimental)
This commit is contained in:
commit
38920382ea
|
@ -3,7 +3,8 @@
|
|||
#include <iostream>
|
||||
#include "../src/nasal.h"
|
||||
|
||||
namespace nasal_fib_module {
|
||||
namespace nasal {
|
||||
namespace fib_module {
|
||||
|
||||
double fibonaci(double x) {
|
||||
if (x<=2) {
|
||||
|
@ -41,9 +42,10 @@ const auto ghost_for_test = "ghost_for_test";
|
|||
|
||||
void ghost_for_test_destructor(void* ptr) {
|
||||
std::cout << "ghost_for_test::destructor (0x";
|
||||
std::cout << std::hex << (u64)ptr << std::dec << ") {\n";
|
||||
delete (u32*)ptr;
|
||||
std::cout << " delete 0x" << std::hex << (u64)ptr << std::dec << ";\n";
|
||||
std::cout << std::hex << reinterpret_cast<u64>(ptr) << std::dec << ") {\n";
|
||||
delete static_cast<u32*>(ptr);
|
||||
std::cout << " delete 0x" << std::hex;
|
||||
std::cout << reinterpret_cast<u64>(ptr) << std::dec << ";\n";
|
||||
std::cout << "}\n";
|
||||
}
|
||||
|
||||
|
@ -88,5 +90,7 @@ module_func_info func_tbl[] = {
|
|||
}
|
||||
|
||||
extern "C" module_func_info* get() {
|
||||
return nasal_fib_module::func_tbl;
|
||||
return fib_module::func_tbl;
|
||||
}
|
||||
|
||||
}
|
|
@ -12,46 +12,50 @@
|
|||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
namespace nasal {
|
||||
|
||||
class noecho_input {
|
||||
private:
|
||||
#ifndef _WIN32
|
||||
struct termios init_termios;
|
||||
struct termios new_termios;
|
||||
int peek_char=-1;
|
||||
int peek_char = -1;
|
||||
#endif
|
||||
public:
|
||||
noecho_input() {
|
||||
#ifndef _WIN32
|
||||
tcflush(0, TCIOFLUSH);
|
||||
tcgetattr(0, &init_termios);
|
||||
new_termios=init_termios;
|
||||
new_termios.c_lflag&=~(ICANON|ECHO|ECHONL|ECHOE);
|
||||
new_termios = init_termios;
|
||||
new_termios.c_lflag &= ~(ICANON|ECHO|ECHONL|ECHOE);
|
||||
// vmin=0 is nonblock input, but in wsl there is a bug that will block input
|
||||
// so we use fcntl to write the nonblock input
|
||||
new_termios.c_cc[VMIN]=1;
|
||||
new_termios.c_cc[VTIME]=0;
|
||||
new_termios.c_cc[VMIN] = 1;
|
||||
new_termios.c_cc[VTIME] = 0;
|
||||
tcsetattr(0, TCSANOW, &new_termios);
|
||||
#endif
|
||||
}
|
||||
|
||||
~noecho_input() {
|
||||
#ifndef _WIN32
|
||||
tcflush(0, TCIOFLUSH);
|
||||
tcsetattr(0, TCSANOW, &init_termios);
|
||||
#endif
|
||||
}
|
||||
|
||||
int noecho_kbhit() {
|
||||
#ifndef _WIN32
|
||||
unsigned char ch=0;
|
||||
int nread=0;
|
||||
unsigned char ch = 0;
|
||||
int nread = 0;
|
||||
if (peek_char!=-1) {
|
||||
return 1;
|
||||
}
|
||||
int flag=fcntl(0, F_GETFL);
|
||||
int flag = fcntl(0, F_GETFL);
|
||||
fcntl(0, F_SETFL,flag|O_NONBLOCK);
|
||||
nread=read(0, &ch, 1);
|
||||
nread = read(0, &ch, 1);
|
||||
fcntl(0, F_SETFL, flag);
|
||||
if (nread==1) {
|
||||
peek_char=ch;
|
||||
peek_char = ch;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -59,15 +63,16 @@ public:
|
|||
return kbhit();
|
||||
#endif
|
||||
}
|
||||
|
||||
int noecho_getch() {
|
||||
#ifndef _WIN32
|
||||
int ch=0;
|
||||
int ch = 0;
|
||||
if (peek_char!=-1) {
|
||||
ch=peek_char;
|
||||
peek_char=-1;
|
||||
ch = peek_char;
|
||||
peek_char = -1;
|
||||
return ch;
|
||||
}
|
||||
ssize_t tmp=read(0, &ch, 1);
|
||||
ssize_t tmp = read(0, &ch, 1);
|
||||
return ch;
|
||||
#else
|
||||
return getch();
|
||||
|
@ -92,7 +97,7 @@ var nas_noblock(var* args, usize size, gc* ngc) {
|
|||
return nil;
|
||||
}
|
||||
|
||||
module_func_info func_tbl[]={
|
||||
module_func_info func_tbl[] = {
|
||||
{"nas_getch",nas_getch},
|
||||
{"nas_kbhit",nas_kbhit},
|
||||
{"nas_noblock",nas_noblock},
|
||||
|
@ -101,4 +106,6 @@ module_func_info func_tbl[]={
|
|||
|
||||
extern "C" module_func_info* get() {
|
||||
return func_tbl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#include "../src/nasal.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var nas_vec2(var* args, usize size, gc* ngc) {
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(args[0]);
|
||||
res.vec().elems.push_back(args[1]);
|
||||
return res;
|
||||
}
|
||||
|
||||
var nas_vec3(var* args, usize size, gc* ngc) {
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(args[0]);
|
||||
res.vec().elems.push_back(args[1]);
|
||||
res.vec().elems.push_back(args[2]);
|
||||
|
@ -19,11 +21,11 @@ var nas_vec3(var* args, usize size, gc* ngc) {
|
|||
var nas_vec2_add(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=2 || v1.size()!=2)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num()));
|
||||
return res;
|
||||
|
@ -32,11 +34,11 @@ var nas_vec2_add(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)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=2 || v1.size()!=2)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num()));
|
||||
return res;
|
||||
|
@ -45,11 +47,11 @@ var nas_vec2_sub(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)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=2 || v1.size()!=2)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num()));
|
||||
return res;
|
||||
|
@ -58,11 +60,11 @@ var nas_vec2_mult(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)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=2 || v1.size()!=2)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num()));
|
||||
return res;
|
||||
|
@ -71,10 +73,10 @@ var nas_vec2_div(var* args, usize size, gc* ngc) {
|
|||
var nas_vec2_neg(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=2)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(-v0[0].num()));
|
||||
res.vec().elems.push_back(var::num(-v0[1].num()));
|
||||
return res;
|
||||
|
@ -83,13 +85,13 @@ var nas_vec2_neg(var* args, usize size, gc* ngc) {
|
|||
var nas_vec2_norm(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=2)
|
||||
return nil;
|
||||
auto x=v0[0].num();
|
||||
auto y=v0[1].num();
|
||||
auto t=std::sqrt(x*x+y*y);
|
||||
var res=ngc->alloc(vm_vec);
|
||||
auto x = v0[0].num();
|
||||
auto y = v0[1].num();
|
||||
auto t = std::sqrt(x*x+y*y);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(x/t));
|
||||
res.vec().elems.push_back(var::num(y/t));
|
||||
return res;
|
||||
|
@ -98,19 +100,19 @@ var nas_vec2_norm(var* args, usize size, gc* ngc) {
|
|||
var nas_vec2_len(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=2)
|
||||
return nil;
|
||||
auto x=v0[0].num();
|
||||
auto y=v0[1].num();
|
||||
auto x = v0[0].num();
|
||||
auto y = v0[1].num();
|
||||
return var::num(std::sqrt(x*x+y*y));
|
||||
}
|
||||
|
||||
var nas_vec2_dot(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=2 || v1.size()!=2)
|
||||
return nil;
|
||||
return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num());
|
||||
|
@ -119,11 +121,11 @@ var nas_vec2_dot(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_add(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=3 || v1.size()!=3)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()+v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()+v1[1].num()));
|
||||
res.vec().elems.push_back(var::num(v0[2].num()+v1[2].num()));
|
||||
|
@ -133,11 +135,11 @@ var nas_vec3_add(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_sub(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=3 || v1.size()!=3)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()-v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()-v1[1].num()));
|
||||
res.vec().elems.push_back(var::num(v0[2].num()-v1[2].num()));
|
||||
|
@ -147,11 +149,11 @@ var nas_vec3_sub(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_mult(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=3 || v1.size()!=3)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()*v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()*v1[1].num()));
|
||||
res.vec().elems.push_back(var::num(v0[2].num()*v1[2].num()));
|
||||
|
@ -161,11 +163,11 @@ var nas_vec3_mult(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_div(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=3 || v1.size()!=3)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()/v1[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()/v1[1].num()));
|
||||
res.vec().elems.push_back(var::num(v0[2].num()/v1[2].num()));
|
||||
|
@ -175,10 +177,10 @@ var nas_vec3_div(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_neg(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=3)
|
||||
return nil;
|
||||
var res=ngc->alloc(vm_vec);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(-v0[0].num()));
|
||||
res.vec().elems.push_back(var::num(-v0[1].num()));
|
||||
res.vec().elems.push_back(var::num(-v0[2].num()));
|
||||
|
@ -188,14 +190,14 @@ var nas_vec3_neg(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_norm(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=3)
|
||||
return nil;
|
||||
auto x=v0[0].num();
|
||||
auto y=v0[1].num();
|
||||
auto z=v0[2].num();
|
||||
auto t=std::sqrt(x*x+y*y+z*z);
|
||||
var res=ngc->alloc(vm_vec);
|
||||
auto x = v0[0].num();
|
||||
auto y = v0[1].num();
|
||||
auto z = v0[2].num();
|
||||
auto t = std::sqrt(x*x+y*y+z*z);
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(x/t));
|
||||
res.vec().elems.push_back(var::num(y/t));
|
||||
res.vec().elems.push_back(var::num(z/t));
|
||||
|
@ -205,23 +207,23 @@ var nas_vec3_norm(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_len(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=3)
|
||||
return nil;
|
||||
auto x=v0[0].num();
|
||||
auto y=v0[1].num();
|
||||
auto z=v0[2].num();
|
||||
auto x = v0[0].num();
|
||||
auto y = v0[1].num();
|
||||
auto z = v0[2].num();
|
||||
return var::num(std::sqrt(x*x+y*y+z*z));
|
||||
}
|
||||
|
||||
var nas_rotate_x(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=3)
|
||||
return nil;
|
||||
auto angle=args[1].num();
|
||||
var res=ngc->alloc(vm_vec);
|
||||
auto angle = args[1].num();
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()));
|
||||
res.vec().elems.push_back(var::num(v0[2].num()*std::sin(angle)+v0[1].num()*std::cos(angle)));
|
||||
res.vec().elems.push_back(var::num(v0[2].num()*std::cos(angle)-v0[1].num()*std::sin(angle)));
|
||||
|
@ -231,11 +233,11 @@ var nas_rotate_x(var* args, usize size, gc* ngc) {
|
|||
var nas_rotate_y(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=3)
|
||||
return nil;
|
||||
auto angle=args[1].num();
|
||||
var res=ngc->alloc(vm_vec);
|
||||
auto angle = args[1].num();
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[2].num()*std::sin(angle)));
|
||||
res.vec().elems.push_back(var::num(v0[1].num()));
|
||||
res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[2].num()*std::cos(angle)));
|
||||
|
@ -245,11 +247,11 @@ var nas_rotate_y(var* args, usize size, gc* ngc) {
|
|||
var nas_rotate_z(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
if (v0.size()!=3)
|
||||
return nil;
|
||||
auto angle=args[1].num();
|
||||
var res=ngc->alloc(vm_vec);
|
||||
auto angle = args[1].num();
|
||||
var res = ngc->alloc(vm_vec);
|
||||
res.vec().elems.push_back(var::num(v0[0].num()*std::cos(angle)-v0[1].num()*std::sin(angle)));
|
||||
res.vec().elems.push_back(var::num(v0[0].num()*std::sin(angle)+v0[1].num()*std::cos(angle)));
|
||||
res.vec().elems.push_back(var::num(v0[2].num()));
|
||||
|
@ -259,38 +261,40 @@ var nas_rotate_z(var* args, usize size, gc* ngc) {
|
|||
var nas_vec3_dot(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_vec || args[1].type!=vm_vec)
|
||||
return nil;
|
||||
auto& v0=args[0].vec().elems;
|
||||
auto& v1=args[1].vec().elems;
|
||||
auto& v0 = args[0].vec().elems;
|
||||
auto& v1 = args[1].vec().elems;
|
||||
if (v0.size()!=3 || v1.size()!=3)
|
||||
return nil;
|
||||
return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()+v0[2].num()*v1[2].num());
|
||||
}
|
||||
|
||||
module_func_info func_tbl[]={
|
||||
{"nas_vec2",nas_vec2},
|
||||
{"nas_vec2_add",nas_vec2_add},
|
||||
{"nas_vec2_sub",nas_vec2_sub},
|
||||
{"nas_vec2_mult",nas_vec2_mult},
|
||||
{"nas_vec2_div",nas_vec2_div},
|
||||
{"nas_vec2_neg",nas_vec2_neg},
|
||||
{"nas_vec2_norm",nas_vec2_norm},
|
||||
{"nas_vec2_len",nas_vec2_len},
|
||||
{"nas_vec2_dot",nas_vec2_dot},
|
||||
{"nas_vec3",nas_vec3},
|
||||
{"nas_vec3_add",nas_vec3_add},
|
||||
{"nas_vec3_sub",nas_vec3_sub},
|
||||
{"nas_vec3_mult",nas_vec3_mult},
|
||||
{"nas_vec3_div",nas_vec3_div},
|
||||
{"nas_vec3_neg",nas_vec3_neg},
|
||||
{"nas_vec3_norm",nas_vec3_norm},
|
||||
{"nas_vec3_len",nas_vec3_len},
|
||||
{"nas_rotate_x",nas_rotate_x},
|
||||
{"nas_rotate_y",nas_rotate_y},
|
||||
{"nas_rotate_z",nas_rotate_z},
|
||||
{"nas_vec3_dot",nas_vec3_dot},
|
||||
{nullptr,nullptr}
|
||||
module_func_info func_tbl[] = {
|
||||
{"nas_vec2", nas_vec2},
|
||||
{"nas_vec2_add", nas_vec2_add},
|
||||
{"nas_vec2_sub", nas_vec2_sub},
|
||||
{"nas_vec2_mult", nas_vec2_mult},
|
||||
{"nas_vec2_div", nas_vec2_div},
|
||||
{"nas_vec2_neg", nas_vec2_neg},
|
||||
{"nas_vec2_norm", nas_vec2_norm},
|
||||
{"nas_vec2_len", nas_vec2_len},
|
||||
{"nas_vec2_dot", nas_vec2_dot},
|
||||
{"nas_vec3", nas_vec3},
|
||||
{"nas_vec3_add", nas_vec3_add},
|
||||
{"nas_vec3_sub", nas_vec3_sub},
|
||||
{"nas_vec3_mult", nas_vec3_mult},
|
||||
{"nas_vec3_div", nas_vec3_div},
|
||||
{"nas_vec3_neg", nas_vec3_neg},
|
||||
{"nas_vec3_norm", nas_vec3_norm},
|
||||
{"nas_vec3_len", nas_vec3_len},
|
||||
{"nas_rotate_x", nas_rotate_x},
|
||||
{"nas_rotate_y", nas_rotate_y},
|
||||
{"nas_rotate_z", nas_rotate_z},
|
||||
{"nas_vec3_dot", nas_vec3_dot},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
extern "C" module_func_info* get() {
|
||||
return func_tbl;
|
||||
}
|
||||
|
||||
}
|
|
@ -28,16 +28,18 @@ static WSAmanager win;
|
|||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var nas_socket(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_num || args[1].type!=vm_num || args[2].type!=vm_num)
|
||||
return nas_err("socket","\"af\", \"type\", \"protocol\" should be number");
|
||||
int sd=socket(args[0].num(),args[1].num(),args[2].num());
|
||||
return nas_err("socket", "\"af\", \"type\", \"protocol\" should be number");
|
||||
int sd = socket(args[0].num(), args[1].num(), args[2].num());
|
||||
return var::num((double)sd);
|
||||
}
|
||||
|
||||
var nas_closesocket(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_num)
|
||||
return nas_err("closesocket","\"sd\" should be number");
|
||||
return nas_err("closesocket", "\"sd\" should be number");
|
||||
#ifdef _WIN32
|
||||
return var::num((double)closesocket(args[0].num()));
|
||||
#else
|
||||
|
@ -47,145 +49,175 @@ var nas_closesocket(var* args, usize size, gc* ngc) {
|
|||
|
||||
var nas_shutdown(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
return nas_err("shutdown","\"how\" must be a number");
|
||||
return var::num((double)shutdown(args[0].num(),args[1].num()));
|
||||
return nas_err("shutdown", "\"how\" must be a number");
|
||||
return var::num((double)shutdown(args[0].num(), args[1].num()));
|
||||
}
|
||||
|
||||
var nas_bind(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
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)
|
||||
return nas_err("bind","\"port\" must be a number");
|
||||
return nas_err("bind", "\"port\" must be a number");
|
||||
sockaddr_in server;
|
||||
memset(&server,0,sizeof(sockaddr_in));
|
||||
server.sin_family=AF_INET;
|
||||
server.sin_addr.s_addr=inet_addr(args[1].str().c_str());
|
||||
server.sin_port=htons(args[2].num());
|
||||
return var::num((double)bind(args[0].num(),(sockaddr*)&server,sizeof(server)));
|
||||
memset(&server, 0, sizeof(sockaddr_in));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = inet_addr(args[1].str().c_str());
|
||||
server.sin_port = htons(args[2].num());
|
||||
return var::num((double)bind(args[0].num(), (sockaddr*)&server, sizeof(server)));
|
||||
}
|
||||
|
||||
var nas_listen(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
return nas_err("listen","\"backlog\" must be a number");
|
||||
return var::num((double)listen(args[0].num(),args[1].num()));
|
||||
return nas_err("listen", "\"backlog\" must be a number");
|
||||
return var::num((double)listen(args[0].num(), args[1].num()));
|
||||
}
|
||||
|
||||
var nas_connect(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
return nas_err("connect","\"hostname\" must be a string");
|
||||
return nas_err("connect", "\"hostname\" must be a string");
|
||||
if (args[2].type!=vm_num)
|
||||
return nas_err("connect","\"port\" must be a number");
|
||||
return nas_err("connect", "\"port\" must be a number");
|
||||
sockaddr_in addr;
|
||||
memset(&addr,0,sizeof(sockaddr_in));
|
||||
addr.sin_family=AF_INET;
|
||||
addr.sin_port=htons(args[2].num());
|
||||
hostent* entry=gethostbyname(args[1].str().c_str());
|
||||
memcpy(&addr.sin_addr,entry->h_addr,entry->h_length);
|
||||
return var::num((double)connect(args[0].num(),(sockaddr*)&addr,sizeof(sockaddr_in)));
|
||||
memset(&addr, 0, sizeof(sockaddr_in));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(args[2].num());
|
||||
hostent* entry = gethostbyname(args[1].str().c_str());
|
||||
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
||||
return var::num((double)connect(
|
||||
args[0].num(),
|
||||
(sockaddr*)&addr,
|
||||
sizeof(sockaddr_in)
|
||||
));
|
||||
}
|
||||
|
||||
var nas_accept(var* args, usize size, gc* ngc) {
|
||||
if (args[0].type!=vm_num)
|
||||
return nas_err("accept","\"sd\" must be a number");
|
||||
return nas_err("accept", "\"sd\" must be a number");
|
||||
sockaddr_in client;
|
||||
int socklen=sizeof(sockaddr_in);
|
||||
int socklen = sizeof(sockaddr_in);
|
||||
#ifdef _WIN32
|
||||
int client_sd=accept(args[0].num(),(sockaddr*)&client,&socklen);
|
||||
int client_sd = accept(args[0].num(), (sockaddr*)&client, &socklen);
|
||||
#else
|
||||
int client_sd=accept(args[0].num(),(sockaddr*)&client,(socklen_t*)&socklen);
|
||||
int client_sd = accept(args[0].num(), (sockaddr*)&client, (socklen_t*)&socklen);
|
||||
#endif
|
||||
var res=ngc->temp=ngc->alloc(vm_hash);
|
||||
auto& hash=res.hash().elems;
|
||||
hash["sd"]=var::num((double)client_sd);
|
||||
hash["ip"]=ngc->newstr(inet_ntoa(client.sin_addr));
|
||||
ngc->temp=nil;
|
||||
var res=ngc->temp = ngc->alloc(vm_hash);
|
||||
auto& hash = res.hash().elems;
|
||||
hash["sd"] = var::num((double)client_sd);
|
||||
hash["ip"] = ngc->newstr(inet_ntoa(client.sin_addr));
|
||||
ngc->temp = nil;
|
||||
return res;
|
||||
}
|
||||
|
||||
var nas_send(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
return nas_err("send","\"buff\" must be a string");
|
||||
return nas_err("send", "\"buff\" must be a string");
|
||||
if (args[2].type!=vm_num)
|
||||
return nas_err("send","\"flags\" muse be a number");
|
||||
return var::num((double)send(args[0].num(),args[1].str().c_str(),args[1].str().length(),args[2].num()));
|
||||
return nas_err("send", "\"flags\" muse be a number");
|
||||
return var::num((double)send(
|
||||
args[0].num(),
|
||||
args[1].str().c_str(),
|
||||
args[1].str().length(),
|
||||
args[2].num()
|
||||
));
|
||||
}
|
||||
|
||||
var nas_sendto(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
return nas_err("sendto","\"hostname\" must be a string");
|
||||
return nas_err("sendto", "\"hostname\" must be a string");
|
||||
if (args[2].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)
|
||||
return nas_err("sendto","\"buff\" must be a string");
|
||||
return nas_err("sendto", "\"buff\" must be a string");
|
||||
if (args[4].type!=vm_num)
|
||||
return nas_err("sendto","\"flags\" must be a number");
|
||||
return nas_err("sendto", "\"flags\" must be a number");
|
||||
sockaddr_in addr;
|
||||
memset(&addr,0,sizeof(sockaddr_in));
|
||||
addr.sin_family=AF_INET;
|
||||
addr.sin_port=htons(args[2].num());
|
||||
hostent* entry=gethostbyname(args[1].str().c_str());
|
||||
memcpy(&addr.sin_addr,entry->h_addr,entry->h_length);
|
||||
return var::num((double)sendto(args[0].num(),args[3].str().c_str(),args[3].str().length(),args[4].num(),(sockaddr*)&addr,sizeof(sockaddr_in)));
|
||||
memset(&addr, 0, sizeof(sockaddr_in));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(args[2].num());
|
||||
hostent* entry = gethostbyname(args[1].str().c_str());
|
||||
memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
|
||||
return var::num((double)sendto(
|
||||
args[0].num(),
|
||||
args[3].str().c_str(),
|
||||
args[3].str().length(),
|
||||
args[4].num(),
|
||||
(sockaddr*)&addr,
|
||||
sizeof(sockaddr_in)
|
||||
));
|
||||
}
|
||||
|
||||
var nas_recv(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
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)
|
||||
return nas_err("recv","\"len\" out of range");
|
||||
return nas_err("recv", "\"len\" out of range");
|
||||
if (args[2].type!=vm_num)
|
||||
return nas_err("recv","\"flags\" muse be a number");
|
||||
var res=ngc->temp=ngc->alloc(vm_hash);
|
||||
auto& hash=res.hash().elems;
|
||||
char* buf=new char[(int)args[1].num()];
|
||||
auto recvsize=recv(args[0].num(),buf,args[1].num(),args[2].num());
|
||||
hash["size"]=var::num((double)recvsize);
|
||||
buf[recvsize>=0?recvsize:0]=0;
|
||||
hash["str"]=ngc->newstr(buf);
|
||||
return nas_err("recv", "\"flags\" muse be a number");
|
||||
var res = ngc->temp = ngc->alloc(vm_hash);
|
||||
auto& hash = res.hash().elems;
|
||||
char* buf = new char[(int)args[1].num()];
|
||||
auto recvsize = recv(args[0].num(), buf,args[1].num(), args[2].num());
|
||||
hash["size"] = var::num((double)recvsize);
|
||||
buf[recvsize>=0? recvsize:0] = 0;
|
||||
hash["str"] = ngc->newstr(buf);
|
||||
delete[] buf;
|
||||
ngc->temp=nil;
|
||||
ngc->temp = nil;
|
||||
return res;
|
||||
}
|
||||
|
||||
var nas_recvfrom(var* args, usize size, gc* ngc) {
|
||||
if (args[0].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)
|
||||
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)
|
||||
return nas_err("recvfrom","\"len\" out of range");
|
||||
return nas_err("recvfrom", "\"len\" out of range");
|
||||
if (args[2].type!=vm_num)
|
||||
return nas_err("recvfrom","\"flags\" muse be a number");
|
||||
return nas_err("recvfrom", "\"flags\" muse be a number");
|
||||
sockaddr_in addr;
|
||||
int socklen=sizeof(sockaddr_in);
|
||||
var res=ngc->temp=ngc->alloc(vm_hash);
|
||||
auto& hash=res.hash().elems;
|
||||
char* buf=new char[(int)args[1].num()+1];
|
||||
int socklen = sizeof(sockaddr_in);
|
||||
var res = ngc->temp = ngc->alloc(vm_hash);
|
||||
auto& hash = res.hash().elems;
|
||||
char* buf = new char[(int)args[1].num()+1];
|
||||
#ifdef _WIN32
|
||||
auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,&socklen);
|
||||
auto recvsize = recvfrom(
|
||||
args[0].num(),
|
||||
buf,
|
||||
args[1].num(),
|
||||
args[2].num(),
|
||||
(sockaddr*)&addr,
|
||||
&socklen
|
||||
);
|
||||
#else
|
||||
auto recvsize=recvfrom(args[0].num(),buf,args[1].num(),args[2].num(),(sockaddr*)&addr,(socklen_t*)&socklen);
|
||||
auto recvsize = recvfrom(
|
||||
args[0].num(),
|
||||
buf,
|
||||
args[1].num(),
|
||||
args[2].num(),
|
||||
(sockaddr*)&addr,
|
||||
(socklen_t*)&socklen
|
||||
);
|
||||
#endif
|
||||
hash["size"]=var::num((double)recvsize);
|
||||
buf[recvsize>=0?recvsize:0]=0;
|
||||
hash["str"]=ngc->newstr(buf);
|
||||
hash["size"] = var::num((double)recvsize);
|
||||
buf[recvsize>=0? recvsize:0] = 0;
|
||||
hash["str"] = ngc->newstr(buf);
|
||||
delete[] buf;
|
||||
hash["fromip"]=ngc->newstr(inet_ntoa(addr.sin_addr));
|
||||
ngc->temp=nil;
|
||||
hash["fromip"] = ngc->newstr(inet_ntoa(addr.sin_addr));
|
||||
ngc->temp = nil;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -193,22 +225,24 @@ var nas_errno(var* args, usize size, gc* ngc) {
|
|||
return ngc->newstr(strerror(errno));
|
||||
}
|
||||
|
||||
module_func_info func_tbl[]={
|
||||
{"nas_socket",nas_socket},
|
||||
{"nas_closesocket",nas_closesocket},
|
||||
{"nas_shutdown",nas_shutdown},
|
||||
{"nas_bind",nas_bind},
|
||||
{"nas_listen",nas_listen},
|
||||
{"nas_connect",nas_connect},
|
||||
{"nas_accept",nas_accept},
|
||||
{"nas_send",nas_send},
|
||||
{"nas_sendto",nas_sendto},
|
||||
{"nas_recv",nas_recv},
|
||||
{"nas_recvfrom",nas_recvfrom},
|
||||
{"nas_errno",nas_errno},
|
||||
{nullptr,nullptr}
|
||||
module_func_info func_tbl[] = {
|
||||
{"nas_socket", nas_socket},
|
||||
{"nas_closesocket", nas_closesocket},
|
||||
{"nas_shutdown", nas_shutdown},
|
||||
{"nas_bind", nas_bind},
|
||||
{"nas_listen", nas_listen},
|
||||
{"nas_connect", nas_connect},
|
||||
{"nas_accept", nas_accept},
|
||||
{"nas_send", nas_send},
|
||||
{"nas_sendto", nas_sendto},
|
||||
{"nas_recv", nas_recv},
|
||||
{"nas_recvfrom", nas_recvfrom},
|
||||
{"nas_errno", nas_errno},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
extern "C" module_func_info* get() {
|
||||
return func_tbl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
#include "bits_lib.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_u32xor(var* local, gc& ngc) {
|
||||
return var::num((f64)(u32(local[1].num())^u32(local[2].num())));
|
||||
return var::num(static_cast<f64>(
|
||||
static_cast<u32>(local[1].num()) ^
|
||||
static_cast<u32>(local[2].num())
|
||||
));
|
||||
}
|
||||
|
||||
var builtin_u32and(var* local, gc& ngc) {
|
||||
return var::num((f64)(u32(local[1].num())&u32(local[2].num())));
|
||||
return var::num(static_cast<f64>(
|
||||
static_cast<u32>(local[1].num()) &
|
||||
static_cast<u32>(local[2].num())
|
||||
));
|
||||
}
|
||||
|
||||
var builtin_u32or(var* local, gc& ngc) {
|
||||
return var::num((f64)(u32(local[1].num())|u32(local[2].num())));
|
||||
return var::num(static_cast<f64>(
|
||||
static_cast<u32>(local[1].num()) |
|
||||
static_cast<u32>(local[2].num())
|
||||
));
|
||||
}
|
||||
|
||||
var builtin_u32nand(var* local, gc& ngc) {
|
||||
return var::num((f64)(u32)(~(u32(local[1].num())&u32(local[2].num()))));
|
||||
return var::num(static_cast<f64>(~(
|
||||
static_cast<u32>(local[1].num()) &
|
||||
static_cast<u32>(local[2].num())
|
||||
)));
|
||||
}
|
||||
|
||||
var builtin_u32not(var* local, gc& ngc) {
|
||||
return var::num((f64)(u32)(~u32(local[1].num())));
|
||||
return var::num(static_cast<f64>(~static_cast<u32>(local[1].num())));
|
||||
}
|
||||
|
||||
var builtin_fld(var* local, gc& ngc) {
|
||||
|
@ -33,8 +47,8 @@ var builtin_fld(var* local, gc& ngc) {
|
|||
if (startbit.type!=vm_num || length.type!=vm_num) {
|
||||
return nas_err("fld", "\"startbit\",\"len\" must be number");
|
||||
}
|
||||
u32 bit = (u32)startbit.num();
|
||||
u32 len = (u32)length.num();
|
||||
u32 bit = static_cast<u32>(startbit.num());
|
||||
u32 len = static_cast<u32>(length.num());
|
||||
if (bit+len>8*str.str().length()) {
|
||||
return nas_err("fld", "bitfield out of bounds");
|
||||
}
|
||||
|
@ -45,7 +59,7 @@ var builtin_fld(var* local, gc& ngc) {
|
|||
res |= 1<<(bit+len-i-1);
|
||||
}
|
||||
}
|
||||
return var::num((f64)res);
|
||||
return var::num(static_cast<f64>(res));
|
||||
}
|
||||
|
||||
var builtin_sfld(var* local, gc& ngc) {
|
||||
|
@ -62,8 +76,8 @@ var builtin_sfld(var* local, gc& ngc) {
|
|||
if (startbit.type!=vm_num || length.type!=vm_num) {
|
||||
return nas_err("sfld", "\"startbit\",\"len\" must be number");
|
||||
}
|
||||
u32 bit = (u32)startbit.num();
|
||||
u32 len = (u32)length.num();
|
||||
u32 bit = static_cast<u32>(startbit.num());
|
||||
u32 len = static_cast<u32>(length.num());
|
||||
if (bit+len>8*str.str().length()) {
|
||||
return nas_err("sfld", "bitfield out of bounds");
|
||||
}
|
||||
|
@ -77,7 +91,7 @@ var builtin_sfld(var* local, gc& ngc) {
|
|||
if (res&(1<<(len-1))) {
|
||||
res |= ~((1<<len)-1);
|
||||
}
|
||||
return var::num((f64)((i32)res));
|
||||
return var::num(static_cast<f64>(static_cast<i32>(res)));
|
||||
}
|
||||
|
||||
var builtin_setfld(var* local, gc& ngc) {
|
||||
|
@ -95,9 +109,9 @@ var builtin_setfld(var* local, gc& ngc) {
|
|||
if (startbit.type!=vm_num || length.type!=vm_num || value.type!=vm_num) {
|
||||
return nas_err("setfld", "\"startbit\",\"len\",\"val\" must be number");
|
||||
}
|
||||
u32 bit = (u32)startbit.num();
|
||||
u32 len = (u32)length.num();
|
||||
u64 val = (u64)value.num();
|
||||
u32 bit = static_cast<u32>(startbit.num());
|
||||
u32 len = static_cast<u32>(length.num());
|
||||
u64 val = static_cast<u64>(value.num());
|
||||
if (bit+len>8*str.str().length()) {
|
||||
return nas_err("setfld", "bitfield out of bounds");
|
||||
}
|
||||
|
@ -134,4 +148,6 @@ nasal_builtin_table bits_native[] = {
|
|||
{"__setfld", builtin_setfld},
|
||||
{"__buf", builtin_buf},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "nasal_gc.h"
|
||||
#include "nasal_builtin.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_u32xor(var*, gc&);
|
||||
var builtin_u32and(var*, gc&);
|
||||
var builtin_u32or(var*, gc&);
|
||||
|
@ -15,3 +17,5 @@ var builtin_setfld(var*, gc&);
|
|||
var builtin_buf(var*, gc&);
|
||||
|
||||
extern nasal_builtin_table bits_native[];
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "coroutine.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_cocreate(var* local, gc& ngc) {
|
||||
// +-------------+
|
||||
// | old pc | <- top[0]
|
||||
|
@ -113,4 +115,6 @@ nasal_builtin_table coroutine_native[] = {
|
|||
{"__costatus", builtin_costatus},
|
||||
{"__corun", builtin_corun},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
#include "nasal_gc.h"
|
||||
#include "nasal_builtin.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_cocreate(var*, gc&);
|
||||
var builtin_coresume(var*, gc&);
|
||||
var builtin_coyield(var*, gc&);
|
||||
var builtin_costatus(var*, gc&);
|
||||
var builtin_corun(var*, gc&);
|
||||
|
||||
extern nasal_builtin_table coroutine_native[];
|
||||
extern nasal_builtin_table coroutine_native[];
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#include "dylib_lib.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
const auto dylib_type_name = "dylib";
|
||||
const auto func_addr_type_name = "faddr";
|
||||
|
||||
void dylib_destructor(void* ptr) {
|
||||
#ifdef _WIN32
|
||||
FreeLibrary((HMODULE)ptr);
|
||||
FreeLibrary(static_cast<HMODULE>(ptr));
|
||||
#else
|
||||
dlclose(ptr);
|
||||
#endif
|
||||
|
@ -39,7 +41,10 @@ var builtin_dlopen(var* local, gc& ngc) {
|
|||
ret.hash().elems["lib"] = lib;
|
||||
|
||||
#ifdef _WIN32
|
||||
void* func = (void*)GetProcAddress((HMODULE)lib.obj().ptr, "get");
|
||||
void* func = (void*)GetProcAddress(
|
||||
static_cast<HMODULE>(lib.obj().ptr),
|
||||
"get"
|
||||
);
|
||||
#else
|
||||
void* func = dlsym(lib.obj().ptr, "get");
|
||||
#endif
|
||||
|
@ -47,7 +52,7 @@ var builtin_dlopen(var* local, gc& ngc) {
|
|||
return nas_err("dlopen", "cannot find <get> function");
|
||||
}
|
||||
// get function pointer by name
|
||||
module_func_info* tbl = ((get_func_ptr)func)();
|
||||
module_func_info* tbl = reinterpret_cast<get_func_ptr>(func)();
|
||||
if (!tbl) {
|
||||
return nas_err("dlopen", "failed to get module functions");
|
||||
}
|
||||
|
@ -78,7 +83,11 @@ var builtin_dlcallv(var* local, gc& ngc) {
|
|||
return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
|
||||
}
|
||||
auto& vec = args.vec().elems;
|
||||
return ((module_func)fp.obj().ptr)(vec.data(), vec.size(), &ngc);
|
||||
return reinterpret_cast<module_func>(fp.obj().ptr)(
|
||||
vec.data(),
|
||||
vec.size(),
|
||||
&ngc
|
||||
);
|
||||
}
|
||||
|
||||
var builtin_dlcall(var* local, gc& ngc) {
|
||||
|
@ -90,10 +99,11 @@ var builtin_dlcall(var* local, gc& ngc) {
|
|||
var* local_frame_start = local+2;
|
||||
usize local_frame_size = ngc.rctx->top-local_frame_start;
|
||||
// arguments' stored place begins at local +2
|
||||
return ((module_func)fp.obj().ptr)(
|
||||
return reinterpret_cast<module_func>(fp.obj().ptr)(
|
||||
local_frame_start,
|
||||
local_frame_size,
|
||||
&ngc);
|
||||
&ngc
|
||||
);
|
||||
}
|
||||
|
||||
nasal_builtin_table dylib_lib_native[] = {
|
||||
|
@ -102,4 +112,6 @@ nasal_builtin_table dylib_lib_native[] = {
|
|||
{"__dlcallv", builtin_dlcallv},
|
||||
{"__dlcall", builtin_dlcall},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
namespace nasal {
|
||||
|
||||
void dylib_destructor(void*);
|
||||
void func_addr_destructor(void*);
|
||||
|
||||
|
@ -19,4 +21,6 @@ var builtin_dlclose(var*, gc&);
|
|||
var builtin_dlcallv(var*, gc&);
|
||||
var builtin_dlcall(var*, gc&);
|
||||
|
||||
extern nasal_builtin_table dylib_lib_native[];
|
||||
extern nasal_builtin_table dylib_lib_native[];
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <fstream>
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_logprint(var* local, gc& ngc) {
|
||||
var level = local[1];
|
||||
var elems = local[2];
|
||||
|
@ -21,7 +23,8 @@ var builtin_logprint(var* local, gc& ngc) {
|
|||
default:
|
||||
return nas_err("logprint",
|
||||
"incorrect log level " +
|
||||
std::to_string(level.num()));
|
||||
std::to_string(level.num())
|
||||
);
|
||||
}
|
||||
for(auto& i : elems.vec().elems) {
|
||||
out << i << " ";
|
||||
|
@ -33,4 +36,6 @@ var builtin_logprint(var* local, gc& ngc) {
|
|||
nasal_builtin_table flight_gear_native[] = {
|
||||
{"_logprint", builtin_logprint},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "nasal_gc.h"
|
||||
#include "nasal_builtin.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
#define SG_LOG_BULK 1
|
||||
#define SG_LOG_DEBUG 2
|
||||
#define SG_LOG_INFO 3
|
||||
|
@ -16,3 +18,5 @@
|
|||
var builtin_logprint(var*, gc&);
|
||||
|
||||
extern nasal_builtin_table flight_gear_native[];
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#include "io_lib.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
const auto file_type_name = "file";
|
||||
|
||||
void filehandle_destructor(void* ptr) {
|
||||
if ((FILE*)ptr==stdin) {
|
||||
if (static_cast<FILE*>(ptr)==stdin) {
|
||||
return;
|
||||
}
|
||||
fclose((FILE*)ptr);
|
||||
fclose(static_cast<FILE*>(ptr));
|
||||
}
|
||||
|
||||
var builtin_readfile(var* local, gc& ngc) {
|
||||
|
@ -90,7 +92,7 @@ var builtin_read(var* local, gc& ngc) {
|
|||
if (!buff) {
|
||||
return nas_err("read", "malloc failed");
|
||||
}
|
||||
f64 res = fread(buff,1,len.num(), (FILE*)fd.obj().ptr);
|
||||
f64 res = fread(buff, 1, len.num(), static_cast<FILE*>(fd.obj().ptr));
|
||||
buf.str() = buff;
|
||||
buf.val.gcobj->unmut = true;
|
||||
delete []buff;
|
||||
|
@ -106,7 +108,12 @@ var builtin_write(var* local, gc& ngc) {
|
|||
if (str.type!=vm_str) {
|
||||
return nas_err("write", "\"str\" must be string");
|
||||
}
|
||||
return var::num((f64)fwrite(str.str().c_str(), 1, str.str().length(), (FILE*)fd.obj().ptr));
|
||||
return var::num(static_cast<f64>(fwrite(
|
||||
str.str().c_str(),
|
||||
1,
|
||||
str.str().length(),
|
||||
static_cast<FILE*>(fd.obj().ptr)
|
||||
)));
|
||||
}
|
||||
|
||||
var builtin_seek(var* local, gc& ngc) {
|
||||
|
@ -116,7 +123,11 @@ var builtin_seek(var* local, gc& ngc) {
|
|||
if (!fd.objchk(file_type_name)) {
|
||||
return nas_err("seek", "not a valid filehandle");
|
||||
}
|
||||
return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num()));
|
||||
return var::num(static_cast<f64>(fseek(
|
||||
static_cast<FILE*>(fd.obj().ptr),
|
||||
pos.num(),
|
||||
whence.num()
|
||||
)));
|
||||
}
|
||||
|
||||
var builtin_tell(var* local, gc& ngc) {
|
||||
|
@ -124,7 +135,7 @@ var builtin_tell(var* local, gc& ngc) {
|
|||
if (!fd.objchk(file_type_name)) {
|
||||
return nas_err("tell", "not a valid filehandle");
|
||||
}
|
||||
return var::num((f64)ftell((FILE*)fd.obj().ptr));
|
||||
return var::num(static_cast<f64>(ftell(static_cast<FILE*>(fd.obj().ptr))));
|
||||
}
|
||||
|
||||
var builtin_readln(var* local, gc& ngc) {
|
||||
|
@ -134,7 +145,7 @@ var builtin_readln(var* local, gc& ngc) {
|
|||
}
|
||||
var str = ngc.alloc(vm_str);
|
||||
char c;
|
||||
while((c = fgetc((FILE*)fd.obj().ptr))!=EOF) {
|
||||
while((c = fgetc(static_cast<FILE*>(fd.obj().ptr)))!=EOF) {
|
||||
if (c=='\r') {
|
||||
continue;
|
||||
}
|
||||
|
@ -160,17 +171,17 @@ var builtin_stat(var* local, gc& ngc) {
|
|||
}
|
||||
var ret = ngc.alloc(vm_vec);
|
||||
ret.vec().elems = {
|
||||
var::num((f64)buf.st_dev),
|
||||
var::num((f64)buf.st_ino),
|
||||
var::num((f64)buf.st_mode),
|
||||
var::num((f64)buf.st_nlink),
|
||||
var::num((f64)buf.st_uid),
|
||||
var::num((f64)buf.st_gid),
|
||||
var::num((f64)buf.st_rdev),
|
||||
var::num((f64)buf.st_size),
|
||||
var::num((f64)buf.st_atime),
|
||||
var::num((f64)buf.st_mtime),
|
||||
var::num((f64)buf.st_ctime)
|
||||
var::num(static_cast<f64>(buf.st_dev)),
|
||||
var::num(static_cast<f64>(buf.st_ino)),
|
||||
var::num(static_cast<f64>(buf.st_mode)),
|
||||
var::num(static_cast<f64>(buf.st_nlink)),
|
||||
var::num(static_cast<f64>(buf.st_uid)),
|
||||
var::num(static_cast<f64>(buf.st_gid)),
|
||||
var::num(static_cast<f64>(buf.st_rdev)),
|
||||
var::num(static_cast<f64>(buf.st_size)),
|
||||
var::num(static_cast<f64>(buf.st_atime)),
|
||||
var::num(static_cast<f64>(buf.st_mtime)),
|
||||
var::num(static_cast<f64>(buf.st_ctime))
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
@ -180,7 +191,7 @@ var builtin_eof(var* local, gc& ngc) {
|
|||
if (!fd.objchk(file_type_name)) {
|
||||
return nas_err("readln", "not a valid filehandle");
|
||||
}
|
||||
return var::num((f64)feof((FILE*)fd.obj().ptr));
|
||||
return var::num(static_cast<f64>(feof(static_cast<FILE*>(fd.obj().ptr))));
|
||||
}
|
||||
|
||||
nasal_builtin_table io_lib_native[] = {
|
||||
|
@ -197,4 +208,6 @@ nasal_builtin_table io_lib_native[] = {
|
|||
{"__stat", builtin_stat},
|
||||
{"__eof", builtin_eof},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#define F_OK 0 // fuck msc
|
||||
#endif
|
||||
|
||||
namespace nasal {
|
||||
|
||||
void filehandle_destructor(void*);
|
||||
|
||||
var builtin_readfile(var*, gc&);
|
||||
|
@ -25,4 +27,6 @@ var builtin_readln(var*, gc&);
|
|||
var builtin_stat(var*, gc&);
|
||||
var builtin_eof(var*, gc&);
|
||||
|
||||
extern nasal_builtin_table io_lib_native[];
|
||||
extern nasal_builtin_table io_lib_native[];
|
||||
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ std::ostream& help(std::ostream& out) {
|
|||
<< " -t, --time | show execute time.\n"
|
||||
<< " -d, --detail | get detail info.\n"
|
||||
<< " -dbg, --debug | debug mode.\n"
|
||||
<< " --prof | show profiling result, available under debug mode.\n"
|
||||
<< " --prof | show profiling result, available in debug mode.\n"
|
||||
<< " --prof-all | show profiling result of all files,"
|
||||
<< "available under debug mode.\n"
|
||||
<< "file:\n"
|
||||
|
@ -154,7 +154,8 @@ void execute(
|
|||
debugger->run(gen, ld, argv, cmd&VM_PROFILE, cmd&VM_PROF_ALL);
|
||||
} else if (cmd&VM_TIME || cmd&VM_EXEC) {
|
||||
auto runtime = std::unique_ptr<nasal::vm>(new nasal::vm);
|
||||
runtime->run(gen, ld, argv, cmd&VM_DETAIL);
|
||||
runtime->set_detail_report_info(cmd&VM_DETAIL);
|
||||
runtime->run(gen, ld, argv);
|
||||
}
|
||||
|
||||
// get running time
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "math_lib.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_pow(var* local, gc& ngc) {
|
||||
var x = local[1];
|
||||
var y = local[2];
|
||||
|
@ -11,37 +13,37 @@ var builtin_pow(var* local, gc& ngc) {
|
|||
|
||||
var builtin_sin(var* local, gc& ngc) {
|
||||
var val = local[1];
|
||||
return var::num(val.type==vm_num?sin(val.num()):std::nan(""));
|
||||
return var::num(val.type==vm_num? sin(val.num()):std::nan(""));
|
||||
}
|
||||
|
||||
var builtin_cos(var* local, gc& ngc) {
|
||||
var val = local[1];
|
||||
return var::num(val.type==vm_num?cos(val.num()):std::nan(""));
|
||||
return var::num(val.type==vm_num? cos(val.num()):std::nan(""));
|
||||
}
|
||||
|
||||
var builtin_tan(var* local, gc& ngc) {
|
||||
var val = local[1];
|
||||
return var::num(val.type==vm_num?tan(val.num()):std::nan(""));
|
||||
return var::num(val.type==vm_num? tan(val.num()):std::nan(""));
|
||||
}
|
||||
|
||||
var builtin_exp(var* local, gc& ngc) {
|
||||
var val = local[1];
|
||||
return var::num(val.type==vm_num?exp(val.num()):std::nan(""));
|
||||
return var::num(val.type==vm_num? exp(val.num()):std::nan(""));
|
||||
}
|
||||
|
||||
var builtin_lg(var* local, gc& ngc) {
|
||||
var val = local[1];
|
||||
return var::num(val.type==vm_num?log(val.num())/log(10.0):std::nan(""));
|
||||
return var::num(val.type==vm_num? log(val.num())/log(10.0):std::nan(""));
|
||||
}
|
||||
|
||||
var builtin_ln(var* local, gc& ngc) {
|
||||
var val = local[1];
|
||||
return var::num(val.type==vm_num?log(val.num()):std::nan(""));
|
||||
return var::num(val.type==vm_num? log(val.num()):std::nan(""));
|
||||
}
|
||||
|
||||
var builtin_sqrt(var* local, gc& ngc) {
|
||||
var val = local[1];
|
||||
return var::num(val.type==vm_num?sqrt(val.num()):std::nan(""));
|
||||
return var::num(val.type==vm_num? sqrt(val.num()):std::nan(""));
|
||||
}
|
||||
|
||||
var builtin_atan2(var* local, gc& ngc) {
|
||||
|
@ -70,4 +72,6 @@ nasal_builtin_table math_lib_native[] = {
|
|||
{"__atan2", builtin_atan2},
|
||||
{"__isnan", builtin_isnan},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "nasal_gc.h"
|
||||
#include "nasal_builtin.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_pow(var*, gc&);
|
||||
var builtin_sin(var*, gc&);
|
||||
var builtin_cos(var*, gc&);
|
||||
|
@ -15,4 +17,6 @@ var builtin_sqrt(var*, gc&);
|
|||
var builtin_atan2(var*, gc&);
|
||||
var builtin_isnan(var*, gc&);
|
||||
|
||||
extern nasal_builtin_table math_lib_native[];
|
||||
extern nasal_builtin_table math_lib_native[];
|
||||
|
||||
}
|
||||
|
|
24
src/nasal.h
24
src/nasal.h
|
@ -11,6 +11,17 @@
|
|||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
using i32 = std::int32_t;
|
||||
using i64 = std::int64_t;
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
using usize = std::size_t;
|
||||
using f64 = double;
|
||||
|
||||
namespace nasal {
|
||||
|
||||
bool is_windows();
|
||||
bool is_linux();
|
||||
bool is_macos();
|
||||
|
@ -23,14 +34,7 @@ bool is_ia64();
|
|||
bool is_powerpc();
|
||||
bool is_superh();
|
||||
|
||||
using i32 = std::int32_t;
|
||||
using i64 = std::int64_t;
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
using usize = std::size_t;
|
||||
using f64 = double;
|
||||
|
||||
|
||||
const u32 STACK_DEPTH = 4096;
|
||||
|
||||
|
@ -50,4 +54,6 @@ i32 utf8_hdchk(const char);
|
|||
std::string chrhex(const char);
|
||||
std::string rawstr(const std::string&, const usize maxlen=0);
|
||||
|
||||
#include "nasal_gc.h"
|
||||
}
|
||||
|
||||
#include "nasal_gc.h"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "nasal_builtin.h"
|
||||
#include <chrono>
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_print(var* local, gc& ngc) {
|
||||
for(auto& i : local[1].vec().elems) {
|
||||
std::cout << i;
|
||||
|
@ -49,7 +51,7 @@ var builtin_setsize(var* local, gc& ngc) {
|
|||
if (size.type!=vm_num || size.num()<0) {
|
||||
return nil;
|
||||
}
|
||||
vec.vec().elems.resize((i64)size.num(), nil);
|
||||
vec.vec().elems.resize(static_cast<i64>(size.num()), nil);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -58,7 +60,7 @@ var builtin_system(var* local, gc& ngc) {
|
|||
if (str.type!=vm_str) {
|
||||
return var::num(-1);
|
||||
}
|
||||
return var::num((f64)system(str.str().c_str()));
|
||||
return var::num(static_cast<f64>(system(str.str().c_str())));
|
||||
}
|
||||
|
||||
var builtin_input(var* local, gc& ngc) {
|
||||
|
@ -117,7 +119,7 @@ var builtin_rand(var* local, gc& ngc) {
|
|||
return nas_err("rand", "\"seed\" must be nil or number");
|
||||
}
|
||||
if (val.type==vm_num) {
|
||||
srand((u32)val.num());
|
||||
srand(static_cast<u32>(val.num()));
|
||||
return nil;
|
||||
}
|
||||
f64 num = 0;
|
||||
|
@ -132,7 +134,8 @@ var builtin_id(var* local, gc& ngc) {
|
|||
std::stringstream ss;
|
||||
ss << "0";
|
||||
if (val.type>vm_num) {
|
||||
ss << "x" << std::hex << (u64)val.val.gcobj << std::dec;
|
||||
ss << "x" << std::hex;
|
||||
ss << reinterpret_cast<u64>(val.val.gcobj) << std::dec;
|
||||
}
|
||||
return ngc.newstr(ss.str());
|
||||
}
|
||||
|
@ -142,7 +145,7 @@ var builtin_int(var* local, gc& ngc) {
|
|||
if (val.type!=vm_num && val.type!=vm_str) {
|
||||
return nil;
|
||||
}
|
||||
return var::num(f64((i32)val.tonum()));
|
||||
return var::num(static_cast<f64>(static_cast<i32>(val.tonum())));
|
||||
}
|
||||
|
||||
var builtin_floor(var* local, gc& ngc) {
|
||||
|
@ -202,7 +205,7 @@ var builtin_time(var* local, gc& ngc) {
|
|||
return nas_err("time", "\"begin\" must be number");
|
||||
}
|
||||
time_t begin = (time_t)val.num();
|
||||
return var::num((f64)time(&begin));
|
||||
return var::num(static_cast<f64>(time(&begin)));
|
||||
}
|
||||
|
||||
var builtin_contains(var* local, gc& ngc) {
|
||||
|
@ -259,9 +262,9 @@ var builtin_find(var* local, gc& ngc) {
|
|||
var haystack = local[2];
|
||||
usize pos = haystack.tostr().find(needle.tostr());
|
||||
if (pos==std::string::npos) {
|
||||
return var::num((f64)-1);
|
||||
return var::num(-1.0);
|
||||
}
|
||||
return var::num((f64)pos);
|
||||
return var::num(static_cast<f64>(pos));
|
||||
}
|
||||
|
||||
var builtin_type(var* local, gc& ngc) {
|
||||
|
@ -331,7 +334,7 @@ var builtin_right(var* local, gc& ngc) {
|
|||
if (len.type!=vm_num) {
|
||||
return nas_err("right", "\"length\" must be number");
|
||||
}
|
||||
i32 length = (i32)len.num();
|
||||
i32 length = static_cast<i32>(len.num());
|
||||
i32 srclen = str.str().length();
|
||||
if (length>srclen) {
|
||||
length = srclen;
|
||||
|
@ -348,7 +351,10 @@ var builtin_cmp(var* local, gc& ngc) {
|
|||
if (a.type!=vm_str || b.type!=vm_str) {
|
||||
return nas_err("cmp", "\"a\" and \"b\" must be string");
|
||||
}
|
||||
return var::num((f64)strcmp(a.str().c_str(), b.str().c_str()));
|
||||
return var::num(static_cast<f64>(strcmp(
|
||||
a.str().c_str(),
|
||||
b.str().c_str()
|
||||
)));
|
||||
}
|
||||
|
||||
var builtin_chr(var* local, gc& ngc) {
|
||||
|
@ -606,7 +612,7 @@ var builtin_ghosttype(var* local, gc& ngc) {
|
|||
}
|
||||
const auto& name = arg.obj().get_ghost_name();
|
||||
if (!name.length()) {
|
||||
return var::num((u64)arg.obj().ptr);
|
||||
return var::num(reinterpret_cast<u64>(arg.obj().ptr));
|
||||
}
|
||||
return ngc.newstr(name);
|
||||
}
|
||||
|
@ -654,4 +660,6 @@ nasal_builtin_table builtin[] = {
|
|||
{"__logtime", builtin_logtime},
|
||||
{"__ghosttype", builtin_ghosttype},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#define environ (*_NSGetEnviron())
|
||||
#endif
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var builtin_print(var*, gc&);
|
||||
var builtin_println(var*, gc&);
|
||||
var builtin_exit(var*, gc&);
|
||||
|
@ -75,3 +77,5 @@ struct nasal_builtin_table {
|
|||
};
|
||||
|
||||
extern nasal_builtin_table builtin[];
|
||||
|
||||
}
|
||||
|
|
|
@ -237,7 +237,8 @@ void dbg::run(
|
|||
const std::vector<std::string>& argv,
|
||||
bool profile,
|
||||
bool show_all_prof_result) {
|
||||
verbose = true;
|
||||
|
||||
set_detail_report_info(true);
|
||||
do_profiling = profile || show_all_prof_result;
|
||||
|
||||
const auto& file_list = linker.get_file_list();
|
||||
|
|
|
@ -75,10 +75,12 @@ std::ostream& reset(std::ostream& s) {
|
|||
void flstream::load(const std::string& f) {
|
||||
if (file==f) { // don't need to load a loaded file
|
||||
return;
|
||||
} else {
|
||||
file = f;
|
||||
}
|
||||
|
||||
// update file name
|
||||
file = f;
|
||||
|
||||
// REPL: load from memory
|
||||
if (repl::info::instance()->in_repl_mode &&
|
||||
repl::info::instance()->repl_file_name==file) {
|
||||
const auto& source = repl::info::instance()->repl_file_source;
|
||||
|
@ -134,15 +136,16 @@ void error::err(
|
|||
const usize maxlen = std::to_string(loc.end_line).length();
|
||||
const std::string iden = identation(maxlen);
|
||||
|
||||
for(u32 line=loc.begin_line; line<=loc.end_line; ++line) {
|
||||
for(u32 line = loc.begin_line; line<=loc.end_line; ++line) {
|
||||
// skip line 0
|
||||
if (!line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loc.begin_line<line && line<loc.end_line) {
|
||||
if (line==loc.begin_line+1) {
|
||||
std::cerr << cyan << iden << " | " << reset << "...\n"
|
||||
<< cyan << iden << " | " << reset << "\n";
|
||||
std::cerr << cyan << iden << " | " << reset << "...\n";
|
||||
std::cerr << cyan << iden << " | " << reset << "\n";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -152,7 +155,12 @@ void error::err(
|
|||
continue;
|
||||
}
|
||||
|
||||
const std::string& code=res[line-1];
|
||||
// line out of range
|
||||
if (line-1>=res.size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& code = res[line-1];
|
||||
std::cerr << cyan << leftpad(line, maxlen) << " | " << reset << code << "\n";
|
||||
// output underline
|
||||
std::cerr << cyan << iden << " | " << reset;
|
||||
|
@ -160,7 +168,7 @@ void error::err(
|
|||
for(u32 i = 0; i<loc.begin_column; ++i) {
|
||||
std::cerr << char(" \t"[code[i]=='\t']);
|
||||
}
|
||||
for(u32 i = loc.begin_column ;i<loc.end_column; ++i) {
|
||||
for(u32 i = loc.begin_column; i<loc.end_column; ++i) {
|
||||
std::cerr << red << (code[i]=='\t'? "^^^^":"^") << reset;
|
||||
}
|
||||
} else if (line==loc.begin_line) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "nasal_gc.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
var nas_vec::get_val(const i32 n) {
|
||||
i32 size = elems.size();
|
||||
if (n<-size || n>=size) {
|
||||
|
@ -128,7 +130,8 @@ void nas_ghost::clear() {
|
|||
|
||||
std::ostream& operator<<(std::ostream& out, const nas_ghost& ghost) {
|
||||
out << "<object " << ghost.get_ghost_name();
|
||||
out << " at 0x" << std::hex << (u64)ghost.ptr << std::dec << ">";
|
||||
out << " at 0x" << std::hex;
|
||||
out << reinterpret_cast<u64>(ghost.ptr) << std::dec << ">";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -152,7 +155,8 @@ void nas_co::clear() {
|
|||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const nas_co& co) {
|
||||
out << "<coroutine at 0x" << std::hex << u64(&co) << std::dec << ">";
|
||||
out << "<coroutine at 0x" << std::hex;
|
||||
out << reinterpret_cast<u64>(&co) << std::dec << ">";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -265,11 +269,11 @@ bool var::objchk(const std::string& name) {
|
|||
}
|
||||
|
||||
var var::none() {
|
||||
return {vm_none, (u32)0};
|
||||
return {vm_none, static_cast<u32>(0)};
|
||||
}
|
||||
|
||||
var var::nil() {
|
||||
return {vm_nil, (u32)0};
|
||||
return {vm_nil, static_cast<u32>(0)};
|
||||
}
|
||||
|
||||
var var::ret(u32 pc) {
|
||||
|
@ -533,11 +537,8 @@ void gc::extend(u8 type) {
|
|||
|
||||
void gc::init(
|
||||
const std::vector<std::string>& s, const std::vector<std::string>& argv) {
|
||||
// initialize function register
|
||||
rctx->funcr = nil;
|
||||
worktime = 0;
|
||||
|
||||
// initialize counters
|
||||
worktime = 0;
|
||||
for(u8 i = 0; i<gc_type_size; ++i) {
|
||||
size[i] = gcnt[i] = acnt[i] = 0;
|
||||
}
|
||||
|
@ -716,4 +717,6 @@ void gc::ctxreserve() {
|
|||
var nas_err(const std::string& error_function_name, const std::string& info) {
|
||||
std::cerr << "[vm] " << error_function_name << ": " << info << "\n";
|
||||
return var::none();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "nasal.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
enum vm_type:u8 {
|
||||
/* none-gc object */
|
||||
vm_none = 0,
|
||||
|
@ -298,9 +300,9 @@ struct gc {
|
|||
var temp = nil;
|
||||
|
||||
/* constants and memory pool */
|
||||
std::vector<var> strs; // reserved address for const vm_str
|
||||
std::vector<var> env_argv; // command line arguments
|
||||
std::vector<nas_val*> memory; // gc memory
|
||||
std::vector<var> strs = {}; // reserved address for const vm_str
|
||||
std::vector<var> env_argv = {}; // command line arguments
|
||||
std::vector<nas_val*> memory; // gc memory
|
||||
std::vector<nas_val*> unused[gc_type_size]; // gc free list
|
||||
|
||||
/* heap increase size */
|
||||
|
@ -388,3 +390,5 @@ struct module_func_info {
|
|||
|
||||
// module function "get" type
|
||||
typedef module_func_info* (*get_func_ptr)();
|
||||
|
||||
}
|
||||
|
|
|
@ -330,6 +330,7 @@ const error& lexer::scan(const std::string& file) {
|
|||
line = 1;
|
||||
column = 0;
|
||||
ptr = 0;
|
||||
toks = {};
|
||||
open(file);
|
||||
|
||||
while(ptr<res.size()) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "nasal.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
bool is_windows() {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
return true;
|
||||
|
@ -227,4 +229,6 @@ std::string rawstr(const std::string& str, const usize maxlen) {
|
|||
ret = ret.substr(0,maxlen)+"...";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "nasal_opcode.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
const char* opname[] = {
|
||||
"exit ", "intg ", "intl ", "loadg ",
|
||||
"loadl ", "loadu ", "pnum ", "pnil ",
|
||||
|
@ -45,7 +47,7 @@ void codestream::dump(std::ostream& out) const {
|
|||
auto num = code.num;
|
||||
out << hex << "0x"
|
||||
<< setw(6) << setfill('0') << index << " "
|
||||
<< setw(2) << setfill('0') << (u32)op << " "
|
||||
<< setw(2) << setfill('0') << static_cast<u32>(op) << " "
|
||||
<< setw(2) << setfill('0') << ((num>>16)&0xff) << " "
|
||||
<< setw(2) << setfill('0') << ((num>>8)&0xff) << " "
|
||||
<< setw(2) << setfill('0') << (num&0xff) << " "
|
||||
|
@ -90,7 +92,8 @@ void codestream::dump(std::ostream& out) const {
|
|||
out << hex << "0x" << num << dec; break;
|
||||
case op_callb:
|
||||
out << hex << "0x" << num << " <" << natives[num].name
|
||||
<< "@0x" << (u64)natives[num].func << dec << ">"; break;
|
||||
<< "@0x" << reinterpret_cast<u64>(natives[num].func)
|
||||
<< dec << ">"; break;
|
||||
case op_upval: case op_mupval:
|
||||
case op_loadu:
|
||||
out << hex << "0x" << ((num>>16)&0xffff)
|
||||
|
@ -115,4 +118,6 @@ void codestream::dump(std::ostream& out) const {
|
|||
std::ostream& operator<<(std::ostream& out, const codestream& ins) {
|
||||
ins.dump(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
namespace nasal {
|
||||
|
||||
enum op_code_type:u8 {
|
||||
op_exit, // stop the virtual machine
|
||||
op_intg, // init global scope
|
||||
|
@ -126,4 +128,6 @@ public:
|
|||
|
||||
std::ostream& operator<<(std::ostream&, const codestream&);
|
||||
|
||||
extern const char* opname[];
|
||||
extern const char* opname[];
|
||||
|
||||
}
|
104
src/nasal_vm.cpp
104
src/nasal_vm.cpp
|
@ -20,19 +20,10 @@ void vm::init(
|
|||
/* set native functions */
|
||||
native = natives;
|
||||
|
||||
/* set canary and program counter */
|
||||
ctx.pc = 0;
|
||||
ctx.localr = nullptr;
|
||||
ctx.memr = nullptr;
|
||||
ctx.funcr = nil;
|
||||
ctx.upvalr = nil;
|
||||
ctx.canary = ctx.stack+STACK_DEPTH-1; // stack[STACK_DEPTH-1]
|
||||
ctx.top = ctx.stack; // nothing is on stack
|
||||
|
||||
/* clear main stack and global */
|
||||
for(u32 i = 0; i<STACK_DEPTH; ++i) {
|
||||
ctx.stack[i] = nil;
|
||||
global[i] = nil;
|
||||
/* set context and global */
|
||||
if (!is_repl_mode || first_exec_flag) {
|
||||
context_and_global_init();
|
||||
first_exec_flag = false;
|
||||
}
|
||||
|
||||
/* init gc */
|
||||
|
@ -52,41 +43,64 @@ void vm::init(
|
|||
arg_instance.vec().elems = ngc.env_argv;
|
||||
}
|
||||
|
||||
void vm::context_and_global_init() {
|
||||
/* set canary and program counter */
|
||||
ctx.pc = 0;
|
||||
ctx.localr = nullptr;
|
||||
ctx.memr = nullptr;
|
||||
ctx.funcr = nil;
|
||||
ctx.upvalr = nil;
|
||||
|
||||
/* set canary = stack[STACK_DEPTH-1] */
|
||||
ctx.canary = ctx.stack+STACK_DEPTH-1;
|
||||
|
||||
/* nothing is on stack */
|
||||
ctx.top = ctx.stack;
|
||||
|
||||
/* clear main stack and global */
|
||||
for(u32 i = 0; i<STACK_DEPTH; ++i) {
|
||||
ctx.stack[i] = nil;
|
||||
global[i] = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void vm::valinfo(var& val) {
|
||||
const nas_val* p = val.val.gcobj;
|
||||
const auto p = reinterpret_cast<u64>(val.val.gcobj);
|
||||
switch(val.type) {
|
||||
case vm_none: std::clog << "| null |"; break;
|
||||
case vm_ret: std::clog << "| pc | 0x" << std::hex
|
||||
<< val.ret() << std::dec; break;
|
||||
case vm_addr: std::clog << "| addr | 0x" << std::hex
|
||||
<< (u64)val.addr() << std::dec; break;
|
||||
<< reinterpret_cast<u64>(val.addr())
|
||||
<< std::dec; break;
|
||||
case vm_cnt: std::clog << "| cnt | " << val.cnt(); break;
|
||||
case vm_nil: std::clog << "| nil |"; break;
|
||||
case vm_num: std::clog << "| num | " << val.num(); break;
|
||||
case vm_str: std::clog << "| str | <0x" << std::hex << (u64)p
|
||||
case vm_str: std::clog << "| str | <0x" << std::hex << p
|
||||
<< "> " << rawstr(val.str(), 16)
|
||||
<< std::dec; break;
|
||||
case vm_func: std::clog << "| func | <0x" << std::hex << (u64)p
|
||||
case vm_func: std::clog << "| func | <0x" << std::hex << p
|
||||
<< "> entry:0x" << val.func().entry
|
||||
<< std::dec; break;
|
||||
case vm_upval:std::clog << "| upval| <0x" << std::hex << (u64)p
|
||||
case vm_upval:std::clog << "| upval| <0x" << std::hex << p
|
||||
<< std::dec << "> [" << val.upval().size
|
||||
<< " val]"; break;
|
||||
case vm_vec: std::clog << "| vec | <0x" << std::hex << (u64)p
|
||||
case vm_vec: std::clog << "| vec | <0x" << std::hex << p
|
||||
<< std::dec << "> [" << val.vec().size()
|
||||
<< " val]"; break;
|
||||
case vm_hash: std::clog << "| hash | <0x" << std::hex << (u64)p
|
||||
case vm_hash: std::clog << "| hash | <0x" << std::hex << p
|
||||
<< std::dec << "> {" << val.hash().size()
|
||||
<< " val}"; break;
|
||||
case vm_obj: std::clog << "| obj | <0x" << std::hex << (u64)p
|
||||
<< "> obj:0x" << (u64)val.obj().ptr
|
||||
case vm_obj: std::clog << "| obj | <0x" << std::hex << p
|
||||
<< "> obj:0x"
|
||||
<< reinterpret_cast<u64>(val.obj().ptr)
|
||||
<< std::dec; break;
|
||||
case vm_co: std::clog << "| co | <0x" << std::hex << (u64)p
|
||||
case vm_co: std::clog << "| co | <0x" << std::hex << p
|
||||
<< std::dec << "> coroutine"; break;
|
||||
case vm_map: std::clog << "| nmspc| <0x" << std::hex << (u64)p
|
||||
case vm_map: std::clog << "| nmspc| <0x" << std::hex << p
|
||||
<< std::dec << "> namespace ["
|
||||
<< val.map().mapper.size() << " val]"; break;
|
||||
default: std::clog << "| err | <0x" << std::hex << (u64)p
|
||||
default: std::clog << "| err | <0x" << std::hex << p
|
||||
<< std::dec << "> unknown object"; break;
|
||||
}
|
||||
std::clog << "\n";
|
||||
|
@ -128,13 +142,13 @@ void vm::traceback() {
|
|||
void vm::stackinfo(const u32 limit = 10) {
|
||||
var* top = ctx.top;
|
||||
var* bottom = ctx.stack;
|
||||
std::clog << "stack (0x" << std::hex << (u64)bottom << std::dec;
|
||||
std::clog << ", limit " << limit << ", total ";
|
||||
std::clog << (top<bottom? 0:(i64)(top-bottom+1)) << ")\n";
|
||||
std::clog << "stack (0x" << std::hex << reinterpret_cast<u64>(bottom);
|
||||
std::clog << std::dec << ", limit " << limit << ", total ";
|
||||
std::clog << (top<bottom? 0:static_cast<i64>(top-bottom+1)) << ")\n";
|
||||
for(u32 i = 0; i<limit && top>=bottom; ++i, --top) {
|
||||
std::clog << " 0x" << std::hex
|
||||
<< std::setw(6) << std::setfill('0')
|
||||
<< (u64)(top-bottom) << std::dec
|
||||
<< static_cast<u64>(top-bottom) << std::dec
|
||||
<< " ";
|
||||
valinfo(top[0]);
|
||||
}
|
||||
|
@ -144,11 +158,16 @@ void vm::reginfo() {
|
|||
std::clog << "registers (" << (ngc.cort? "coroutine":"main")
|
||||
<< ")\n" << std::hex
|
||||
<< " [pc ] | pc | 0x" << ctx.pc << "\n"
|
||||
<< " [global] | addr | 0x" << (u64)global << "\n"
|
||||
<< " [local ] | addr | 0x" << (u64)ctx.localr << "\n"
|
||||
<< " [memr ] | addr | 0x" << (u64)ctx.memr << "\n"
|
||||
<< " [canary] | addr | 0x" << (u64)ctx.canary << "\n"
|
||||
<< " [top ] | addr | 0x" << (u64)ctx.top << "\n"
|
||||
<< " [global] | addr | 0x"
|
||||
<< reinterpret_cast<u64>(global) << "\n"
|
||||
<< " [local ] | addr | 0x"
|
||||
<< reinterpret_cast<u64>(ctx.localr) << "\n"
|
||||
<< " [memr ] | addr | 0x"
|
||||
<< reinterpret_cast<u64>(ctx.memr) << "\n"
|
||||
<< " [canary] | addr | 0x"
|
||||
<< reinterpret_cast<u64>(ctx.canary) << "\n"
|
||||
<< " [top ] | addr | 0x"
|
||||
<< reinterpret_cast<u64>(ctx.top) << "\n"
|
||||
<< std::dec;
|
||||
std::clog << " [funcr ] "; valinfo(ctx.funcr);
|
||||
std::clog << " [upval ] "; valinfo(ctx.upvalr);
|
||||
|
@ -159,7 +178,7 @@ void vm::gstate() {
|
|||
return;
|
||||
}
|
||||
std::clog << "global (0x" << std::hex
|
||||
<< (u64)global << ")\n" << std::dec;
|
||||
<< reinterpret_cast<u64>(global) << ")\n" << std::dec;
|
||||
for(usize i = 0; i<global_size; ++i) {
|
||||
std::clog << " 0x" << std::hex << std::setw(6)
|
||||
<< std::setfill('0') << i << std::dec
|
||||
|
@ -173,8 +192,8 @@ void vm::lstate() {
|
|||
return;
|
||||
}
|
||||
const u32 lsize = ctx.funcr.func().lsize;
|
||||
std::clog << "local (0x" << std::hex << (u64)ctx.localr
|
||||
<< " <+" << (u64)(ctx.localr-ctx.stack)
|
||||
std::clog << "local (0x" << std::hex << reinterpret_cast<u64>(ctx.localr)
|
||||
<< " <+" << static_cast<u64>(ctx.localr-ctx.stack)
|
||||
<< ">)\n" << std::dec;
|
||||
for(u32 i = 0; i<lsize; ++i) {
|
||||
std::clog << " 0x" << std::hex << std::setw(6)
|
||||
|
@ -233,9 +252,8 @@ void vm::die(const std::string& str) {
|
|||
void vm::run(
|
||||
const codegen& gen,
|
||||
const linker& linker,
|
||||
const std::vector<std::string>& argv,
|
||||
const bool detail) {
|
||||
verbose = detail;
|
||||
const std::vector<std::string>& argv
|
||||
) {
|
||||
init(gen.strs(), gen.nums(), gen.natives(),
|
||||
gen.codes(), gen.globals(), linker.get_file_list(), argv);
|
||||
#ifndef _MSC_VER
|
||||
|
@ -334,11 +352,13 @@ void vm::run(
|
|||
#endif
|
||||
|
||||
vmexit:
|
||||
if (detail) {
|
||||
if (verbose) {
|
||||
ngc.info();
|
||||
}
|
||||
ngc.clear();
|
||||
imm.clear();
|
||||
if (!is_repl_mode) {
|
||||
ngc.clear();
|
||||
}
|
||||
return;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
|
|
@ -38,6 +38,10 @@ protected:
|
|||
const std::string* files = nullptr; // file name list
|
||||
const opcode* bytecode = nullptr; // bytecode buffer address
|
||||
|
||||
/* variables for repl mode */
|
||||
bool is_repl_mode = false;
|
||||
bool first_exec_flag = true;
|
||||
|
||||
/* vm initializing function */
|
||||
void init(
|
||||
const std::vector<std::string>&,
|
||||
|
@ -46,7 +50,9 @@ protected:
|
|||
const std::vector<opcode>&,
|
||||
const std::unordered_map<std::string, i32>&,
|
||||
const std::vector<std::string>&,
|
||||
const std::vector<std::string>&);
|
||||
const std::vector<std::string>&
|
||||
);
|
||||
void context_and_global_init();
|
||||
|
||||
/* debug functions */
|
||||
bool verbose = false;
|
||||
|
@ -167,8 +173,13 @@ public:
|
|||
void run(
|
||||
const codegen&,
|
||||
const linker&,
|
||||
const std::vector<std::string>&,
|
||||
const bool);
|
||||
const std::vector<std::string>&
|
||||
);
|
||||
|
||||
/* set detail report info flag */
|
||||
void set_detail_report_info(bool flag) {verbose = flag;}
|
||||
/* set repl mode flag */
|
||||
void set_repl_mode_flag(bool flag) {is_repl_mode = flag;}
|
||||
};
|
||||
|
||||
inline bool vm::cond(var& val) {
|
||||
|
@ -285,7 +296,7 @@ inline void vm::o_lnot() {
|
|||
case vm_str: {
|
||||
const f64 num = str2num(val.str().c_str());
|
||||
if (std::isnan(num)) {
|
||||
ctx.top[0] = var::num((f64)val.str().empty());
|
||||
ctx.top[0] = var::num(static_cast<f64>(val.str().empty()));
|
||||
} else {
|
||||
ctx.top[0] = num? zero:one;
|
||||
}
|
||||
|
|
36
src/repl.cpp
36
src/repl.cpp
|
@ -21,7 +21,7 @@ void repl::update_temp_file() {
|
|||
for(const auto& i : source) {
|
||||
content += i + "\n";
|
||||
}
|
||||
info::instance()->repl_file_source = content;
|
||||
info::instance()->repl_file_source = content + " ";
|
||||
}
|
||||
|
||||
bool repl::check_need_more_input() {
|
||||
|
@ -49,6 +49,7 @@ bool repl::check_need_more_input() {
|
|||
if (in_curve<=0 && in_bracket<=0 && in_brace<=0) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto line = readline("... ");
|
||||
source.back() += "\n" + line;
|
||||
}
|
||||
|
@ -56,27 +57,26 @@ bool repl::check_need_more_input() {
|
|||
}
|
||||
|
||||
void repl::help() {
|
||||
std::cout << ".h, .help | show help\n";
|
||||
std::cout << ".e, .exit | quit the REPL\n";
|
||||
std::cout << ".q, .quit | quit the REPL\n";
|
||||
std::cout << ".c, .clear | clear the screen\n";
|
||||
std::cout << ".h, .help | show help\n";
|
||||
std::cout << ".e, .exit | quit the REPL\n";
|
||||
std::cout << ".q, .quit | quit the REPL\n";
|
||||
std::cout << ".c, .clear | clear the screen\n";
|
||||
std::cout << ".s, .source | show source code\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
bool repl::run() {
|
||||
update_temp_file();
|
||||
|
||||
using clk = std::chrono::high_resolution_clock;
|
||||
const auto den = clk::duration::period::den;
|
||||
auto start = clk::now();
|
||||
const auto den = clk::duration::period::den;
|
||||
|
||||
auto nasal_lexer = std::unique_ptr<lexer>(new lexer);
|
||||
auto nasal_parser = std::unique_ptr<parse>(new parse);
|
||||
auto nasal_linker = std::unique_ptr<linker>(new linker);
|
||||
auto nasal_opt = std::unique_ptr<optimizer>(new optimizer);
|
||||
auto nasal_codegen = std::unique_ptr<codegen>(new codegen);
|
||||
auto nasal_runtime = std::unique_ptr<vm>(new vm);
|
||||
|
||||
auto start = clk::now();
|
||||
update_temp_file();
|
||||
if (nasal_lexer->scan("<nasal-repl>").geterr()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -89,14 +89,18 @@ bool repl::run() {
|
|||
return false;
|
||||
}
|
||||
|
||||
nasal_opt->do_optimization(nasal_parser->tree());
|
||||
// nasal_opt->do_optimization(nasal_parser->tree());
|
||||
if (nasal_codegen->compile(*nasal_parser, *nasal_linker).geterr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto end = clk::now();
|
||||
std::clog << "[compile time: " << (end-start).count()*1000.0/den << " ms]\n";
|
||||
nasal_runtime->run(*nasal_codegen, *nasal_linker, {}, false);
|
||||
|
||||
// TODO: gc init stage in this run may cause memory leak,
|
||||
// because constant strings will be generated again.
|
||||
// but we could not delete old strings, they maybe still on stack.
|
||||
runtime.run(*nasal_codegen, *nasal_linker, {});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -114,7 +118,9 @@ void repl::execute() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (line == ".e" || line == ".exit" || line == ".q" || line == ".quit") {
|
||||
if (line == ".e" || line == ".exit") {
|
||||
break;
|
||||
} else if (line == ".q" || line == ".quit") {
|
||||
break;
|
||||
} else if (line == ".h" || line == ".help") {
|
||||
help();
|
||||
|
@ -122,6 +128,10 @@ void repl::execute() {
|
|||
} else if (line == ".c" || line == ".clear") {
|
||||
std::cout << "\033c";
|
||||
continue;
|
||||
} else if (line == ".s" || line == ".source") {
|
||||
update_temp_file();
|
||||
std::cout << info::instance()->repl_file_source << "\n";
|
||||
continue;
|
||||
} else if (line[0] == "."[0]) {
|
||||
std::cout << "no such command \"" << line;
|
||||
std::cout << "\", input \".help\" for help\n";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "nasal.h"
|
||||
#include "nasal_vm.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
@ -26,6 +27,7 @@ struct info {
|
|||
class repl {
|
||||
private:
|
||||
std::vector<std::string> source;
|
||||
vm runtime;
|
||||
|
||||
private:
|
||||
std::string readline(std::string);
|
||||
|
@ -35,6 +37,12 @@ private:
|
|||
bool run();
|
||||
|
||||
public:
|
||||
repl() {
|
||||
// set repl mode
|
||||
runtime.set_repl_mode_flag(true);
|
||||
// no detail report info
|
||||
runtime.set_detail_report_info(false);
|
||||
}
|
||||
void execute();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#include "unix_lib.h"
|
||||
|
||||
namespace nasal {
|
||||
|
||||
const auto dir_type_name = "dir";
|
||||
|
||||
void dir_entry_destructor(void* ptr) {
|
||||
#ifndef _MSC_VER
|
||||
closedir((DIR*)ptr);
|
||||
closedir(static_cast<DIR*>(ptr));
|
||||
#else
|
||||
FindClose(ptr);
|
||||
#endif
|
||||
|
@ -17,11 +19,11 @@ var builtin_pipe(var* local, gc& ngc) {
|
|||
if (pipe(fd)==-1) {
|
||||
return nas_err("pipe", "failed to create pipe");
|
||||
}
|
||||
res.vec().elems.push_back(var::num((f64)fd[0]));
|
||||
res.vec().elems.push_back(var::num((f64)fd[1]));
|
||||
res.vec().elems.push_back(var::num(static_cast<f64>(fd[0])));
|
||||
res.vec().elems.push_back(var::num(static_cast<f64>(fd[1])));
|
||||
return res;
|
||||
#endif
|
||||
return nas_err("pipe", "not supported");
|
||||
return nas_err("pipe", "not supported on windows");
|
||||
}
|
||||
|
||||
var builtin_fork(var* local, gc& ngc) {
|
||||
|
@ -30,9 +32,9 @@ var builtin_fork(var* local, gc& ngc) {
|
|||
if (res<0) {
|
||||
return nas_err("fork", "failed to fork a process");
|
||||
}
|
||||
return var::num((f64)res);
|
||||
return var::num(static_cast<f64>(res));
|
||||
#endif
|
||||
return nas_err("fork", "not supported");
|
||||
return nas_err("fork", "not supported on windows");
|
||||
}
|
||||
|
||||
var builtin_waitpid(var* local, gc& ngc) {
|
||||
|
@ -42,14 +44,14 @@ var builtin_waitpid(var* local, gc& ngc) {
|
|||
return nas_err("waitpid", "pid and nohang must be number");
|
||||
}
|
||||
#ifndef _WIN32
|
||||
i32 ret_pid,status;
|
||||
ret_pid = waitpid(pid.num(),&status,nohang.num()==0? 0:WNOHANG);
|
||||
i32 ret_pid, status;
|
||||
ret_pid = waitpid(pid.num(), &status, nohang.num()==0? 0:WNOHANG);
|
||||
var vec = ngc.alloc(vm_vec);
|
||||
vec.vec().elems.push_back(var::num((f64)ret_pid));
|
||||
vec.vec().elems.push_back(var::num((f64)status));
|
||||
vec.vec().elems.push_back(var::num(static_cast<f64>(ret_pid)));
|
||||
vec.vec().elems.push_back(var::num(static_cast<f64>(status)));
|
||||
return vec;
|
||||
#endif
|
||||
return nas_err("waitpid", "not supported");
|
||||
return nas_err("waitpid", "not supported on windows");
|
||||
}
|
||||
|
||||
var builtin_opendir(var* local, gc& ngc) {
|
||||
|
@ -60,7 +62,7 @@ var builtin_opendir(var* local, gc& ngc) {
|
|||
#ifdef _MSC_VER
|
||||
WIN32_FIND_DATAA data;
|
||||
HANDLE p;
|
||||
p = FindFirstFileA((path.str()+"\\*.*").c_str(),&data);
|
||||
p = FindFirstFileA((path.str()+"\\*.*").c_str(), &data);
|
||||
if (p==INVALID_HANDLE_VALUE) {
|
||||
return nas_err("opendir", "cannot open dir <"+path.str()+">");
|
||||
}
|
||||
|
@ -87,7 +89,7 @@ var builtin_readdir(var* local, gc& ngc) {
|
|||
}
|
||||
return ngc.newstr(data.cFileName);
|
||||
#else
|
||||
dirent* p = readdir((DIR*)handle.obj().ptr);
|
||||
dirent* p = readdir(static_cast<DIR*>(handle.obj().ptr));
|
||||
return p? ngc.newstr(p->d_name):nil;
|
||||
#endif
|
||||
}
|
||||
|
@ -104,9 +106,9 @@ var builtin_closedir(var* local, gc& ngc) {
|
|||
var builtin_chdir(var* local, gc& ngc) {
|
||||
var path = local[1];
|
||||
if (path.type!=vm_str) {
|
||||
return var::num((f64)-1);
|
||||
return var::num(-1.0);
|
||||
}
|
||||
return var::num((f64)chdir(path.str().c_str()));
|
||||
return var::num(static_cast<f64>(chdir(path.str().c_str())));
|
||||
}
|
||||
|
||||
var builtin_environ(var* local, gc& ngc) {
|
||||
|
@ -148,4 +150,6 @@ nasal_builtin_table unix_lib_native[] = {
|
|||
{"__getcwd", builtin_getcwd},
|
||||
{"__getenv", builtin_getenv},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
namespace nasal {
|
||||
|
||||
void dir_entry_destructor(void*);
|
||||
|
||||
var builtin_pipe(var*, gc&);
|
||||
|
@ -33,4 +35,6 @@ var builtin_environ(var*, gc&);
|
|||
var builtin_getcwd(var*, gc&);
|
||||
var builtin_getenv(var*, gc&);
|
||||
|
||||
extern nasal_builtin_table unix_lib_native[];
|
||||
extern nasal_builtin_table unix_lib_native[];
|
||||
|
||||
}
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
# experimental repl
|
||||
# 2023/8/19 by ValKmjolnir
|
||||
|
||||
var help = func() {
|
||||
println(" .help | show help");
|
||||
println(" .exit | quit the REPL");
|
||||
println(" .quit | quit the REPL");
|
||||
println(" .clear | clear the screen");
|
||||
println();
|
||||
}
|
||||
|
||||
var content = [];
|
||||
var log_cache = "";
|
||||
|
||||
println("Nasal: This is experimental REPL");
|
||||
println("Tips : \";\" is automatically added at the end of the input line.");
|
||||
help();
|
||||
|
||||
var count_bracket = func(line) {
|
||||
var len = size(line);
|
||||
var count = 0;
|
||||
for(var i = 0; i < len; i += 1) {
|
||||
if (line[i] == "{"[0]) {
|
||||
count += 1;
|
||||
} elsif (line[i] == "}"[0]) {
|
||||
count -= 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
var line = readline(">>> ");
|
||||
if (!size(line)) {
|
||||
continue;
|
||||
}
|
||||
if (line == ".exit" or line == ".quit") {
|
||||
break;
|
||||
} elsif (line == ".help") {
|
||||
println();
|
||||
help();
|
||||
continue;
|
||||
} elsif (line == ".clear") {
|
||||
print("\ec");
|
||||
continue;
|
||||
} elsif (line[0] == "."[0]) {
|
||||
println("no such command \"", line, "\", input \".help\" for help\n");
|
||||
continue;
|
||||
}
|
||||
var in_bracket_level = count_bracket(line);
|
||||
while(in_bracket_level > 0) {
|
||||
var temp_line = readline("... ");
|
||||
in_bracket_level += count_bracket(temp_line);
|
||||
line ~= temp_line ~ "\n";
|
||||
}
|
||||
|
||||
append(content, line);
|
||||
|
||||
var source = "";
|
||||
foreach(var i; content) {
|
||||
source ~= i ~ ";\n";
|
||||
}
|
||||
|
||||
io.fout(".temp.nas", source);
|
||||
var result = system("nasal .temp.nas > .temp.log");
|
||||
if (result != 0) {
|
||||
pop(content);
|
||||
continue;
|
||||
}
|
||||
|
||||
var log = io.readfile(".temp.log");
|
||||
if (size(log) and size(log) != size(log_cache)) {
|
||||
println(substr(log, size(log_cache), size(log)), "\n");
|
||||
log_cache = log;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue