diff --git a/doc/tutorial.md b/doc/tutorial.md index d2af8fc..6188298 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -113,11 +113,12 @@ This type is created by native-function of nasal. If want to define a new data t ## Operators -Nasal has basic math operators `+` `-` `*` `/` and a special operator `~` that joints strings. +Nasal has basic math operators `+` `-` `*` `/` and a special operator `~` that joints strings or vectors. ```javascript 1+2-(1+3)*(2+4)/(16-9); "str1"~"str2"; +[0]~[1]; # should be [0, 1] ``` For conditional expressions, operators `==` `!=` `<` `>` `<=` `>=` are used to compare two values. @@ -162,6 +163,9 @@ a ~= "string"; a ^= 0xff; a &= 0xca; a |= 0xba; + +a = [0]; +a ~= [1]; # should be [0, 1] ``` Operator `??` is used to check left hand side value is `nil` or not, if not, diff --git a/doc/tutorial_zh.md b/doc/tutorial_zh.md index 9500456..62910ad 100644 --- a/doc/tutorial_zh.md +++ b/doc/tutorial_zh.md @@ -109,11 +109,12 @@ __`ghost`__ 是用来存储`C/C++`的一些复杂数据结构。这种类型的 ## 运算符 -Nasal拥有基本的四种数学运算符 `+` `-` `*` `/`以及一个特别的运算符 `~`,用于拼接字符串。 +Nasal拥有基本的四种数学运算符 `+` `-` `*` `/`以及一个特别的运算符 `~`,用于拼接字符串或者数组。 ```javascript 1+2-(1+3)*(2+4)/(16-9); "str1"~"str2"; +[0]~[1]; # should be [0, 1] ``` 对于条件语句,可以使用`==` `!=` `<` `>` `<=` `>=`来比较数据。`and` `or` 与C/C++中 `&&` `||`运算符一致。 @@ -157,6 +158,9 @@ a ~= "string"; a ^= 0xff; a &= 0xca; a |= 0xba; + +a = [0]; +a ~= [1]; # should be [0, 1] ``` `??` 运算符用于检查左侧值是否为 `nil`,如果不是则返回右侧的值: diff --git a/src/nasal_codegen.cpp b/src/nasal_codegen.cpp index e68b3db..523be41 100644 --- a/src/nasal_codegen.cpp +++ b/src/nasal_codegen.cpp @@ -17,13 +17,16 @@ void codegen::load_native_function_table(nasal_builtin_table* table) { err.err("code", "\"" + std::string(table[i].name) + "\" conflicts."); continue; } + + // replace unsafe native functions with redirect function in limit mode if (flag_limited_mode && unsafe_system_api.count(table[i].name)) { native_function.push_back({"__unsafe_redirect", builtin_unsafe}); } else { native_function.push_back(table[i]); } - auto index = native_function_mapper.size(); + // insert into mapper + auto index = native_function_mapper.size(); native_function_mapper[table[i].name] = index; } } diff --git a/src/nasal_codegen.h b/src/nasal_codegen.h index 8b4d123..961a105 100644 --- a/src/nasal_codegen.h +++ b/src/nasal_codegen.h @@ -57,8 +57,7 @@ private: // dylib "__dlopen", "__dlclose", "__dlcallv", "__dlcall", // unix - "__pipe", "__fork", "__waitpid", "__chdir", - "__environ", "__getcwd", "__getenv", + "__chdir", "__environ", "__getcwd", "__getenv", // subprocess "__subprocess_create", "__subprocess_terminate" diff --git a/src/nasal_vm.h b/src/nasal_vm.h index 27b9678..89b9cf3 100644 --- a/src/nasal_vm.h +++ b/src/nasal_vm.h @@ -536,6 +536,22 @@ inline void vm::o_subeq() {op_calc_eq(-);} inline void vm::o_muleq() {op_calc_eq(*);} inline void vm::o_diveq() {op_calc_eq(/);} inline void vm::o_lnkeq() { + // concat two vectors into one + if (ctx.top[-1].is_vec() && ctx.memr[0].is_vec()) { + ngc.temp = ngc.alloc(vm_type::vm_vec); + for(auto i : ctx.memr[0].vec().elems) { + ngc.temp.vec().elems.push_back(i); + } + for(auto i : ctx.top[-1].vec().elems) { + ngc.temp.vec().elems.push_back(i); + } + ctx.top[-1] = ctx.memr[0] = ngc.temp; + ngc.temp = nil; + ctx.memr = nullptr; + ctx.top -= imm[ctx.pc]+1; + return; + } + ctx.top[-1] = ctx.memr[0] = ngc.newstr( ctx.memr[0].to_str()+ctx.top[-1].to_str() ); diff --git a/src/natives/unix_lib.cpp b/src/natives/unix_lib.cpp index f394734..a23ddd5 100644 --- a/src/natives/unix_lib.cpp +++ b/src/natives/unix_lib.cpp @@ -12,48 +12,6 @@ void dir_entry_destructor(void* ptr) { #endif } -var builtin_pipe(context* ctx, gc* ngc) { -#ifndef _WIN32 - i32 fd[2]; - var res = ngc->alloc(vm_type::vm_vec); - if (pipe(fd)==-1) { - return nas_err("unix::pipe", "failed to create pipe"); - } - res.vec().elems.push_back(var::num(static_cast(fd[0]))); - res.vec().elems.push_back(var::num(static_cast(fd[1]))); - return res; -#endif - return nas_err("unix::pipe", "not supported on windows"); -} - -var builtin_fork(context* ctx, gc* ngc) { -#ifndef _WIN32 - f64 res = fork(); - if (res<0) { - return nas_err("unix::fork", "failed to fork a process"); - } - return var::num(static_cast(res)); -#endif - return nas_err("unix::fork", "not supported on windows"); -} - -var builtin_waitpid(context* ctx, gc* ngc) { - auto pid = ctx->localr[1]; - auto nohang = ctx->localr[2]; - if (!pid.is_num() || !nohang.is_num()) { - return nas_err("unix::waitpid", "pid and nohang must be number"); - } -#ifndef _WIN32 - i32 ret_pid, status; - ret_pid = waitpid(pid.num(), &status, nohang.num()==0? 0:WNOHANG); - var vec = ngc->alloc(vm_type::vm_vec); - vec.vec().elems.push_back(var::num(static_cast(ret_pid))); - vec.vec().elems.push_back(var::num(static_cast(status))); - return vec; -#endif - return nas_err("unix::waitpid", "not supported on windows"); -} - var builtin_opendir(context* ctx, gc* ngc) { auto path = ctx->localr[1]; if (!path.is_str()) { @@ -139,9 +97,6 @@ var builtin_getenv(context* ctx, gc* ngc) { } nasal_builtin_table unix_lib_native[] = { - {"__pipe", builtin_pipe}, - {"__fork", builtin_fork}, - {"__waitpid", builtin_waitpid}, {"__opendir", builtin_opendir}, {"__readdir", builtin_readdir}, {"__closedir", builtin_closedir}, diff --git a/src/natives/unix_lib.h b/src/natives/unix_lib.h index 93a70aa..6ea292b 100644 --- a/src/natives/unix_lib.h +++ b/src/natives/unix_lib.h @@ -24,9 +24,6 @@ namespace nasal { void dir_entry_destructor(void*); -var builtin_pipe(context*, gc*); -var builtin_fork(context*, gc*); -var builtin_waitpid(context*, gc*); var builtin_opendir(context*, gc*); var builtin_readdir(context*, gc*); var builtin_closedir(context*, gc*); diff --git a/std/unix.nas b/std/unix.nas index a966c09..714f46f 100644 --- a/std/unix.nas +++ b/std/unix.nas @@ -7,26 +7,6 @@ use std.io; var _S_IFDIR = 0x4000; var _S_IFREG = 0x8000; -var pipe = func() { - return __pipe; -} - -var fork = func() { - return __fork; -} - -var dup2 = func(fd0, fd1) { - die("not supported yet"); -} - -var exec = func(filename, argv, envp) { - die("not supported yet"); -} - -var waitpid = func(pid, nohang = 0) { - return __waitpid; -} - var isdir = func(path) { return !!bits.u32_and(io.stat(path)[2], _S_IFDIR); }