Skip to content

Commit

Permalink
Merge pull request #50 from ValKmjolnir/develop
Browse files Browse the repository at this point in the history
🐛 fix operand `lnkeq` when splicing vectors
  • Loading branch information
ValKmjolnir committed Jun 14, 2024
2 parents 7c175a2 + 5da80d1 commit 78dd535
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 73 deletions.
6 changes: 5 additions & 1 deletion doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion doc/tutorial_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -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++中 `&&` `||`运算符一致。
Expand Down Expand Up @@ -157,6 +158,9 @@ a ~= "string";
a ^= 0xff;
a &= 0xca;
a |= 0xba;

a = [0];
a ~= [1]; # should be [0, 1]
```

`??` 运算符用于检查左侧值是否为 `nil`,如果不是则返回右侧的值:
Expand Down
5 changes: 4 additions & 1 deletion src/nasal_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/nasal_codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ class codegen {
// dylib
"__dlopen", "__dlclose", "__dlcallv", "__dlcall",
// unix
"__pipe", "__fork", "__waitpid", "__chdir",
"__environ", "__getcwd", "__getenv",
"__chdir", "__environ", "__getcwd", "__getenv",
// subprocess
"__subprocess_create",
"__subprocess_terminate"
Expand Down
16 changes: 16 additions & 0 deletions src/nasal_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()
);
Expand Down
45 changes: 0 additions & 45 deletions src/natives/unix_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<f64>(fd[0])));
res.vec().elems.push_back(var::num(static_cast<f64>(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<f64>(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<f64>(ret_pid)));
vec.vec().elems.push_back(var::num(static_cast<f64>(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()) {
Expand Down Expand Up @@ -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},
Expand Down
3 changes: 0 additions & 3 deletions src/natives/unix_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand Down
20 changes: 0 additions & 20 deletions std/unix.nas
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 78dd535

Please sign in to comment.