safer stl/module.nas & add stl/file.nas encapsulated from lib.nas/io

This commit is contained in:
ValKmjolnir 2022-03-06 15:17:39 +08:00
parent ca9b8581b4
commit debe32b187
7 changed files with 72 additions and 23 deletions

View File

@ -710,7 +710,7 @@ dylib.dlclose(dlhandle);
`dylib.dlcall` is used to call the function, the first argument is the function address, make sure this argument is vm_obj and type=obj_extern. `dylib.dlcall` is used to call the function, the first argument is the function address, make sure this argument is vm_obj and type=obj_extern.
`dylib.dlclose` is used to unload the library, at the moment that you call the function, all the function addresses that gotten from it are invalid. `dylib.dlclose` is used to unload the library, at the moment that you call the function, all the function addresses that got from it are invalid.
If get this, Congratulations! If get this, Congratulations!

View File

@ -154,6 +154,13 @@ var chr=func(code){
return __builtin_chr(code); return __builtin_chr(code);
} }
# mut is used to change unmutable strings to mutable.
var mut=func(str){
if(typeof(str)!="str")
die("mut: \"str\" must be string.");
return str~"";
}
# println has the same function as print. # println has the same function as print.
# but it will output a '\n' after using print. # but it will output a '\n' after using print.
var println=func(elems...){ var println=func(elems...){
@ -176,6 +183,7 @@ var io=
# same as C fclose. close file by FILE*. # same as C fclose. close file by FILE*.
close: func(filehandle){return __builtin_close(filehandle);}, close: func(filehandle){return __builtin_close(filehandle);},
# same as C fread. read file by FILE*. # same as C fread. read file by FILE*.
# caution: buf must be a mutable string.use mut("") to get an empty mutable string.
read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);}, read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);},
# same as C fwrite. write file by FILE*. # same as C fwrite. write file by FILE*.
write: func(filehandle,str){return __builtin_write(filehandle,str);}, write: func(filehandle,str){return __builtin_write(filehandle,str);},

View File

@ -757,6 +757,8 @@ nasal_ref builtin_read(nasal_ref* local,nasal_gc& gc)
return builtin_err("read","not a correct filehandle"); return builtin_err("read","not a correct filehandle");
if(buf.type!=vm_str) if(buf.type!=vm_str)
return builtin_err("read","\"buf\" must be string"); return builtin_err("read","\"buf\" must be string");
if(buf.value.gcobj->unmut)
return builtin_err("read","\"buf\" is not a mutable string");
if(len.type!=vm_num) if(len.type!=vm_num)
return builtin_err("read","\"len\" must be number"); return builtin_err("read","\"len\" must be number");
if(len.num()<=0 || len.num()>=(1<<30)) if(len.num()<=0 || len.num()>=(1<<30))

26
stl/file.nas Normal file
View File

@ -0,0 +1,26 @@
# lib file.nas
# ValKmjolnir 2022/3/6
import("lib.nas");
var file={
SEEK_SET:io.SEEK_SET,
SEEK_CUR:io.SEEK_CUR,
SEEK_END:io.SEEK_END,
new: func(filename,mode="r"){
var fd=io.open(filename,mode);
return {
close: func(){io.close(fd);},
read: func(len){
var buf=mut("");
io.read(fd,buf,len);
return buf;
},
write: func(str){return io.write(fd,str);},
seek: func(pos,whence){return io.seek(fd,pos,whence);},
tell: func(){return io.tell(fd);},
readln: func(){return io.readln(fd);},
stat: func(){return io.stat(filename);},
eof: func(){return io.eof(fd);}
};
}
};

View File

@ -154,6 +154,13 @@ var chr=func(code){
return __builtin_chr(code); return __builtin_chr(code);
} }
# mut is used to change unmutable strings to mutable.
var mut=func(str){
if(typeof(str)!="str")
die("mut: \"str\" must be string.");
return str~"";
}
# println has the same function as print. # println has the same function as print.
# but it will output a '\n' after using print. # but it will output a '\n' after using print.
var println=func(elems...){ var println=func(elems...){
@ -176,6 +183,7 @@ var io=
# same as C fclose. close file by FILE*. # same as C fclose. close file by FILE*.
close: func(filehandle){return __builtin_close(filehandle);}, close: func(filehandle){return __builtin_close(filehandle);},
# same as C fread. read file by FILE*. # same as C fread. read file by FILE*.
# caution: buf must be a mutable string.use mut("") to get an empty mutable string.
read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);}, read: func(filehandle,buf,len){return __builtin_read(filehandle,buf,len);},
# same as C fwrite. write file by FILE*. # same as C fwrite. write file by FILE*.
write: func(filehandle,str){return __builtin_write(filehandle,str);}, write: func(filehandle,str){return __builtin_write(filehandle,str);},

View File

@ -11,35 +11,36 @@ var module_call_func=func(fptr,args){
} }
var extern={ var extern={
new: func(fptr){ new: func(fptr){
var isopen=1;
return { return {
fptr:fptr, close:func(){isopen=0;},
isopen:1, call:func(args...){
parents:[extern] return (!isopen)?
nil:
module_call_func(fptr,args);
}
}; };
},
call: func(args...){
return (!me.isopen)?nil:module_call_func(me.fptr,args);
} }
}; };
var module={ var module={
name:nil,
new: func(name){ new: func(name){
me.name=name;
var lib=dylib.dlopen(name);
var f={};
return { return {
name:name, get:func(symbol){
lib:dylib.dlopen(name), if(contains(f,symbol))
f:{}, return f[symbol];
parents:[module] var fp=extern.new(dylib.dlsym(lib,symbol));
f[symbol]=fp;
return fp;
},
close: func(){
foreach(var i;keys(f))
f[i].close();
dylib.dlclose(lib);
}
}; };
},
get: func(symbol){
if(contains(me.f,symbol))
return me.f[symbol];
var f=extern.new(dylib.dlsym(me.lib,symbol));
me.f[symbol]=f;
return f;
},
close: func(){
foreach(var i;keys(me.f))
me.f[i].isopen=0;
dylib.dlclose(me.lib);
} }
}; };

View File

@ -16,8 +16,10 @@ var source=[
]; ];
var lib=[ var lib=[
"stl/file.nas ",
"stl/lib.nas ", "stl/lib.nas ",
"stl/list.nas ", "stl/list.nas ",
"stl/module.nas ",
"stl/queue.nas ", "stl/queue.nas ",
"stl/result.nas ", "stl/result.nas ",
"stl/sort.nas ", "stl/sort.nas ",
@ -28,6 +30,7 @@ var testfile=[
"test/ascii-art.nas ", "test/ascii-art.nas ",
"test/auto_crash.nas ", "test/auto_crash.nas ",
"test/bf.nas ", "test/bf.nas ",
"test/bfcolored.nas ",
"test/bfconvertor.nas ", "test/bfconvertor.nas ",
"test/bfs.nas ", "test/bfs.nas ",
"test/bigloop.nas ", "test/bigloop.nas ",
@ -53,6 +56,7 @@ var testfile=[
"test/props.nas ", "test/props.nas ",
"test/quick_sort.nas ", "test/quick_sort.nas ",
"test/scalar.nas ", "test/scalar.nas ",
"test/tetris.nas ",
"test/trait.nas ", "test/trait.nas ",
"test/turingmachine.nas", "test/turingmachine.nas",
"test/ycombinator.nas " "test/ycombinator.nas "