Skip to content

Commit

Permalink
Merge pull request #624 from HigherOrderCO/621-add-io-for-loading-and…
Browse files Browse the repository at this point in the history
…-calling-dynamicly-linked-libraries

#621 Add dylib IO functions
  • Loading branch information
imaqtkatt authored Jul 22, 2024
2 parents 060239a + 3c042d4 commit 02492e6
Show file tree
Hide file tree
Showing 15 changed files with 570 additions and 94 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ and this project does not currently adhere to a particular versioning scheme.
- Add import system. ([#544][gh-544])
- Add multi line comment `#{ ... #}` syntax. ([#595][gh-595])
- Add error message when input file is not found. ([#513][gh-513])
- Add `List/filter` and `String/{equals, filter}` builtins.
- Add IO functions for loading dynamically linked libraries (`IO/DyLib/open`, `IO/DyLib/call`, `IO/DyLib/close`). ([#621][gh-621])

## [0.2.36] - 2024-07-04

Expand All @@ -27,6 +29,8 @@ and this project does not currently adhere to a particular versioning scheme.
- Don't allow tabs to be used for indentation or spacing. ([#463][gh-463])
- Rename builtin function `sleep` to `IO/nanosleep`. ([#581][gh-581])
- Equational number pattern compilation to use the predecessor variable when possible. ([#470][gh-470])
- Rename `Bytes/decode_utf8` to `String/decode_utf8` and `Bytes/decode_ascii` to `String/decode_ascii`.
- Rename `log` to `Math/log` and `atan2` to `Math/atan2`.

### Fixed

Expand Down Expand Up @@ -395,5 +399,6 @@ and this project does not currently adhere to a particular versioning scheme.
[gh-598]: https://github.com/HigherOrderCO/Bend/issues/598
[gh-618]: https://github.com/HigherOrderCO/Bend/issues/618
[gh-620]: https://github.com/HigherOrderCO/Bend/issues/620
[gh-621]: https://github.com/HigherOrderCO/Bend/issues/621
[gh-623]: https://github.com/HigherOrderCO/Bend/issues/623
[Unreleased]: https://github.com/HigherOrderCO/Bend/compare/0.2.36...HEAD
2 changes: 1 addition & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,6 @@
"/`...`/g",
"/`....`/g",
"/`.....`/g",
"/```.*\n.*\n```/g"
"/```(.*\n)*```/g"
]
}
156 changes: 143 additions & 13 deletions docs/builtins.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ A String literal is surrounded with `"`. Accepts the same values as characters l
"Hello, World!"
```

### Functions

#### String/equals

Checks if two strings are equal.

```python
def String/equals(s1: String, s2: String) -> u24
```

#### String/split

Splits a string into a list of strings based on the given delimiter.

```python
def String/split(s: String, delimiter: u24) -> [String]
```

## List

```python
Expand Down Expand Up @@ -84,6 +102,22 @@ List/concat([1, 2], [4, 5])
# Result: [1, 2, 4, 5]
```

#### List/filter

Filters a list based on a predicate function.

```python
List/filter(xs: List(T), pred: T -> Bool) -> List(T)
```

#### List/split_once

Splits a list into two lists at the first occurrence of a value.

```python
List/split_once(xs: List(T), val: T) -> (Result(List(T), List(T)))
```

## Tree

```python
Expand Down Expand Up @@ -306,6 +340,48 @@ A Natural Number can be written with literals with a `#` before the literal numb
#1337
```

## DiffList

DiffList is a list that has constant time prepends (cons), appends and concatenation, but can't be pattern matched.

It is implemented as a function that receives a list to be appended to the last element of the DiffList.

For example, the list `List/Cons(1, List/Cons(2, List/Nil))` can be written as the difference list `lambda x: List/Cons(1, List/Cons(2, x))`.

### Functions

#### DiffList/new

Creates a new difference list.

```python
def DiffList/new() -> (List(T) -> List(T))
```

#### DiffList/append

Appends a value to the end of the difference list.

```python
def DiffList/append(diff: List(T) -> List(T), val: T) -> (List(T) -> List(T))
```

#### DiffList/cons

Appends a value to the beginning of the difference list.

```python
def DiffList/cons(diff: List(T) -> List(T), val: T) -> (List(T) -> List(T))
```

#### DiffList/to_list

Converts a difference list to a regular cons list.

```python
def DiffList/to_list(diff: List(T) -> List(T)) -> (List(T))
```

## IO

The basic builtin IO functions are under development and will be stable in the next milestone.
Expand Down Expand Up @@ -439,25 +515,45 @@ Flushes the file with the given `file` descriptor.

Returns nothing (`*`).

## Numeric operations
### Dinamically linked libraries

### log
It's possible to dynamically load shared objects (libraries) with functions that implement the Bend IO interface.
You can read more on how to implement these libraries in the [Dynamically linked libraries and foreign functions](docs/ffi.md) documentation.

#### IO/DyLib/open

```py
def log(x: f24, base: f24) -> f24
def IO/DyLib/open(path: String, lazy: u24) -> u24
```

Computes the logarithm of `x` with the specified `base`.
Loads a dynamic library file.
* `path` is the path to the library file.
* `lazy` is a boolean encoded as a `u24` that determines if all functions are loaded lazily (`1`) or upfront (`0`).
* Returns an unique id to the library object encoded as a `u24`.

### atan2
#### IO/DyLib/call

``` py
def IO/DyLib/call(dl: u24, fn: String, args: Any) -> Any
```

Calls a function of a previously opened library.
* `dl` is the id of the library object.
* `fn` is the name of the function in the library.
* `args` are the arguments to the function. The expected values depend on the called function.
* The returned value is determined by the called function.

#### IO/DyLib/close

```py
def atan2(x: f24, y: f24) -> f24
def IO/DyLib/close(dl: u24) -> None
```

Computes the arctangent of `y / x`.
Closes a previously open library.
* `dl` is the id of the library object.
* Returns nothing (`*`).

Has the same behaviour as `atan2f` in the C math lib.
## Native number casting

### to_f24

Expand Down Expand Up @@ -485,18 +581,18 @@ Casts any native number to an i24.

## String encoding / decoding

### Bytes/decode_utf8
### String/decode_utf8

```py
def Bytes/decode_utf8(bytes: [u24]) -> String
```
def String/decode_utf8(bytes: [u24]) -> String
```

Decodes a sequence of bytes to a String using utf-8 encoding.

### Bytes/decode_ascii
### String/decode_ascii

```py
def Bytes/decode_ascii(bytes: [u24]) -> String
def String/decode_ascii(bytes: [u24]) -> String
```

Decodes a sequence of bytes to a String using ascii encoding.
Expand Down Expand Up @@ -533,6 +629,25 @@ def Utf8/REPLACEMENT_CHARACTER: u24 = '\u{FFFD}'

## Math

### Math/log

```py
def Math/log(x: f24, base: f24) -> f24
```

Computes the logarithm of `x` with the specified `base`.

### Math/atan2

```py
def Math/atan2(x: f24, y: f24) -> f24
```

Computes the arctangent of `y / x`.

Has the same behaviour as `atan2f` in the C math lib.


### Math/PI

Defines the Pi constant.
Expand All @@ -541,6 +656,14 @@ Defines the Pi constant.
def Math/PI: f24 = 3.1415926535
```

### Math/E

Euler's number

```py
def Math/E: f24 = 2.718281828
```

### Math/sin

Computes the sine of the given angle in radians.
Expand Down Expand Up @@ -652,3 +775,10 @@ Round float to the nearest integer.
```py
def Math/round(n: f24) -> f24
```

## Lazy thunks

You can force a function call to be evaluated lazily by wrapping it in a lazy thunk.
In Bend, this can be expressed as `lambda x: x(my_function, arg1, arg2, ...)`.

To evaluate the thunk, you can use the `undefer` function or apply `lambda x: x` to it.
Loading

0 comments on commit 02492e6

Please sign in to comment.