update docs & fix bug in nasal_builtin.h
This commit is contained in:
parent
9bcad59e45
commit
c4d52a88cd
37
README.md
37
README.md
|
@ -518,11 +518,11 @@ println(a.get());
|
||||||
|
|
||||||
### __native functions__
|
### __native functions__
|
||||||
|
|
||||||
You could add builtin functions of your own
|
This part shows how we add native functions in this nasal interpreter.
|
||||||
(written in C/C++) to help you calculate things more quickly.
|
If you are interested in this part, this may help you.
|
||||||
But you should add your own code into the source code of this interpreter and re-compile it.
|
And...
|
||||||
|
|
||||||
If you want to add your own functions __without__ changing the source code of the interpreter, see the __`module`__ after this part.
|
__CAUTION:__ If you want to add your own functions __without__ changing the source code of the interpreter, see the __`module`__ after this part.
|
||||||
|
|
||||||
If you really want to change source code, check built-in functions in lib.nas and see the example below.
|
If you really want to change source code, check built-in functions in lib.nas and see the example below.
|
||||||
|
|
||||||
|
@ -530,6 +530,8 @@ Definition:
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
nasal_ref builtin_print(nasal_ref*,nasal_gc&);
|
nasal_ref builtin_print(nasal_ref*,nasal_gc&);
|
||||||
|
// you could also use a macro to define one.
|
||||||
|
nas_native(builtin_print);
|
||||||
```
|
```
|
||||||
|
|
||||||
Then complete this function using C++:
|
Then complete this function using C++:
|
||||||
|
@ -538,12 +540,12 @@ Then complete this function using C++:
|
||||||
nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
// find value with index begin from 1
|
// find value with index begin from 1
|
||||||
// because local_scope[0] is reserved for value 'me'
|
// because local[0] is reserved for value 'me'
|
||||||
nasal_ref vec=local[1];
|
nasal_ref vec=local[1];
|
||||||
// main process
|
// main process
|
||||||
// also check number of arguments and type here
|
// also check number of arguments and type here
|
||||||
// if get an error,use builtin_err
|
// if get an error,use builtin_err
|
||||||
for(auto i:vec.vec().elems)
|
for(auto& i:vec.vec().elems)
|
||||||
switch(i.type)
|
switch(i.type)
|
||||||
{
|
{
|
||||||
case vm_none: std::cout<<"undefined"; break;
|
case vm_none: std::cout<<"undefined"; break;
|
||||||
|
@ -556,7 +558,8 @@ nasal_ref builtin_print(nasal_ref* local,nasal_gc& gc)
|
||||||
case vm_obj: std::cout<<"<object>"; break;
|
case vm_obj: std::cout<<"<object>"; break;
|
||||||
}
|
}
|
||||||
std::cout<<std::flush;
|
std::cout<<std::flush;
|
||||||
// generate return value,use gc::alloc(type) to make a new value
|
// generate return value,
|
||||||
|
// use gc::alloc(type) to make a new value
|
||||||
// or use reserved reference nil/one/zero
|
// or use reserved reference nil/one/zero
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -569,7 +572,7 @@ struct func
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
nasal_ref (*func)(nasal_ref*,nasal_gc&);
|
nasal_ref (*func)(nasal_ref*,nasal_gc&);
|
||||||
} builtin_func[]=
|
} builtin[]=
|
||||||
{
|
{
|
||||||
{"__builtin_print",builtin_print},
|
{"__builtin_print",builtin_print},
|
||||||
{nullptr, nullptr }
|
{nullptr, nullptr }
|
||||||
|
@ -584,7 +587,7 @@ var print=func(elems...){
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
In fact the arguments that `__builtin_print` uses is not necessary.
|
In fact the arguments that `__builtin_print` uses are not necessary.
|
||||||
So writting it like this is also right:
|
So writting it like this is also right:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
@ -610,7 +613,9 @@ this may cause mark-sweep in `gc::alloc`.
|
||||||
The value got before will be collected,but stil in use in this builtin function,
|
The value got before will be collected,but stil in use in this builtin function,
|
||||||
this is a fatal error.
|
this is a fatal error.
|
||||||
|
|
||||||
So use `builtin_alloc` in builtin functions like this:
|
So use `gc::builtin_alloc` in builtin functions to allocate a new object.
|
||||||
|
|
||||||
|
Or use `gc::alloc` like this to avoid sweeping objects incorrectly:
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
||||||
|
@ -620,7 +625,7 @@ nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("keys","\"hash\" must be hash");
|
return builtin_err("keys","\"hash\" must be hash");
|
||||||
// push vector into local scope to avoid being sweeped
|
// push vector into local scope to avoid being sweeped
|
||||||
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||||
builtin_err("keys","expand temporary space error:stackoverflow");
|
return builtin_err("keys","expand temporary space error:stackoverflow");
|
||||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||||
auto& vec=gc.top[0].vec().elems;
|
auto& vec=gc.top[0].vec().elems;
|
||||||
for(auto& iter:hash.hash().elems)
|
for(auto& iter:hash.hash().elems)
|
||||||
|
@ -767,7 +772,15 @@ please change it to:
|
||||||
|
|
||||||
`canary=gc.stack+STACK_MAX_DEPTH-1;`
|
`canary=gc.stack+STACK_MAX_DEPTH-1;`
|
||||||
|
|
||||||
If do not change this line, only the debugger runs abnormally. this bug is fixed in `v9.0`
|
If do not change this line, only the debugger runs abnormally. this bug is fixed in `v9.0`.
|
||||||
|
|
||||||
|
Another bug is that in `nasal_err.h:class nasal_err`, we should add a constructor for this class:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
nasal_err():error(0){}
|
||||||
|
```
|
||||||
|
|
||||||
|
This bug is fixed in `v9.0`.
|
||||||
|
|
||||||
## __Parser__
|
## __Parser__
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,6 @@
|
||||||
#define environ (*_NSGetEnviron())
|
#define environ (*_NSGetEnviron())
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
builtin functions must be called inside a function like this:
|
|
||||||
var print=func(elems...){
|
|
||||||
return __builtin_print(elems);
|
|
||||||
}
|
|
||||||
builtin function __builtin_print is wrapped up by print
|
|
||||||
*/
|
|
||||||
|
|
||||||
// declaration of builtin functions
|
// declaration of builtin functions
|
||||||
// to add new builtin function, declare it here and write the definition below
|
// to add new builtin function, declare it here and write the definition below
|
||||||
#define nas_native(name) nasal_ref name(nasal_ref*,nasal_gc&)
|
#define nas_native(name) nasal_ref name(nasal_ref*,nasal_gc&)
|
||||||
|
@ -283,7 +275,7 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
||||||
|
|
||||||
// push it to local scope to avoid being sweeped
|
// push it to local scope to avoid being sweeped
|
||||||
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||||
builtin_err("split","expand temporary space error:stackoverflow");
|
return builtin_err("split","expand temporary space error:stackoverflow");
|
||||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||||
|
|
||||||
std::vector<nasal_ref>& vec=gc.top[0].vec().elems;
|
std::vector<nasal_ref>& vec=gc.top[0].vec().elems;
|
||||||
|
@ -575,7 +567,7 @@ nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
||||||
return builtin_err("keys","\"hash\" must be hash");
|
return builtin_err("keys","\"hash\" must be hash");
|
||||||
// push vector into local scope to avoid being sweeped
|
// push vector into local scope to avoid being sweeped
|
||||||
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||||
builtin_err("keys","expand temporary space error:stackoverflow");
|
return builtin_err("keys","expand temporary space error:stackoverflow");
|
||||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||||
auto& vec=gc.top[0].vec().elems;
|
auto& vec=gc.top[0].vec().elems;
|
||||||
for(auto& iter:hash.hash().elems)
|
for(auto& iter:hash.hash().elems)
|
||||||
|
@ -1032,7 +1024,7 @@ nasal_ref builtin_environ(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
char** env=environ;
|
char** env=environ;
|
||||||
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
if(gc.top+1>=gc.stack+STACK_MAX_DEPTH-1)
|
||||||
builtin_err("environ","expand temporary space error:stackoverflow");
|
return builtin_err("environ","expand temporary space error:stackoverflow");
|
||||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||||
auto& vec=gc.top[0].vec().elems;
|
auto& vec=gc.top[0].vec().elems;
|
||||||
while(*env)
|
while(*env)
|
||||||
|
|
|
@ -171,7 +171,7 @@ struct nasal_obj
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
if(destructor && ptr)
|
if(destructor && ptr)
|
||||||
{destructor(ptr);}
|
destructor(ptr);
|
||||||
ptr=nullptr;
|
ptr=nullptr;
|
||||||
destructor=nullptr;
|
destructor=nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,7 @@ for(var i=0;i<10;i+=1)
|
||||||
|
|
||||||
var prt=func()
|
var prt=func()
|
||||||
{
|
{
|
||||||
if(os.platform()=="windows")
|
var s="\e[0;0H+--------------------+\n";
|
||||||
system("cls");
|
|
||||||
else
|
|
||||||
system("clear");
|
|
||||||
var s="+--------------------+\n";
|
|
||||||
for(var i=0;i<10;i+=1)
|
for(var i=0;i<10;i+=1)
|
||||||
{
|
{
|
||||||
s~="|";
|
s~="|";
|
||||||
|
@ -28,6 +24,7 @@ var prt=func()
|
||||||
}
|
}
|
||||||
s~='+--------------------+\n';
|
s~='+--------------------+\n';
|
||||||
print(s);
|
print(s);
|
||||||
|
unix.sleep(1/144);
|
||||||
}
|
}
|
||||||
|
|
||||||
var bfs=func(begin,end)
|
var bfs=func(begin,end)
|
||||||
|
@ -49,6 +46,7 @@ var bfs=func(begin,end)
|
||||||
{
|
{
|
||||||
map[x][y]=3;
|
map[x][y]=3;
|
||||||
prt();
|
prt();
|
||||||
|
print("reached.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(0<=x and x<10 and 0<=y and y<20 and map[x][y]==0)
|
if(0<=x and x<10 and 0<=y and y<20 and map[x][y]==0)
|
||||||
|
@ -63,4 +61,5 @@ var bfs=func(begin,end)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("\ec");
|
||||||
bfs([0,0],[9,19]);
|
bfs([0,0],[9,19]);
|
|
@ -23,22 +23,20 @@ var new_map=func()
|
||||||
|
|
||||||
var prt=func()
|
var prt=func()
|
||||||
{
|
{
|
||||||
var s='';
|
var s='\e[0;0H';
|
||||||
foreach(var line;map)
|
foreach(var line;map)
|
||||||
{
|
{
|
||||||
foreach(var elem;line)
|
foreach(var elem;line)
|
||||||
s~=elem~' ';
|
s~=elem~' ';
|
||||||
s~='\n';
|
s~='\n';
|
||||||
}
|
}
|
||||||
if(os.platform()=="windows")
|
|
||||||
system("cls");
|
|
||||||
else
|
|
||||||
system("clear");
|
|
||||||
print(s);
|
print(s);
|
||||||
|
unix.sleep(1/144);
|
||||||
}
|
}
|
||||||
|
|
||||||
func()
|
func()
|
||||||
{
|
{
|
||||||
|
print("\ec");
|
||||||
rand(time(0));
|
rand(time(0));
|
||||||
map=new_map();
|
map=new_map();
|
||||||
forindex(var i;map)
|
forindex(var i;map)
|
||||||
|
|
Loading…
Reference in New Issue