Add file IO functions

This commit is contained in:
Nicolas Abril 2024-06-12 17:35:30 +02:00
parent 84661fd12a
commit e57caa189e
3 changed files with 105 additions and 8 deletions

View File

@ -23,6 +23,7 @@ and this project does not currently adhere to a particular versioning scheme.
- Add `log` and `atan2` builtin functions. ([#583][gh-583])
- Add `to_f24`, `to_u24` and `to_i24` number casting builtin functions. ([#582][gh-582])
- Add `IO/sleep` builtin function to sleep for a given amount of seconds as a float. ([#581][gh-581])
- Add primitive file IO functions `IO/FS/{read, write, seek, open, close}`. ([#573][gh-573])
## [0.2.35] - 2024-06-06
@ -344,6 +345,7 @@ and this project does not currently adhere to a particular versioning scheme.
[gh-526]: https://github.com/HigherOrderCO/Bend/issues/526
[gh-528]: https://github.com/HigherOrderCO/Bend/issues/528
[gh-581]: https://github.com/HigherOrderCO/Bend/issues/581
[gh-573]: https://github.com/HigherOrderCO/Bend/issues/573
[gh-582]: https://github.com/HigherOrderCO/Bend/issues/582
[gh-583]: https://github.com/HigherOrderCO/Bend/issues/583
[gh-586]: https://github.com/HigherOrderCO/Bend/issues/586

View File

@ -225,7 +225,74 @@ A Natural Number can be written with literals with a `#` before the literal numb
## IO
IO Functions are in the **next milestone**!
The basic builtin IO functions are under development and will be stable in the next milestone.
Here is the current list of functions, but be aware that they may change in the near future.
### File IO
#### File open
```python
def IO/FS/open(path, mode)
```
Opens a file with with `path` being given as a string and `mode` being a string with the mode to open the file in. The mode should be one of the following:
- `"r"`: Read mode
- `"w"`: Write mode (write at the beginning of the file, overwriting any existing content)
- `"a"`: Append mode (write at the end of the file)
- `"r+"`: Read and write mode
- `"w+"`: Read and write mode
- `"a+"`: Read and append mode
Returns an U24 with the file descriptor. File descriptors are not necessarily the same as the ones assigned by the operating system, but rather unique identifiers internal to Bend's runtime.
#### File descriptors for standard files
The standard input/output files are always open and assigned the following file descriptors:
- `IO/FS/STDIN = 0`: Standard input
- `IO/FS/STDOUT = 1`: Standard output
- `IO/FS/STDERR = 2`: Standard error
#### File close
```python
def IO/FS/close(file)
```
Closes the file with the given `file` descriptor.
#### File read
```python
def IO/FS/read(file, num_bytes)
```
Reads `num_bytes` bytes from the file with the given `file` descriptor.
Returns a list of U24 with each element representing a byte read from the file.
#### File write
```python
def IO/FS/write(file, bytes)
```
Writes `bytes`, a list of U24 with each element representing a byte, to the file with the given `file` descriptor.
Returns nothing (`*`).
Writing discards any preexisting content that came after the current position. For example, if your file contains the text `Hello, world!` and the current position is at the `,`, writing `!` will
#### File seek
```python
def IO/FS/seek(file, offset, mode)
```
Moves the current position of the file with the given `file` descriptor to the given `offset`, an I24 or U24 number, in bytes.
`mode` can be one of the following:
- `IO/FS/SEEK_SET = 0`: Seek from start of file
- `IO/FS/SEEK_CUR = 1`: Seek from current position
- `IO/FS/SEEK_END = 2`: Seek from end of file
Returns nothing (`*`).
## Numeric operations

View File

@ -88,13 +88,7 @@ def IO/bind(a, b):
def call(func, argm):
return IO/Call(IO/MAGIC, func, argm, lambda x: IO/Done(IO/MAGIC, x))
print text = (IO/Call IO/MAGIC "WRITE" (1, text) @x (IO/Done IO/MAGIC x))
#input = (IO/Call IO/MAGIC "GET_TEXT" * @x (IO/Done IO/MAGIC x))
#read_file path = (IO/Call IO/MAGIC "GET_FILE" path @x (IO/Done IO/MAGIC x))
#write_file path text = (IO/Call IO/MAGIC "PUT_FILE" (path, text) @x (IO/Done IO/MAGIC x))
## Time and sleep
# Returns a monotonically increasing nanosecond timestamp as an u48 encoded as a pair of u24s.
IO/get_time = (IO/Call IO/MAGIC "GET_TIME" * @x (IO/Done IO/MAGIC x))
@ -108,6 +102,40 @@ def IO/sleep(seconds):
hi = to_u24(nanos / 0x1_000_000.0)
return IO/nanosleep((hi, lo))
## File IO
### File IO primitives
IO/FS/open path mode = (IO/Call IO/MAGIC "OPEN" (path, mode) @x (IO/Done IO/MAGIC x))
IO/FS/close file = (IO/Call IO/MAGIC "CLOSE" file @x (IO/Done IO/MAGIC x))
IO/FS/read file num_bytes = (IO/Call IO/MAGIC "READ" (file, num_bytes) @x (IO/Done IO/MAGIC x))
IO/FS/write file bytes = (IO/Call IO/MAGIC "WRITE" (file, bytes) @x (IO/Done IO/MAGIC x))
IO/FS/seek file offset mode = (IO/Call IO/MAGIC "SEEK" (file, (offset, mode)) @x (IO/Done IO/MAGIC x))
### Always available files
IO/FS/STDIN = 0
IO/FS/STDOUT = 1
IO/FS/STDERR = 2
### Seek modes
# Seek from start of file
IO/FS/SEEK_SET = +0
# Seek from current position
IO/FS/SEEK_CUR = +1
# Seek from end of file
IO/FS/SEEK_END = +2
### File utilities
#read_file path = (IO/Call IO/MAGIC "GET_FILE" path @x (IO/Done IO/MAGIC x))
#write_file path text = (IO/Call IO/MAGIC "PUT_FILE" (path, text) @x (IO/Done IO/MAGIC x))
### Standard input and output utilities
# TODO: Encode with utf-8
IO/print text = (IO/FS/write IO/FS/STDOUT text)
# TODO: Should read any length of input
IO/input = (IO/FS/read IO/FS/STDIN 1024)
# Lazy thunks
# We can defer the evaluation of a function by wrapping it in a thunk
# Ex: @x (x @arg1 @arg2 @arg3 (f arg1 arg2 arg3) arg1 arg2 arg3)