From: Elias Fleckenstein Date: Thu, 30 Dec 2021 21:13:48 +0000 (+0100) Subject: Implement nolambda:fs module X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=9d8170032150e3030f8dcc88c731410ef4e9dbb8;p=uwu-nolambda.git Implement nolambda:fs module --- diff --git a/Makefile b/Makefile index bd4f504..7e163ae 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -all: flow.so io.so +all: flow.so io.so fs.so uwu_include_path=../uwulang/ diff --git a/README.md b/README.md index 8bfb578..8f20a2c 100644 --- a/README.md +++ b/README.md @@ -20,35 +20,35 @@ make uwu_include_path=/path/to/uwulang/repo ### `nolambda:flow` - `nolambda:flow:linear`: Accepts an arbitrary number of arguments of arbitrary type, but at least one and evaulates all of them in order. Returns the last argument. -- `nolambda:flow:error`: Accepts an arbitrary value as $0, prints it to stderr appending a newline and exits the program with failure. Returns `:nil:nil` in theory. +- `nolambda:flow:error`: Accepts an arbitrary type as $0, prints it to stderr appending a newline and exits the program with failure. Returns `:nil:nil` in theory. ### `nolambda:io` -- `nolambda:io:print`: Accepts an arbitrary value as $0 and prints it to stdout, followed by a newline. Returns $0. +- `nolambda:io:print`: Accepts an arbitrary type as $0 and prints it to stdout, followed by a newline. Returns $0. - `nolambda:io:scan`: Reads a line from stdin and returns it as a string, without the newline character at the end. If $0 is given, it is used as a prompt (after converting to string). ### `nolambda:fs` Note: all file paths are relative to the _directory the program was started from_. -- `nolambda:fs:read`: Accepts a file name (arbirary value, used as string) as $0 and returns it's contents as a string. Causes an error if the file does not exist. -- `nolambda:fs:write`: Accepts a file name (arbirary value, used as string) as $0 and overwrites it with the contents in $1 (arbirary value, used as string). Causes an error if the file could not be written. Returns `:bool:true` if the file was freshly created, `:bool:false` if it was overwritten. -- `nolambda:fs:remove`: Accepts a file name (arbirary value, used as string) as $0 and removes it from the file system. Causes an error if the file could not be removed, but does not cause an error if the file does not exist. Returns `:bool:true` if the file existed and was removed, `:bool:false` otherwise. -- `nolambda:fs:exists`: Accepts a file name (arbirary value, used as string) as $0 and returns `:bool:true` if it exists, `:bool:fase` else. +- `nolambda:fs:read`: Accepts a file name (arbirary value, converted to string) as $0 and returns it's contents as a string. Causes an error if the file does not exist. +- `nolambda:fs:write`: Accepts a file name (arbirary value, converted to string) as $0 and overwrites it with the contents in $1 (arbirary value, converted to string). Causes an error if the file could not be written. Returns `:nil:nil`. +- `nolambda:fs:remove`: Accepts an arbitrary number of file names (arbirary type, converted to string), but at least one and unlinks them from the file system (the files can also be a directories). Causes an error if one of the file could not be removed, but does not cause an error if some or all of the files did not exist in the first place. Returns `:nil:nil`. +- `nolambda:fs:exists`: Accepts an arbitrary number of file names (arbirary type, converted to string), but at least one and returns `:bool:true` if all of them exist, `:bool:fase` else. ### `nolambda:os` - `nolambda:os:exit`: Optionally takes an exit code (integer) as $0 and exits the program with the given exit code, or 0 if no exit code was given. Returns `:nil:nil` in theory. - `nolambda:os:sleep`: Takes an integer as $0 and pauses the execution of the program for $1 milliseconds. Returns `:nil:nil`. -- `nolambda:os:execute`: Takes a command (arbirary value, used as string) as $0 and executes it as a shell command. Returns the exit code of the command as an integer. +- `nolambda:os:execute`: Takes a command (arbirary value, converted to string) as $0 and executes it as a shell command. Returns the exit code of the command as an integer. - `nolambda:os:time`: Returns the current unix time as an integer. ### `nolambda:global` -- `nolambda:global:set`: Creates or overwrites a global variable named $0 (arbirary value, used as string) and puts the contents of $1 (arbitrary type) into it. Returns `:bool:false` if the variable existed previously and was updated, `:bool:true` if it was created. -- `nolambda:global:get`: Returns the global variable named $0 (arbirary value, used as string). Causes an error if the variable does not exist. -- `nolambda:global:exists`: Returns `:bool:true` if the global variable named $0 (arbirary value, used as string) exists, `:bool:false` else. -- `nolambda:global:delete`: Deletes the global variable named $0 (arbirary value, used as string). Returns `:bool:true` if the variable existed previously, `:bool:false` else. +- `nolambda:global:set`: Creates or overwrites a global variable named $0 (arbirary value, converted to string) and puts the contents of $1 (arbitrary type) into it. Returns `:bool:false` if the variable existed previously and was updated, `:bool:true` if it was created. +- `nolambda:global:get`: Returns the global variable named $0 (arbirary value, converted to string). Causes an error if the variable does not exist. +- `nolambda:global:exists`: Returns `:bool:true` if the global variable named $0 (arbirary value, converted to string) exists, `:bool:false` else. +- `nolambda:global:delete`: Deletes the global variable named $0 (arbirary value, converted to string). Returns `:bool:true` if the variable existed previously, `:bool:false` else. ### `nolambda:random` diff --git a/fs.c b/fs.c new file mode 100644 index 0000000..0c64c39 --- /dev/null +++ b/fs.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include "common/err.h" +#include "common/file.h" +#include "api/vm.h" +#include "api/str.h" +#include "api/nil.h" +#include "api/bool.h" +#include "api/util.h" + +UwUVMValue uwu_read(UwUVMArgs *args) +{ + uwuutil_require_exact("nolambda:fs:read", args, 1); + + char *filename = uwustr_get(uwuvm_get_arg(args, 0)); + + FILE *file = fopen(filename, "r"); + if (! file) syserror("fopen", file); + if (fseek(file, 0, SEEK_END) == -1) syserror("fseek", file); + + size_t size = ftell(file); + if (size == 1) syserror("ftell", file); + if (fseek(file, 0, SEEK_SET) == -1) syserror("fseek", file); + + char contents[size]; + if (fread(contents, 1, size, file) != size) syserror("fread", file); + + fclose(file); + free(filename); + + return uwustr_create(contents); +} + +UwUVMValue uwu_write(UwUVMArgs *args) +{ + uwuutil_require_exact("nolambda:fs:write", args, 2); + + char *filename = uwustr_get(uwuvm_get_arg(args, 0)); + char *contents = uwustr_get(uwuvm_get_arg(args, 1)); + + FILE *file = fopen(filename, "w"); + if (! file) syserror("fopen", file); + + size_t size = strlen(contents); + if (fwrite(contents, 1, size, file) != size) syserror("fwrite", file); + + fclose(file); + free(filename); + free(contents); + + return uwunil_create(); +} + +UwUVMValue uwu_remove(UwUVMArgs *args) +{ + uwuutil_require_min("nolambda:fs:remove", args, 1); + + for (size_t i = 0; i < args->num; i++) { + char *filename = uwustr_get(uwuvm_get_arg(args, i)); + + if (remove(filename) != 0) syserror("remove", NULL); + + free(filename); + } + + return uwunil_create(); +} + +UwUVMValue uwu_exists(UwUVMArgs *args) +{ + uwuutil_require_min("nolambda:fs:exists", args, 1); + + for (size_t i = 0; i < args->num; i++) { + char *filename = uwustr_get(uwuvm_get_arg(args, i)); + bool exists = file_exists(filename); + free(filename); + + if (! exists) + return uwubool_create(false); + } + + return uwubool_create(true); +} diff --git a/test.uwu b/test.uwu index a061a99..a0e0681 100644 --- a/test.uwu +++ b/test.uwu @@ -1,9 +1,31 @@ main flow:linear( io:print("please enter something:"), io:print(io:scan), + io:print(:str:cat( "your input: ", io:scan("please enter something else: ") )), + + io:print(:nil:nil), + io:print("--- QUINE ---"), + io:print(fs:read("test.uwu")), + io:print("--- END OF QUINE ---"), + io:print(:nil:nil), + + fs:write("test", "hello world"), + :bool:if(fs:exists("test"), + io:print("successfully wrote file"), + flow:error("failed to write file") + ), + + io:print(fs:read("test")), + + fs:remove("test"), + :bool:if(fs:exists("test"), + flow:error("failed to remove file"), + io:print("successfully removed file") + ), + "success" )