🐛 fix `lnkeq` on 2 vecs

This commit is contained in:
ValKmjolnir 2024-06-15 00:33:16 +08:00
parent 7cc9a9f5c9
commit 5da80d1b22
4 changed files with 30 additions and 3 deletions

View File

@ -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,

View File

@ -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`,如果不是则返回右侧的值:

View File

@ -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;
}
}

View File

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