Skip to content

Commit

Permalink
Merge pull request #32 from ValKmjolnir/develop
Browse files Browse the repository at this point in the history
📝 update release notes and tutorials
  • Loading branch information
ValKmjolnir authored Oct 7, 2023
2 parents d108e40 + 0b179bf commit c8c233d
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 6 deletions.
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,30 @@ var (a,b,c)=[0,1,2]; # define multiple variables from a vector
var (a,b,c)=(0,1,2); # define multiple variables from a tuple
```

Nasal has many special global symbols:

```javascript
globals; # hashmap including all global symbols and their values
arg; # in global scope, arg is the command line arguments
# in local scope, arg is the dynamic arguments of this function call
```

For example:

```javascript
var a = 1;
println(globals); # will print {a:1}
```

```javascript
# nasal a b c
println(arg); # will print ["a", "b", "c"]

func() {
println(arg);
}(1, 2, 3); # will print [1, 2, 3]
```

</details>

<details><summary> Multi-assignment </summary>
Expand Down Expand Up @@ -767,6 +791,62 @@ If get this, Congratulations!

</details>

<details><summary> Ghost Type(for lib developers) </summary>

It's quite easy to create a new ghost by yourself now.
Look at the example below:

```c++
const auto ghost_for_test = "ghost_for_test";

// declare destructor for ghost type
void ghost_for_test_destructor(void* ptr) {
std::cout << "ghost_for_test::destructor (0x";
std::cout << std::hex << reinterpret_cast<u64>(ptr) << std::dec << ") {\n";
delete static_cast<u32*>(ptr);
std::cout << " delete 0x" << std::hex;
std::cout << reinterpret_cast<u64>(ptr) << std::dec << ";\n";
std::cout << "}\n";
}

var create_new_ghost(var* args, usize size, gc* ngc) {
var res = ngc->alloc(vm_obj);
// create ghost type
res.obj().set(ghost_for_test, ghost_for_test_destructor, new u32);
return res;
}

var print_new_ghost(var* args, usize size, gc* ngc) {
var res = args[0];
// check ghost type by the type name
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;
}
```

We use this function to create a new ghost type:

`void nas_ghost::set(const std::string&, nasal::nas_ghost::destructor, void*);`

`const std::string&` is the name of the ghost type.

`nasal::nas_ghost::destructor` is the pointer of the destructor of the ghost type.

`void*` is the pointer of the ghost type instance.

And we use this function to check if value is the correct ghost type:

`bool var::objchk(const std::string&);`

The parameter is the name of the ghost type.

</details>

## __Difference Between Andy's and This Interpreter__

![error](./doc/gif/error.gif)
Expand Down Expand Up @@ -1018,3 +1098,19 @@ We added experimental repl interpreter in v11.0.
Use this command to use the repl interpreter:

> nasal -r
Then enjoy!

```bash
[nasal-repl] Initializating enviroment...
[nasal-repl] Initialization complete.

Nasal REPL interpreter version 11.0 (Oct 7 2023 17:28:31)
.h, .help | show help
.e, .exit | quit the REPL
.q, .quit | quit the REPL
.c, .clear | clear the screen
.s, .source | show source code

>>>
```
95 changes: 95 additions & 0 deletions doc/README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,30 @@ var (a,b,c)=[0,1,2]; # 从数组中初始化多个变量
var (a,b,c)=(0,1,2); # 从元组中初始化多个变量
```

Nasal 有很多特别的全局变量:

```javascript
globals; # 包含所有全局声明变量名和对应数据的哈希表
arg; # 在全局作用域,arg 是包含命令行参数的数组
# 在局部作用域,arg 是函数调用时的动态参数数组
```

具体实例:

```javascript
var a = 1;
println(globals); # 输出 {a:1}
```

```javascript
# nasal a b c
println(arg); # 输出 ["a", "b", "c"]

func() {
println(arg);
}(1, 2, 3); # 输出 [1, 2, 3]
```

</details>

<details><summary>多变量赋值</summary>
Expand Down Expand Up @@ -741,6 +765,61 @@ dylib.dlclose(dlhandle.lib);

</details>

<details><summary> 自定义类型(开发者教程) </summary>

创建一个自定义类型现在不是很困难。下面是使用示例:

```c++
const auto ghost_for_test = "ghost_for_test";

// 声明自定义类型的析构函数
void ghost_for_test_destructor(void* ptr) {
std::cout << "ghost_for_test::destructor (0x";
std::cout << std::hex << reinterpret_cast<u64>(ptr) << std::dec << ") {\n";
delete static_cast<u32*>(ptr);
std::cout << " delete 0x" << std::hex;
std::cout << reinterpret_cast<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, ghost_for_test_destructor, new u32);
return res;
}

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

我们使用下面这个函数来创建一个自定义类型:

`void nas_ghost::set(const std::string&, nasal::nas_ghost::destructor, void*);`

`const std::string&` 是自定义类型的类型名。

`nasal::nas_ghost::destructor` 是自定义类型的析构函数指针。

`void*` 是指向自定义类型实例的指针。

我们使用下面的这个函数检测是否是正确的自定义类型:

`bool var::objchk(const std::string&);`

参数是自定义类型的类型名。

</details>

## __与andy解释器的不同之处__

![error](../doc/gif/error.gif)
Expand Down Expand Up @@ -982,3 +1061,19 @@ vm stack (0x7fffd0259138 <sp+65>, limit 10, total 7)
v11.0 版本新增了交互式解释器 (REPL),使用如下命令开启:

> nasal -r
接下来就可以随便玩了~

```bash
[nasal-repl] Initializating enviroment...
[nasal-repl] Initialization complete.

