add tutorial of how to add built-in function

This commit is contained in:
Valk Richard Li 2021-02-23 23:33:01 +08:00
parent b1a5a5f6c0
commit 1c40cca673
1 changed files with 101 additions and 11 deletions

112
README.md
View File

@ -127,37 +127,46 @@ Function is also a value type in nasal.
var spc=nil; var spc=nil;
var a=1; var a=1;
a=0x7fffffff; var a=2.71828;
a=0o170001; var a=2.147e16;
var a=1e-10;
var a=0x7fffffff;
var a=0xAA55;
var a=0o170001;
var b='str'; var b='str';
b="another string"; var b="another string";
b=`c`; var b=`c`;
var c=[]; var c=[];
c=[0,nil,{},[],func(){return 0;}]; var c=[0,nil,{},[],func(){return 0;}];
append(c,0,1,2); append(c,0,1,2);
var d={ var d={
member1:nil, member1:nil,
member2:'str', member2:'str',
'member3':'member\'s name can also be a string constant', 'member3':'member\'s name can also be a string constant',
"member4":"also this" "member4":"also this",
function:func()
{
var a=me.member2~me.member3;
return a;
}
}; };
var e=func(x,y,z) var f=func(x,y,z)
{ {
return nil; return nil;
} }
e=func var f=func
{ {
return 1024; return 1024;
} }
e=func(x,y,z,default_parameter1=1,default_parameter2=2) var f=func(x,y,z,default_parameter1=1,default_parameter2=2)
{ {
return x+y+z+default_parameter1+default_parameter2; return x+y+z+default_parameter1+default_parameter2;
} }
e=func(x,y,z,dynamic_parameter...) var f=func(x,y,z,dynamic_parameter...)
{ {
var sum=0; var sum=0;
foreach(var i;dynamic_parameter) foreach(var i;dynamic_parameter)
@ -174,6 +183,7 @@ e=func(x,y,z,dynamic_parameter...)
1*2; 1*2;
1/2; 1/2;
'str1'~'str2'; 'str1'~'str2';
(1+2)*(3+4)
1+1 and 0; 1+1 and 0;
1+2*3 or 0; 1+2*3 or 0;
@ -251,8 +261,11 @@ foreach(var i;elem)
## subvec ## subvec
Use index to search one element in the string will get the ascii number of this character.If you want to get the character,use built-in function chr().
```javascript ```javascript
a[-1,1,0:2,0:,:3,:,nil:8,3:nil,nil:nil]; a[-1,1,0:2,0:,:3,:,nil:8,3:nil,nil:nil];
"hello world"[0];
``` ```
## special function call ## special function call
@ -263,10 +276,87 @@ This is of great use but is not very efficient.
a(x:0,y:1,z:2); a(x:0,y:1,z:2);
``` ```
## closure
```javascript
var f=func()
{
var a=1;
return func(){return a;};
}
print(f()());
```
## built-in functions ## built-in functions
Must import lib.nas or has these functions' definitions inside your code. Must import lib.nas or has these functions' definitions inside your code.
Also you could add builtin functions of your own(written in C/C++) to help you calculate things more quickly.(Advanced usage) Also you could add builtin functions of your own(written in C/C++) to help you calculate things more quickly.(Advanced usage)
Check built-in functions in lib.nas! Check built-in functions in lib.nas!
If you want to add your own built-in functions,define the function in nasal_builtin.h.
definition:
```C++
nasal_val* builtin_chr(nasal_val*,nasal_gc&);
```
Then complete this function using C++:
```C++
nasal_val* builtin_print(nasal_val* local_scope_addr,nasal_gc& gc)
{
// get arguments by using in_builtin_find
nasal_val* vector_value_addr=in_builtin_find("elements");
// main process
// also check type here,if get a type error,use builtin_error_occurred and return nullptr
nasal_vec& ref_vec=vector_value_addr->get_vector();
int size=ref_vec.size();
for(int i=0;i<size;++i)
{
nasal_val* tmp=ref_vec[i];
switch(tmp->get_type())
{
case vm_nil: std::cout<<"nil"; break;
case vm_num: std::cout<<tmp->get_number(); break;
case vm_str: std::cout<<tmp->get_string(); break;
case vm_vec: tmp->get_vector().print(); break;
case vm_hash: tmp->get_hash().print(); break;
case vm_func: std::cout<<"func(...){...}"; break;
}
}
// if a nasal value is not in use,use gc::del_reference to delete it
// if get a new reference of a nasal value,use gc::add_reference
// generate return value,use gc::gc_alloc(type) to make a new value
return gc.gc_alloc(vm_nil);
}
```
After that, write the built-in function's name(in nasal) and the function's pointer in this table:
```C++
struct FUNC_TABLE
{
std::string func_name;
nasal_val* (*func_pointer)(nasal_val* x,nasal_gc& gc);
} builtin_func_table[]=
{
{"nasal_call_builtin_std_cout",builtin_print},
{"",NULL}
};
```
At last,warp the 'nasal_call_builtin_std_cout' in a nasal file:
```javascript
var print=func(elements...)
{
nasal_call_builtin_std_cout(elements);
return nil;
};
```
In version 5.0,if you don't warp built-in function in a normal nasal function,this built-in function may cause a fault when searching arguments,which will cause SIGSEGV segmentation error(maybe).
Use import("") to get the nasal file including your biult-in functions,then you could use it.