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_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() );