Merge pull request #19 from ValKmjolnir/develop

 add ghost_type_table for type registration & add cmake for VS to build
This commit is contained in:
Li Haokun 2023-05-11 20:59:49 +08:00 committed by GitHub
commit 36f6dd6c96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 959 additions and 788 deletions

2
.gitignore vendored
View File

@ -38,6 +38,7 @@
*.vcxproj.user
.vs
x64
CMakePresents.json
# nasal executable
nasal
@ -49,6 +50,7 @@ dump
# build dir
build
out
# macOS special cache directory
.DS_Store

View File

@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.10)
project(nasal VERSION 10.1)
message("CMAKE_HOST_SYSTEM_NAME: ${CMAKE_HOST_SYSTEM_NAME}")
# -std=c++14 -Wshadow -Wall
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
@ -9,6 +11,7 @@ set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wshadow -Wall")
# generate release executables
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/module)
add_library(fib SHARED ${CMAKE_SOURCE_DIR}/module/fib.cpp)
target_include_directories(fib PRIVATE ${CMAKE_SOURCE_DIR})
@ -23,5 +26,20 @@ add_library(nasock SHARED ${CMAKE_SOURCE_DIR}/module/nasocket.cpp)
target_include_directories(nasock PRIVATE ${CMAKE_SOURCE_DIR})
add_executable(nasal main.cpp)
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
message("Ignore linking dl lib")
else()
target_link_libraries(nasal dl)
endif()
target_include_directories(nasal PRIVATE ${CMAKE_SOURCE_DIR})
if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
add_custom_command(
TARGET nasal POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/build/nasal
${CMAKE_SOURCE_DIR}/nasal
)
endif()

View File

@ -2,12 +2,22 @@
## First | 首先
Make sure you are using VS 2022.
We give a __CMakeLists.txt__ for you to create new VS project from it.
确保你使用的是 VS 2022。
我们为你提供了 __CMakeLists.txt__ 用于创建新的 VS 工程。
If you are using this way, you will __not need__ to continue reading.
如果你使用的是这种方式,下面的内容你就 __不需要__ 再读了。
Creating VS project from a CMake file is the __simplest__ way.
从 CMake 文件创建 VS 工程是 __最简单__ 的方式。
## How to Create VS project
Make sure you are using VS 2022. You may not get the dynamic libraries by using this way to compile.
1. Get code from this repo using `git`.
2. In Visual Studio, click `File`->`New`->`Project From Existing Code...`.
@ -20,6 +30,8 @@ Make sure you are using VS 2022.
## 如何创建VS工程
确保你使用的是 VS 2022。这个方式可能无法生成一些动态库。
1. 用 `git` 从这个仓库获取代码。
2. 在VS的界面点击文件(F)->新建(N)->从现有代码创建项目(E)。

View File

