Merge pull request #32 from ValKmjolnir/develop

📝 update release notes and tutorials
This commit is contained in:
Li Haokun 2023-10-07 22:53:52 +08:00 committed by GitHub
commit c8c233d1d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 255 additions and 6 deletions

View File

@ -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 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>
<details><summary> Multi-assignment </summary> <details><summary> Multi-assignment </summary>
@ -767,6 +791,62 @@ If get this, Congratulations!
</details> </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__ ## __Difference Between Andy's and This Interpreter__
![error](./doc/gif/error.gif) ![error](./doc/gif/error.gif)
@ -1018,3 +1098,19 @@ We added experimental repl interpreter in v11.0.
Use this command to use the repl interpreter: Use this command to use the repl interpreter:
> nasal -r > 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
>>>
```

View File

@ -247,6 +247,30 @@ var (a,b,c)=[0,1,2]; # 从数组中初始化多个变量
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>
<details><summary>多变量赋值</summary> <details><summary>多变量赋值</summary>
@ -741,6 +765,61 @@ dylib.dlclose(dlhandle.lib);
</details> </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解释器的不同之处__ ## __与andy解释器的不同之处__
![error](../doc/gif/error.gif) ![error](../doc/gif/error.gif)
@ -982,3 +1061,19 @@ vm stack (0x7fffd0259138 <sp+65>, limit 10, total 7)
v11.0 版本新增了交互式解释器 (REPL),使用如下命令开启: v11.0 版本新增了交互式解释器 (REPL),使用如下命令开启:
> nasal -r > 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
>>>
```

View File

@ -9,6 +9,7 @@
* [v2.0](#version-20-ast-last-update-2020831) * [v2.0](#version-20-ast-last-update-2020831)
* [v3.0](#version-30-ast-last-update-20201023) * [v3.0](#version-30-ast-last-update-20201023)
* [v5.0](#version-50-ast-last-update-202137) * [v5.0](#version-50-ast-last-update-202137)
* [v11.0](#version-110-ast-latest)
* [__Bytecode VM__](#bytecode-virtual-machine) * [__Bytecode VM__](#bytecode-virtual-machine)
* [v4.0](#version-40-vm-last-update-20201217) * [v4.0](#version-40-vm-last-update-20201217)
* [v5.0](#version-50-vm-last-update-202137) * [v5.0](#version-50-vm-last-update-202137)
@ -17,8 +18,10 @@
* [v7.0](#version-70-vm-last-update-2021108) * [v7.0](#version-70-vm-last-update-2021108)
* [v8.0](#version-80-vm-last-update-2022212) * [v8.0](#version-80-vm-last-update-2022212)
* [v9.0](#version-90-vm-last-update-2022518) * [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) * [__Release Notes__](#release-notes)
* [v8.0](#version-80-release)
* [v11.0](#version-110-release)
## __Parser__ ## __Parser__
@ -97,6 +100,10 @@ AST interpreter leaves me too much things to do.
If i continue saving this interpreter, If i continue saving this interpreter,
it will be harder for me to make the bytecode vm become more efficient. 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__ ## __Bytecode Virtual Machine__
![op](../doc/gif/opcode.gif) ![op](../doc/gif/opcode.gif)
@ -513,7 +520,7 @@ func <0x2a3>:
0x000002aa: 0c 00 00 00 6a happ 0x6a ("dlsym") 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: 2022/5/19 update:
@ -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: Another bug is that in `nasal_err.h:class nasal_err`, we should add a constructor for this class:
```C++ ```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`. 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.

View File

@ -9,6 +9,7 @@
* [v2.0](#version-20-ast-last-update-2020831) * [v2.0](#version-20-ast-last-update-2020831)
* [v3.0](#version-30-ast-last-update-20201023) * [v3.0](#version-30-ast-last-update-20201023)
* [v5.0](#version-50-ast-last-update-202137) * [v5.0](#version-50-ast-last-update-202137)
* [v11.0](#version-110-ast-latest)
* [__字节码虚拟机__](#字节码虚拟机) * [__字节码虚拟机__](#字节码虚拟机)
* [v4.0](#version-40-vm-last-update-20201217) * [v4.0](#version-40-vm-last-update-20201217)
* [v5.0](#version-50-vm-last-update-202137) * [v5.0](#version-50-vm-last-update-202137)
@ -17,8 +18,10 @@
* [v7.0](#version-70-vm-last-update-2021108) * [v7.0](#version-70-vm-last-update-2021108)
* [v8.0](#version-80-vm-last-update-2022212) * [v8.0](#version-80-vm-last-update-2022212)
* [v9.0](#version-90-vm-last-update-2022518) * [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)
## __语法分析__ ## __语法分析__
@ -89,6 +92,10 @@ __该项目于2019/7/25正式开始__。
我改变想法了,树解释器给维护带来了太大的麻烦。如果想继续保留这个解释器,那么为了兼容性,字节码虚拟机的优化工作会更难推进。 我改变想法了,树解释器给维护带来了太大的麻烦。如果想继续保留这个解释器,那么为了兼容性,字节码虚拟机的优化工作会更难推进。
### version 11.0 ast (latest)
改变了语法树的设计模式,采用访问者模式。
## __字节码虚拟机__ ## __字节码虚拟机__
![op](../doc/gif/opcode.gif) ![op](../doc/gif/opcode.gif)
@ -458,7 +465,7 @@ func <0x2a3>:
0x000002aa: 0c 00 00 00 6a happ 0x6a ("dlsym") 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: 2022/5/19 update:
@ -597,7 +604,29 @@ in __`nasal_dbg.h:215`__: `auto canary=gc.stack+STACK_MAX_DEPTH-1;`
另外一个bug在 `nasal_err.h:class nasal_err`这边,要给这个类添加一个构造函数来进行初始化,否则会出问题: 另外一个bug在 `nasal_err.h:class nasal_err`这边,要给这个类添加一个构造函数来进行初始化,否则会出问题:
```C++ ```C++
nasal_err():error(0){} nasal_err(): error(0) {}
``` ```
同样这个也在`v9.0`中修复了。所以我们建议不要使用`v8.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. 全新的自定义类型注册流程。