mirror of
https://github.com/ValKmjolnir/Nasal-Interpreter.git
synced 2026-05-02 19:00:47 +08:00
change output format of information of bytecodes
This commit is contained in:
129
README.md
129
README.md
@@ -46,16 +46,18 @@ this interpreter to a useful tool in your own projects(such as a script in your
|
||||
## How to Compile
|
||||
|
||||
Better choose the latest update of the interpreter.
|
||||
Download the source code and build it!
|
||||
It's quite easy to build this interpreter.
|
||||
|
||||
MUST USE -O2/-O3 if want to optimize the interpreter!
|
||||
|
||||
Also remember to use g++ or clang++.
|
||||
|
||||
> [cpp compiler] -std=c++11 -O2 main.cpp -o nasal.exe
|
||||
> [cpp compiler] -std=c++11 -O3 main.cpp -o nasal.exe -fno-exceptions
|
||||
|
||||
Or use this in linux/macOS/Unix
|
||||
|
||||
> [cpp compiler] -std=c++11 -O2 main.cpp -o nasal
|
||||
> [cpp compiler] -std=c++11 -O3 main.cpp -o nasal -fno-exceptions
|
||||
|
||||
## How to Use?
|
||||
|
||||
@@ -150,11 +152,13 @@ I decide to save the ast interpreter after releasing v4.0. Because it took me a
|
||||
|
||||
### Version 5.0(last update 2021/3/7)
|
||||
|
||||
I change my mind.AST interpreter leaves me too much things to do.
|
||||
I change my mind.
|
||||
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.
|
||||
If i continue saving this interpreter,
|
||||
it will be harder for me to make the bytecode vm become more efficient.
|
||||
|
||||
## Byte Code VM
|
||||
## Byte Code Virtual Machine
|
||||
|
||||
### Version 4.0 (last update 2020/12/17)
|
||||
|
||||
@@ -170,7 +174,7 @@ There's an example of byte code below:
|
||||
for(var i=0;i<4000000;i+=1);
|
||||
```
|
||||
|
||||
```asm
|
||||
```MIPS
|
||||
.number 0
|
||||
.number 4e+006
|
||||
.number 1
|
||||
@@ -221,7 +225,7 @@ So the bytecode generator changed a lot.
|
||||
for(var i=0;i<4000000;i+=1);
|
||||
```
|
||||
|
||||
```asm
|
||||
```MIPS
|
||||
.number 4e+006
|
||||
0x00000000: intg 0x00000001
|
||||
0x00000001: pzero 0x00000000
|
||||
@@ -269,7 +273,7 @@ var f=func(x,y){return x+y;}
|
||||
f(1024,2048);
|
||||
```
|
||||
|
||||
```asm
|
||||
```MIPS
|
||||
.number 1024
|
||||
.number 2048
|
||||
.symbol x
|
||||
@@ -323,7 +327,7 @@ codegen will generate byte code by nasal_codegen::call_gen() instead of nasal_co
|
||||
and the last child of the ast will be generated by nasal_codegen::mcall_gen().
|
||||
So the bytecode is totally different now:
|
||||
|
||||
```asm
|
||||
```MIPS
|
||||
.number 10
|
||||
.number 2
|
||||
.symbol _
|
||||
@@ -394,7 +398,7 @@ is deleted from nasal_vm,
|
||||
and now nasal_vm use nasal_val** mem_addr to store the memory address.
|
||||
This will not cause fatal errors because the memory address is used __immediately__ after getting it.
|
||||
|
||||
### version 7.0 (2021/10/8)
|
||||
### version 7.0 (last update 2021/10/8)
|
||||
|
||||
2021/6/26 update:
|
||||
|
||||
@@ -421,7 +425,7 @@ op_addc,op_subc,op_mulc,op_divc,op_lnkc,op_addeqc,op_subeqc,op_muleqc,op_diveqc,
|
||||
|
||||
Now the bytecode of test/bigloop.nas seems like this:
|
||||
|
||||
```asm
|
||||
```MIPS
|
||||
.number 4e+006
|
||||
.number 1
|
||||
0x00000000: intg 0x00000001
|
||||
@@ -450,7 +454,7 @@ var (a,b)=(1,2);
|
||||
a=b=0;
|
||||
```
|
||||
|
||||
```asm
|
||||
```MIPS
|
||||
.number 2
|
||||
0x00000000: intg 0x00000002
|
||||
0x00000001: pone 0x00000000
|
||||
@@ -475,9 +479,52 @@ New value type is added: vm_obj.
|
||||
This type is reserved for user to define their own value types.
|
||||
Related API will be added in the future.
|
||||
|
||||
## Test data
|
||||
Fully functional closure:
|
||||
Add new operands that get and set upvalues.
|
||||
Delete an old operand 'op_offset'.
|
||||
|
||||
### version 6.5(i5-8250U windows10 2021/6/19)
|
||||
2021/10/13 update:
|
||||
|
||||
The format of output information of bytecodes changes to this:
|
||||
|
||||
```MIPS
|
||||
0x0000017c: jmp 0x181
|
||||
0x0000017d: calll 0x1
|
||||
0x0000017e: calll 0x1
|
||||
0x0000017f: callfv 0x1
|
||||
0x00000180: ret
|
||||
0x00000181: newf 0x185
|
||||
0x00000182: intl 0x2
|
||||
0x00000183: para 0x29 ("f")
|
||||
0x00000184: jmp 0x19d
|
||||
0x00000185: newf 0x189
|
||||
0x00000186: intl 0x2
|
||||
0x00000187: para 0x1d ("x")
|
||||
0x00000188: jmp 0x19c
|
||||
0x00000189: calll 0x1
|
||||
0x0000018a: lessc 0x12 (2.000000)
|
||||
0x0000018b: jf 0x18e
|
||||
0x0000018c: calll 0x1
|
||||
0x0000018d: ret
|
||||
0x0000018e: upval 0x0[0x1]
|
||||
0x0000018f: upval 0x0[0x1]
|
||||
0x00000190: callfv 0x1
|
||||
0x00000191: calll 0x1
|
||||
0x00000192: subc 0x13 (1.000000)
|
||||
0x00000193: callfv 0x1
|
||||
0x00000194: upval 0x0[0x1]
|
||||
0x00000195: upval 0x0[0x1]
|
||||
0x00000196: callfv 0x1
|
||||
0x00000197: calll 0x1
|
||||
0x00000198: subc 0x12 (2.000000)
|
||||
0x00000199: callfv 0x1
|
||||
0x0000019a: add
|
||||
0x0000019b: ret
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
|
||||
### version 6.5 (i5-8250U windows10 2021/6/19)
|
||||
|
||||
running time and gc time:
|
||||
|
||||
@@ -524,7 +571,7 @@ operands calling total times:
|
||||
|quick_sort.nas|16226|5561|4144|3524|2833|
|
||||
|bfs.nas|24707|16297|14606|14269|8672|
|
||||
|
||||
### version 7.0(i5-8250U ubuntu-WSL on windows10 2021/6/29)
|
||||
### version 7.0 (i5-8250U ubuntu-WSL on windows10 2021/6/29)
|
||||
|
||||
running time:
|
||||
|
||||
@@ -541,7 +588,7 @@ running time:
|
||||
|quick_sort.nas|0s|great improvement|
|
||||
|bfs.nas|0.0156s|great improvement|
|
||||
|
||||
## How to Use Nasal to Program
|
||||
## Use Nasal to Program
|
||||
|
||||
### basic value type
|
||||
|
||||
@@ -587,27 +634,18 @@ var d={
|
||||
member2:'str',
|
||||
'member3':'member\'s name can also be a string constant',
|
||||
"member4":"also this",
|
||||
function:func()
|
||||
{
|
||||
function:func(){
|
||||
var a=me.member2~me.member3;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
var f=func(x,y,z)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
var f=func
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
var f=func(x,y,z,default_para1=1,default_para2=2)
|
||||
{
|
||||
var f=func(x,y,z){return nil;}
|
||||
var f=func{return 1024;}
|
||||
var f=func(x,y,z,default_para1=1,default_para2=2){
|
||||
return x+y+z+default_para1+default_para2;
|
||||
}
|
||||
var f=func(x,y,z,dynamic_para...)
|
||||
{
|
||||
var f=func(x,y,z,dynamic_para...){
|
||||
var sum=0;
|
||||
foreach(var i;dynamic_para)
|
||||
sum+=i;
|
||||
@@ -713,20 +751,33 @@ func(x,y){return x+y}(0,1);
|
||||
func(x){return 1/(1+math.exp(-x));}(0.5);
|
||||
```
|
||||
|
||||
There's an interesting test file 'y-combinator.nas',
|
||||
try it for fun:
|
||||
```javascript
|
||||
var fib=func(f){
|
||||
return f(f);
|
||||
}(
|
||||
func(f){
|
||||
return func(x){
|
||||
if(x<2) return x;
|
||||
return f(f)(x-1)+f(f)(x-2);
|
||||
}
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### closure
|
||||
|
||||
Use closure to OOP.
|
||||
|
||||
```javascript
|
||||
var f=func()
|
||||
{
|
||||
var f=func(){
|
||||
var a=1;
|
||||
return func(){return a;};
|
||||
}
|
||||
print(f()());
|
||||
|
||||
var student=func(name,age)
|
||||
{
|
||||
var student=func(name,age){
|
||||
var val={
|
||||
name:name,
|
||||
age:age
|
||||
@@ -741,7 +792,7 @@ var student=func(name,age)
|
||||
}
|
||||
```
|
||||
|
||||
### built-in functions
|
||||
### native functions
|
||||
|
||||
Must import lib.nas or has these functions' definitions inside your code.
|
||||
|
||||
@@ -779,7 +830,7 @@ nasal_ref builtin_print(std::vector<nasal_ref>& local,nasal_gc& gc)
|
||||
case vm_vec: i.vec()->print(); break;
|
||||
case vm_hash: i.hash()->print(); break;
|
||||
case vm_func: std::cout<<"func(...){...}"; break;
|
||||
case vm_obj: std::cout<<"<obj>"; break;
|
||||
case vm_obj: std::cout<<"<object>"; break;
|
||||
}
|
||||
std::cout<<std::flush;
|
||||
// if a nasal value is not in use,use gc::del_reference to delete it
|
||||
@@ -806,8 +857,7 @@ struct FUNC_TABLE
|
||||
At last,warp the '__builtin_print' in a nasal file:
|
||||
|
||||
```javascript
|
||||
var print=func(elems...)
|
||||
{
|
||||
var print=func(elems...){
|
||||
return __builtin_print(elems);
|
||||
};
|
||||
```
|
||||
@@ -815,8 +865,7 @@ var print=func(elems...)
|
||||
In fact the arguments that '__builtin_print' uses is not necessary,So writting it like this is also right:
|
||||
|
||||
```javascript
|
||||
var print=func(elems...)
|
||||
{
|
||||
var print=func(elems...){
|
||||
return __builtin_print;
|
||||
};
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user