@ -1,6 +1,10 @@
// module for test
#include <iostream>
#include "../nasal.h"
namespace nasal_fib_module {
double fibonaci(double x) {
if (x<=2) {
return x;
@ -33,12 +37,63 @@ var quick_fib(var* args, usize size, gc* ngc) {
return var::num(res);
}
mod_func func_tbl[]={
u32 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<<"}\n";
}
var create_new_ghost(var* args, usize size, gc* ngc) {
var res=ngc->alloc(vm_obj);
res.obj().set(ghost_for_test, new u32, &ngc->global_ghost_type_table);
return res;
}
var set_new_ghost(var* args, usize size, gc* ngc) {
var res=args[0];
if (!res.objchk(ghost_for_test)) {
std::cout<<"set_new_ghost: not ghost for test type.\n";
return nil;
}
f64 num=args[1].num();
*((u32*)res.obj().ptr)=static_cast<u32>(num);
std::cout<<"set_new_ghost: successfully set ghost = "<<num<<"\n";
return nil;
}
var print_new_ghost(var* args, usize size, gc* ngc) {
var res=args[0];
if (!res.objchk(ghost_for_test)) {
std::cout<<"print_new_ghost: not ghost for test type.\n";
return nil;
}
std::cout<<"print_new_ghost: "<<res.obj()<<" result = "<<*((u32*)res.obj().ptr)<<"\n";
return nil;
}
module_func_info func_tbl[]={
{"fib", fib},
{"quick_fib", quick_fib},
{nullptr, nullptr},
{"create_ghost", create_new_ghost},
{"set_ghost", set_new_ghost},
{"print_ghost", print_new_ghost},
{nullptr, nullptr}
};
extern "C" mod_func* get() {
return func_tbl;
}
extern "C" module_func_info* get(ghost_register_table* table) {
if (table->exists("fib_for_test")) {
nasal_fib_module::ghost_for_test=table->get_ghost_type_index("fib_for_test");
return nasal_fib_module::func_tbl;
}
nasal_fib_module::ghost_for_test=table->register_ghost_type(
"fib_for_test",
nasal_fib_module::ghost_for_test_destructor
);
return nasal_fib_module::func_tbl;
}

View File

@ -1,6 +1,10 @@
#include "../nasal.h"
#include <unistd.h>
#include <iostream>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#ifdef _WIN32
#include <conio.h>
#else
@ -88,13 +92,13 @@ var nas_noblock(var* args, usize size, gc* ngc) {
return nil;
}
mod_func func_tbl[]={
module_func_info func_tbl[]={
{"nas_getch",nas_getch},
{"nas_kbhit",nas_kbhit},
{"nas_noblock",nas_noblock},
{nullptr,nullptr}
};
extern "C" mod_func* get() {
extern "C" module_func_info* get(ghost_register_table* table) {
return func_tbl;
}

View File

@ -2,9 +2,28 @@ var libfib=func(){
var dl=dylib.dlopen("libfib."~(os.platform()=="windows"?"dll":"so"));
var fib=dl.fib;
var qfib=dl.quick_fib;
var create_ghost=dl.create_ghost;
var set_ghost=dl.set_ghost;
var print_ghost=dl.print_ghost;
var zero_call=dylib.limitcall(0);
var call=dylib.limitcall(1);
return {
var test_call=dylib.limitcall(2);
var res={
fib: func(x) {return call(fib,x)},
qfib:func(x){return call(qfib,x)}
qfib: func(x) {return call(qfib,x)},
create_ghost: func() {return zero_call(create_ghost)},
set_ghost: func(object, x) {return test_call(set_ghost, object, x)},
print_ghost: func(object) {return call(print_ghost, object)}
};
res.test_ghost=func() {
var ghost=res.create_ghost();
res.print_ghost(nil); # err
res.print_ghost(ghost); # random
res.set_ghost(nil, 114); # err
res.set_ghost(ghost, 114); # success
res.print_ghost(ghost); # 114
}
return res;
}();

View File

@ -266,7 +266,7 @@ var nas_vec3_dot(var* args, usize size, gc* ngc) {
return var::num(v0[0].num()*v1[0].num()+v0[1].num()*v1[1].num()+v0[2].num()*v1[2].num());
}
mod_func func_tbl[]={
module_func_info func_tbl[]={
{"nas_vec2",nas_vec2},
{"nas_vec2_add",nas_vec2_add},
{"nas_vec2_sub",nas_vec2_sub},
@ -291,6 +291,6 @@ mod_func func_tbl[]={
{nullptr,nullptr}
};
extern "C" mod_func* get() {
extern "C" module_func_info* get(ghost_register_table* table) {
return func_tbl;
}

View File

@ -1,5 +1,8 @@
#include "../nasal.h"
#ifndef _MSC_VER
#include <unistd.h>
#endif
#ifdef _WIN32
#include <winsock.h>
@ -190,7 +193,7 @@ var nas_errno(var* args, usize size, gc* ngc) {
return ngc->newstr(strerror(errno));
}
mod_func func_tbl[]={
module_func_info func_tbl[]={
{"nas_socket",nas_socket},
{"nas_closesocket",nas_closesocket},
{"nas_shutdown",nas_shutdown},
@ -206,6 +209,6 @@ mod_func func_tbl[]={
{nullptr,nullptr}
};
extern "C" mod_func* get() {
extern "C" module_func_info* get(ghost_register_table* table) {
return func_tbl;
}

View File

@ -8,6 +8,9 @@
#include <dirent.h>
#else
#pragma warning (disable:4566) // i know i'm using utf-8, fuck you
#pragma warning (disable:4244)
#pragma warning (disable:4267)
#pragma warning (disable:4996)
#define _CRT_SECURE_NO_DEPRECATE 1
#define _CRT_NONSTDC_NO_DEPRECATE 1
#include <io.h>
@ -544,13 +547,13 @@ var builtin_open(var* local, gc& ngc) {
return nas_err("open", "failed to open file <"+name.str()+">");
}
var ret=ngc.alloc(vm_obj);
ret.obj().set(obj_type::file, res);
ret.obj().set(ngc.global_ghost_type_table.ghost_file, res, &ngc.global_ghost_type_table);
return ret;
}
var builtin_close(var* local, gc& ngc) {
var fd=local[1];
if (!fd.objchk(obj_type::file)) {
if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) {
return nas_err("close", "not a valid filehandle");
}
fd.obj().clear();
@ -561,7 +564,7 @@ var builtin_read(var* local, gc& ngc) {
var fd=local[1];
var buf=local[2];
var len=local[3];
if (!fd.objchk(obj_type::file)) {
if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) {
return nas_err("read", "not a valid filehandle");
}
if (buf.type!=vm_str || buf.val.gcobj->unmut) {
@ -587,7 +590,7 @@ var builtin_read(var* local, gc& ngc) {
var builtin_write(var* local, gc& ngc) {
var fd=local[1];
var str=local[2];
if (!fd.objchk(obj_type::file)) {
if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) {
return nas_err("write", "not a valid filehandle");
}
if (str.type!=vm_str) {
@ -600,7 +603,7 @@ var builtin_seek(var* local, gc& ngc) {
var fd=local[1];
var pos=local[2];
var whence=local[3];
if (!fd.objchk(obj_type::file)) {
if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) {
return nas_err("seek", "not a valid filehandle");
}
return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num()));
@ -608,7 +611,7 @@ var builtin_seek(var* local, gc& ngc) {
var builtin_tell(var* local, gc& ngc) {
var fd=local[1];
if (!fd.objchk(obj_type::file)) {
if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) {
return nas_err("tell", "not a valid filehandle");
}
return var::num((f64)ftell((FILE*)fd.obj().ptr));
@ -616,7 +619,7 @@ var builtin_tell(var* local, gc& ngc) {
var builtin_readln(var* local, gc& ngc) {
var fd=local[1];
if (!fd.objchk(obj_type::file)) {
if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) {
return nas_err("readln", "not a valid filehandle");
}
var str=ngc.alloc(vm_str);
@ -664,7 +667,7 @@ var builtin_stat(var* local, gc& ngc) {
var builtin_eof(var* local, gc& ngc) {
var fd=local[1];
if (!fd.objchk(obj_type::file)) {
if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) {
return nas_err("readln", "not a valid filehandle");
}
return var::num((f64)feof((FILE*)fd.obj().ptr));
@ -849,13 +852,13 @@ var builtin_opendir(var* local, gc& ngc) {
}
#endif
var ret=ngc.alloc(vm_obj);
ret.obj().set(obj_type::dir,p);
ret.obj().set(ngc.global_ghost_type_table.ghost_dir, p, &ngc.global_ghost_type_table);
return ret;
}
var builtin_readdir(var* local, gc& ngc) {
var handle=local[1];
if (!handle.objchk(obj_type::dir)) {
if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) {
return nas_err("readdir", "not a valid dir handle");
}
#ifdef _MSC_VER
@ -872,7 +875,7 @@ var builtin_readdir(var* local, gc& ngc) {
var builtin_closedir(var* local, gc& ngc) {
var handle=local[1];
if (!handle.objchk(obj_type::dir)) {
if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) {
return nas_err("closedir", "not a valid dir handle");
}
handle.obj().clear();
@ -936,7 +939,7 @@ var builtin_dlopen(var* local, gc& ngc) {
}
var ret=ngc.temp=ngc.alloc(vm_hash);
var lib=ngc.alloc(vm_obj);
lib.obj().set(obj_type::dylib, ptr);
lib.obj().set(ngc.global_ghost_type_table.ghost_dylib, ptr, &ngc.global_ghost_type_table);
ret.hash().elems["lib"]=lib;
#ifdef _WIN32
@ -948,14 +951,14 @@ var builtin_dlopen(var* local, gc& ngc) {
return nas_err("dlopen", "cannot find <get> function");
}
// get function pointer by name
mod_func* tbl=(mod_func*)((getptr)func)();
module_func_info* tbl=((get_func_ptr)func)(&ngc.global_ghost_type_table);
if (!tbl) {
return nas_err("dlopen", "failed to get module functions");
}
for(u32 i=0;tbl[i].name;++i) {
void* p=(void*)tbl[i].fd;
var tmp=ngc.alloc(vm_obj);
tmp.obj().set(obj_type::faddr, p);
tmp.obj().set(ngc.global_ghost_type_table.ghost_faddr, p, &ngc.global_ghost_type_table);
ret.hash().elems[tbl[i].name]=tmp;
}
@ -965,7 +968,7 @@ var builtin_dlopen(var* local, gc& ngc) {
var builtin_dlclose(var* local, gc& ngc) {
var libptr=local[1];
if (!libptr.objchk(obj_type::dylib)) {
if (!libptr.objchk(ngc.global_ghost_type_table.ghost_dylib)) {
return nas_err("dlclose", "\"lib\" is not a valid dynamic lib");
}
libptr.obj().clear();
@ -975,23 +978,27 @@ var builtin_dlclose(var* local, gc& ngc) {
var builtin_dlcallv(var* local, gc& ngc) {
var fp=local[1];
var args=local[2];
if (!fp.objchk(obj_type::faddr)) {
if (!fp.objchk(ngc.global_ghost_type_table.ghost_faddr)) {
return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
}
auto& vec=args.vec().elems;
return ((mod)fp.obj().ptr)(vec.data(), vec.size(), &ngc);
return ((module_func)fp.obj().ptr)(
vec.data(),
vec.size(),
&ngc
);
}
var builtin_dlcall(var* local, gc& ngc) {
var fp=local[1];
if (!fp.objchk(obj_type::faddr)) {
if (!fp.objchk(ngc.global_ghost_type_table.ghost_faddr)) {
return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
}
var* local_frame_start=local+2;
usize local_frame_size=ngc.rctx->top-local_frame_start;
// arguments' stored place begins at local +2
return ((mod)fp.obj().ptr)(
return ((module_func)fp.obj().ptr)(
local_frame_start,
local_frame_size,
&ngc

View File

@ -9,6 +9,11 @@
#include <stack>
#include <unordered_map>
#ifdef _MSC_VER
#pragma warning (disable:4244)
#pragma warning (disable:4267)
#endif
class codegen {
private:
u16 fileindex;

View File

@ -1,4 +1,9 @@
#pragma once
#ifdef _MSC_VER
#pragma warning (disable:4244)
#pragma warning (disable:4267)
#pragma warning (disable:4102)
#endif
#ifndef _MSC_VER
#include <unistd.h>
@ -43,14 +48,6 @@ enum vm_type:u8 {
const u32 gc_type_size=vm_co-vm_str+1;
enum class obj_type:u32 {
null=0,
file=1,
dir,
dylib,
faddr
};
enum class coroutine_status:u32 {
suspended,
running,
@ -99,7 +96,7 @@ public:
// number and string can be translated to each other
f64 tonum();
string tostr();
bool objchk(obj_type);
bool objchk(usize);
// create new var object
static var none();
@ -162,6 +159,7 @@ struct nas_func {
};
struct nas_upval {
public:
/* on stack, use these variables */
bool onstk;
u32 size;
@ -170,55 +168,119 @@ struct nas_upval {
/* not on stack, use this */
std::vector<var> elems;
nas_upval() {onstk=true;stk=nullptr;size=0;}
var& operator[](usize n) {return onstk? stk[n]:elems[n];}
void clear() {onstk=true;elems.clear();size=0;}
};
struct ghost_info {
string name;
void (*destructor)(void*);
};
struct nas_ghost {
private:
static std::vector<ghost_info> ghost_register_table;
usize type;
void* ptr;
public:
nas_ghost(): type(0), ptr(nullptr) {}
~nas_ghost() {
if (!ptr) { return; }
ghost_register_table[type].destructor(ptr);
nas_upval(): onstk(true), size(0), stk(nullptr) {}
var& operator[](usize n) {
return onstk? stk[n]:elems[n];
}
static usize regist_ghost_type(ghost_info i) {
auto res=ghost_register_table.size();
ghost_register_table.push_back(i);
void clear() {
onstk=true;
elems.clear();
size=0;
}
};
void filehandle_destructor(void* ptr) {
if ((FILE*)ptr==stdin) {
return;
}
fclose((FILE*)ptr);
}
void dir_entry_destructor(void* ptr) {
#ifndef _MSC_VER
closedir((DIR*)ptr);
#else
FindClose(ptr);
#endif
}
void dylib_destructor(void* ptr) {
#ifdef _WIN32
FreeLibrary((HMODULE)ptr);
#else
dlclose(ptr);
#endif
}
void func_addr_destructor(void* ptr) {}
struct ghost_register_table {
private:
using dtor=void (*)(void*);
private:
std::unordered_map<string,usize> mapper;
std::vector<string> ghost_name;
std::vector<dtor> destructors;
public:
// reserved ghost type only for native functions
usize ghost_file;
usize ghost_dir;
usize ghost_dylib;
usize ghost_faddr;
public:
ghost_register_table() {
ghost_file=register_ghost_type("file", filehandle_destructor);
ghost_dir=register_ghost_type("dir", dir_entry_destructor);
ghost_dylib=register_ghost_type("dylib", dylib_destructor);
ghost_faddr=register_ghost_type("faddr", func_addr_destructor);
}
bool exists(const string& name) const {
return mapper.count(name);
}
usize get_ghost_type_index(const string& name) const {
return mapper.at(name);
}
const string& get_ghost_name(usize index) const {
return ghost_name.at(index);
}
usize register_ghost_type(const std::string& name, dtor ptr) {
if (mapper.count(name)) {
std::cerr<<"nasal_gc.h: ghost_register_table::register_ghost_type: ";
std::cerr<<"ghost type \""<<name<<"\" already exists.\n";
std::exit(-1);
}
auto res=destructors.size();
mapper[name]=res;
ghost_name.push_back(name);
destructors.push_back(ptr);
return res;
}
const std::string& name() {
return ghost_register_table[type].name;
dtor destructor(usize index) {
return destructors.at(index);
}
};
struct nas_obj {
obj_type type;
public:
usize type;
void* ptr;
private:
/* RAII constructor, new object is initialized when creating */
void file_dtor();
void dir_dtor();
void dylib_dtor();
ghost_register_table* ghost_type_table;
public:
nas_obj(): type(obj_type::null), ptr(nullptr) {}
nas_obj(): type(0), ptr(nullptr), ghost_type_table(nullptr) {}
~nas_obj() {clear();}
void set(obj_type, void*);
void set(usize, void*, ghost_register_table*);
void clear();
public:
friend std::ostream& operator<<(std::ostream& out, nas_obj& ghost) {
out<<"<object "<<ghost.ghost_type_table->get_ghost_name(ghost.type);
out<<" at 0x"<<std::hex<<(u64)ghost.ptr<<std::dec<<">";
return out;
}
};
struct context {
@ -357,47 +419,20 @@ void nas_func::clear() {
keys.clear();
}
void nas_obj::set(obj_type t, void* p) {
void nas_obj::set(usize t, void* p, ghost_register_table* table) {
type=t;
ptr=p;
ghost_type_table=table;
}
void nas_obj::clear() {
if (!ptr) {
return;
}
switch(type) {
case obj_type::file: file_dtor(); break;
case obj_type::dir: dir_dtor(); break;
case obj_type::dylib: dylib_dtor();break;
default: break;
}
ghost_type_table->destructor(type)(ptr);
ptr=nullptr;
}
void nas_obj::file_dtor() {
if ((FILE*)ptr==stdin) {
return;
}
fclose((FILE*)ptr);
}
void nas_obj::dir_dtor() {
#ifndef _MSC_VER
closedir((DIR*)ptr);
#else
FindClose(ptr);
#endif
}
void nas_obj::dylib_dtor() {
#ifdef _WIN32
FreeLibrary((HMODULE)ptr);
#else
dlclose(ptr);
#endif
}
void nas_co::clear() {
for(u32 i=0;i<STACK_DEPTH;++i) {
stack[i]=var::nil();
@ -479,14 +514,14 @@ std::ostream& operator<<(std::ostream& out, var& ref) {
case vm_vec: out<<ref.vec(); break;
case vm_hash: out<<ref.hash(); break;
case vm_func: out<<"func(..) {..}";break;
case vm_obj: out<<"<object>"; break;
case vm_obj: out<<ref.obj(); break;
case vm_co: out<<"<coroutine>"; break;
}
return out;
}
bool var::objchk(obj_type objtype) {
return type==vm_obj && obj().type==objtype && obj().ptr;
bool var::objchk(usize obj_type) {
return type==vm_obj && obj().type==obj_type && obj().ptr;
}
var var::none() {
@ -534,6 +569,7 @@ const var one =var::num(1);
const var nil =var::nil();
struct gc {
ghost_register_table global_ghost_type_table;
/* main context temporary storage */
context mctx;
@ -587,11 +623,27 @@ public:
void clear();
void info();
var alloc(const u8);
var newstr(char);
var newstr(const char*);
var newstr(const string&);
void ctxchg(nas_co&);
void ctxreserve();
public:
var newstr(char c) {
var s=alloc(vm_str);
s.str()=c;
return s;
}
var newstr(const char* buff) {
var s=alloc(vm_str);
s.str()=buff;
return s;
}
var newstr(const string& buff) {
var s=alloc(vm_str);
s.str()=buff;
return s;
}
};
void gc::mark() {
@ -691,14 +743,15 @@ void gc::sweep() {
}
void gc::extend(u8 type) {
u8 index=type-vm_str;
const u8 index=type-vm_str;
size[index]+=incr[index];
for(u32 i=0;i<incr[index];++i) {
nas_val* tmp=new nas_val(type);
if (!tmp) {
std::cerr<<"failed to allocate new memory\n";
std::cerr<<"nasal_gc.h: gc::extend: ";
std::cerr<<"failed to allocate memory\n";
std::exit(-1);
}
@ -720,7 +773,7 @@ void gc::init(const std::vector<string>& s, const std::vector<string>& argv) {
size[i]=gcnt[i]=acnt[i]=0;
}
// coroutine pointer set to nullpre
// coroutine pointer set to nullptr
cort=nullptr;
// init constant strings
@ -820,24 +873,6 @@ var gc::alloc(u8 type) {
return ret;
}
var gc::newstr(char c) {
var s=alloc(vm_str);
s.str()=c;
return s;
}
var gc::newstr(const char* buff) {
var s=alloc(vm_str);
s.str()=buff;
return s;
}
var gc::newstr(const string& buff) {
var s=alloc(vm_str);
s.str()=buff;
return s;
}
void gc::ctxchg(nas_co& co) {
// store running state to main context
mctx=*rctx;
@ -869,19 +904,19 @@ void gc::ctxreserve() {
}
// use to print error log and return error value
var nas_err(const string& err_f, const string& info) {
std::cerr<<"[vm] "<<err_f<<": "<<info<<"\n";
var nas_err(const string& error_function_name, const string& info) {
std::cerr<<"[vm] "<<error_function_name<<": "<<info<<"\n";
return var::none();
}
// module function type
typedef var (*mod)(var*, usize, gc*);
typedef var (*module_func)(var*, usize, gc*);
// module function stores in tables with this type, end with {nullptr,nullptr}
struct mod_func {
struct module_func_info {
const char* name;
mod fd;
module_func fd;
};
// module function "get" type
typedef mod_func* (*getptr)();
typedef module_func_info* (*get_func_ptr)(ghost_register_table*);

View File

@ -1,4 +1,9 @@
#pragma once
#ifdef _MSC_VER
#pragma warning (disable:4244)
#pragma warning (disable:4267)
#pragma warning (disable:4102)
#endif
#include <cstring>
#include <sstream>

View File

@ -7,6 +7,12 @@
#include "nasal_gc.h"
#include "nasal_codegen.h"
#ifdef _MSC_VER
#pragma warning (disable:4244)
#pragma warning (disable:4267)
#pragma warning (disable:4102)
#endif
class vm {
protected:

View File

@ -11,7 +11,7 @@ var new_map=func(width,height){
}
var prt=func(map){
var s='\e[1;1H';
var s='\ec\e[1;1H';
foreach(var line;map){
foreach(var elem;line)
s~=elem~' ';