Nasal REPL interpreter version 11.0 (Oct 7 2023 17:28:31)
.h, .help | show help
.e, .exit | quit the REPL
.q, .quit | quit the REPL
.c, .clear | clear the screen
.s, .source | show source code

>>>
```
35 changes: 32 additions & 3 deletions doc/dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [v2.0](#version-20-ast-last-update-2020831)
* [v3.0](#version-30-ast-last-update-20201023)
* [v5.0](#version-50-ast-last-update-202137)
* [v11.0](#version-110-ast-latest)
* [__Bytecode VM__](#bytecode-virtual-machine)
* [v4.0](#version-40-vm-last-update-20201217)
* [v5.0](#version-50-vm-last-update-202137)
Expand All @@ -17,8 +18,10 @@
* [v7.0](#version-70-vm-last-update-2021108)
* [v8.0](#version-80-vm-last-update-2022212)
* [v9.0](#version-90-vm-last-update-2022518)
* [v10.0](#version-100-vm-latest)
* [v10.0](#version-100-vm-last-update-2022816)
* [__Release Notes__](#release-notes)
* [v8.0](#version-80-release)
* [v11.0](#version-110-release)

## __Parser__

Expand Down Expand Up @@ -97,6 +100,10 @@ AST interpreter leaves me too much things to do.
If i continue saving this interpreter,
it will be harder for me to make the bytecode vm become more efficient.

### version 11.0 ast (latest)

Change ast framework. Now we use visitor pattern.

## __Bytecode Virtual Machine__

![op](../doc/gif/opcode.gif)
Expand Down Expand Up @@ -513,7 +520,7 @@ func <0x2a3>:
0x000002aa: 0c 00 00 00 6a happ 0x6a ("dlsym")
```

### version 10.0 vm (latest)
### version 10.0 vm (last update 2022/8/16)

2022/5/19 update:

Expand Down Expand Up @@ -664,7 +671,29 @@ If do not change this line, only the debugger runs abnormally. this bug is fixed
Another bug is that in `nasal_err.h:class nasal_err`, we should add a constructor for this class:

```C++
nasal_err():error(0){}
nasal_err(): error(0) {}
```
This bug is fixed in `v9.0`. So we suggest that do not use `v8.0`.
### __version 11.0 release__
1. Use C++ `std=c++17`.
2. Change framework of ast, using visitor pattern.
3. New ast structure dump info format.
4. Change the way of module export, split library into different modules. Symbols begin with `_` will not be exported.
5. Change `stl` to `std`.
6. Add REPL interpreter.
7. Improve structure of virtual machine, split global symbol stack(stores global symbols' values) and value stack(using in process).
8. Delete operand `op_intg`, add operand `op_repl`.
9. Add `CMakeLists.txt` for cmake user(including `Visual Studio`).
10. New ghost type register process.
35 changes: 32 additions & 3 deletions doc/dev_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [v2.0](#version-20-ast-last-update-2020831)
* [v3.0](#version-30-ast-last-update-20201023)
* [v5.0](#version-50-ast-last-update-202137)
* [v11.0](#version-110-ast-latest)
* [__字节码虚拟机__](#字节码虚拟机)
* [v4.0](#version-40-vm-last-update-20201217)
* [v5.0](#version-50-vm-last-update-202137)
Expand All @@ -17,8 +18,10 @@
* [v7.0](#version-70-vm-last-update-2021108)
* [v8.0](#version-80-vm-last-update-2022212)
* [v9.0](#version-90-vm-last-update-2022518)
* [v10.0](#version-100-vm-latest)
* [v10.0](#version-100-vm-last-update-2022816)
* [__发行日志__](#发行日志)
* [v8.0](#version-80-release)
* [v11.0](#version-110-release)

## __语法分析__

Expand Down Expand Up @@ -89,6 +92,10 @@ __该项目于2019/7/25正式开始__。

我改变想法了,树解释器给维护带来了太大的麻烦。如果想继续保留这个解释器,那么为了兼容性,字节码虚拟机的优化工作会更难推进。

### version 11.0 ast (latest)

改变了语法树的设计模式,采用访问者模式。

## __字节码虚拟机__

![op](../doc/gif/opcode.gif)
Expand Down Expand Up @@ -458,7 +465,7 @@ func <0x2a3>:
0x000002aa: 0c 00 00 00 6a happ 0x6a ("dlsym")
```

### version 10.0 vm (latest)
### version 10.0 vm (last update 2022/8/16)

2022/5/19 update:

Expand Down Expand Up @@ -597,7 +604,29 @@ in __`nasal_dbg.h:215`__: `auto canary=gc.stack+STACK_MAX_DEPTH-1;`
另外一个bug在 `nasal_err.h:class nasal_err`这边,要给这个类添加一个构造函数来进行初始化,否则会出问题:

```C++
nasal_err():error(0){}
nasal_err(): error(0) {}
```
同样这个也在`v9.0`中修复了。所以我们建议不要使用`v8.0`
### __version 11.0 release__
1. 使用C++标准 `std=c++17`
2. 改变语法树设计模式,采用访问者模式。
3. 全新的语法树结构输出格式。
4. 改变了导出模块的方式,把主要的库分成了多个模块。以`_`开头的变量不会被导出。
5. 文件夹`stl`更名为`std`
6. 添加交互式解释器 (REPL)。
7. 优化虚拟机结构, 将全局数据栈 (存储全局变量的数据) 和操作数据栈 (用于运算) 分离。
8. 删除`op_intg`指令,添加`op_repl`指令。
9. 添加`CMakeLists.txt` (可在`Visual Studio`中使用)。
10. 全新的自定义类型注册流程。

0 comments on commit c8c233d

Please sign in to comment.