diff --git a/README.md b/README.md
index 2a00439b..e12c4b90 100644
--- a/README.md
+++ b/README.md
@@ -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]
+```
+
Multi-assignment
@@ -767,6 +791,62 @@ If get this, Congratulations!
+ Ghost Type(for lib developers)
+
+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(ptr) << std::dec << ") {\n";
+ delete static_cast(ptr);
+ std::cout << " delete 0x" << std::hex;
+ std::cout << reinterpret_cast(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.
+
+
+
## __Difference Between Andy's and This Interpreter__
![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:
> 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
+
+>>>
+```
diff --git a/doc/README_zh.md b/doc/README_zh.md
index a803ce1c..8e5bf11d 100644
--- a/doc/README_zh.md
+++ b/doc/README_zh.md
@@ -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]
+```
+
多变量赋值
@@ -741,6 +765,61 @@ dylib.dlclose(dlhandle.lib);
+ 自定义类型(开发者教程)
+
+创建一个自定义类型现在不是很困难。下面是使用示例:
+
+```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(ptr) << std::dec << ") {\n";
+ delete static_cast(ptr);
+ std::cout << " delete 0x" << std::hex;
+ std::cout << reinterpret_cast(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&);`
+
+参数是自定义类型的类型名。
+
+
+
## __与andy解释器的不同之处__
![error](../doc/gif/error.gif)
@@ -982,3 +1061,19 @@ vm stack (0x7fffd0259138 , 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
+
+>>>
+```
diff --git a/doc/dev.md b/doc/dev.md
index dd03a9ff..9d61ff64 100644
--- a/doc/dev.md
+++ b/doc/dev.md
@@ -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)
@@ -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__
@@ -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)
@@ -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:
@@ -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.
diff --git a/doc/dev_zh.md b/doc/dev_zh.md
index 83e5dda2..4a8fc240 100644
--- a/doc/dev_zh.md
+++ b/doc/dev_zh.md
@@ -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)
@@ -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)
## __语法分析__
@@ -89,6 +92,10 @@ __该项目于2019/7/25正式开始__。
我改变想法了,树解释器给维护带来了太大的麻烦。如果想继续保留这个解释器,那么为了兼容性,字节码虚拟机的优化工作会更难推进。
+### version 11.0 ast (latest)
+
+改变了语法树的设计模式,采用访问者模式。
+
## __字节码虚拟机__
![op](../doc/gif/opcode.gif)
@@ -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:
@@ -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. 全新的自定义类型注册流程。