update src/README.md
This commit is contained in:
parent
4ecd336595
commit
d53548e1e7
@ -45,10 +45,13 @@ src/
|
|||||||
|
|
||||||
## Base
|
## Base
|
||||||
|
|
||||||
`B` represents any BQN object. Some are heap-allocated, some are not.
|
`B` represents any BQN object. It's a 64-bit NaN-boxed value; some of the NaN-boxed values, determined by the top 16 bits, are heap-allocated (i.e. low 48 bits are a `Value*`), some aren't:
|
||||||
```C
|
```C
|
||||||
Type checks (all are safe to execute on any B object):
|
Type checks (all are safe to execute on any B object):
|
||||||
test tag description heap-allocated
|
test tag description heap-allocated
|
||||||
|
isF64(x) F64_TAG a number no
|
||||||
|
isChr(x) C32_TAG a character no
|
||||||
|
isAtm(x) [many] !isArr(x) depends
|
||||||
isVal(x) [many] heap-allocated yes
|
isVal(x) [many] heap-allocated yes
|
||||||
isFun(x) FUN_TAG a function yes
|
isFun(x) FUN_TAG a function yes
|
||||||
isMd1(x) MD1_TAG a 1-modifier yes
|
isMd1(x) MD1_TAG a 1-modifier yes
|
||||||
@ -56,12 +59,9 @@ Type checks (all are safe to execute on any B object):
|
|||||||
isMd (x) [many] any modifier yes
|
isMd (x) [many] any modifier yes
|
||||||
isCallable(x) [many] isFun|isMd yes
|
isCallable(x) [many] isFun|isMd yes
|
||||||
isArr(x) ARR_TAG an array type yes
|
isArr(x) ARR_TAG an array type yes
|
||||||
isAtm(x) [many] !isArr(x) depends
|
|
||||||
isChr(x) C32_TAG a character no
|
|
||||||
isF64(x) F64_TAG a number no
|
|
||||||
isNsp(x) NSP_TAG a namespace yes
|
isNsp(x) NSP_TAG a namespace yes
|
||||||
isObj(x) OBJ_TAG internal yes
|
isObj(x) OBJ_TAG internal yes
|
||||||
and then there are some extra types for variables for the VM & whatever; see h.h *_TAG definitions
|
and then there are some extra types for variable slot references for the VM & whatever; see h.h *_TAG definitions
|
||||||
|
|
||||||
Functions for converting/using basic types:
|
Functions for converting/using basic types:
|
||||||
m_f64(x) // f64 → B
|
m_f64(x) // f64 → B
|
||||||
@ -85,17 +85,17 @@ Functions for converting/using basic types:
|
|||||||
noFill(x) // if x represents undefined fill (returned by getFill*; ≡ bi_noFill)
|
noFill(x) // if x represents undefined fill (returned by getFill*; ≡ bi_noFill)
|
||||||
tag(x,*_TAG) // pointer → B
|
tag(x,*_TAG) // pointer → B
|
||||||
|
|
||||||
See src/h.h for more basic functions
|
See src/h.h for more basics
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
All heap-allocated objects have a type - `t_i32arr`, `t_f64slice`, `t_funBl`, `t_temp`, etc. Full list is at `#define FOR_TYPE` in `src/h.h`.
|
All heap-allocated objects have a type - `t_i32arr`, `t_f64slice`, `t_funBl`, `t_temp`, etc. Full list is at `#define FOR_TYPE` in `src/h.h`.
|
||||||
|
|
||||||
An object can be allocated with `mm_alloc(sizeInBytes, t_something)`. The returned object starts with `Value`, so custom data must be after that. `mm_free` can be used to force-free an object regardless of its reference count.
|
An object can be allocated with `mm_alloc(sizeInBytes, t_something)`. The returned object starts with the structure of `Value`, so custom data must be after that. `mm_free` can be used to force-free an object regardless of its reference count.
|
||||||
|
|
||||||
A heap-allocated object of type `B` can be cast to a `Value*` with `v(x)`, to an `Arr*` with `a(x)`, or to a specific pointer type with `c(Type,x)`. `v(x)->type` stores the type of an object (one of `t_whatever`), which is used to dynamically determine how to interpret an object.
|
A heap-allocated object from type `B` can be cast to a `Value*` with `v(x)`, to an `Arr*` with `a(x)`, or to a specific pointer type with `c(Type,x)`. `v(x)->type` stores the type of an object (one of `t_whatever`), which is used to dynamically determine how to interpret an object. Note that the type is separate from the tag used for NaN-boxing.
|
||||||
|
|
||||||
The reference count of any `B` object can be incremented/decremented with `inc(x)`/`dec(x)`, and any subtype of `Value*` can use `ptr_inc(x)`/`ptr_dec(x)`. `inc(x)`/`ptr_inc(x)` will return the argument, so you can use it inline, and `dec`/`ptr_dec` will return the object to the memory manager if the refcount as a result goes to zero.
|
The reference count of any `B` object can be incremented/decremented with `inc(x)`/`dec(x)`, and any subtype of `Value*` can use `ptr_inc(x)`/`ptr_dec(x)`. `inc(x)` and `ptr_inc(x)` will return the argument, so you can use it inline. `dec(x)` and `ptr_dec(x)` will return the object to the memory manager if the refcount as a result goes to zero.
|
||||||
|
|
||||||
Since reference counting is hard, there's `make heapverify` that verifies that any code executed does it right (and screams unreadable messages when it doesn't). After any changes, I'd suggest running:
|
Since reference counting is hard, there's `make heapverify` that verifies that any code executed does it right (and screams unreadable messages when it doesn't). After any changes, I'd suggest running:
|
||||||
```bash
|
```bash
|
||||||
@ -128,7 +128,7 @@ All virtual method accesses require that the argument is heap-allocated.
|
|||||||
|
|
||||||
You can get a virtual function of a `B` object with `TI(x, something)`. There's also `TIv(x, something)` for a pointer `x` instead. See `#define FOR_TI` in `src/h.h` for available functions.
|
You can get a virtual function of a `B` object with `TI(x, something)`. There's also `TIv(x, something)` for a pointer `x` instead. See `#define FOR_TI` in `src/h.h` for available functions.
|
||||||
|
|
||||||
Call a BQN function object with `c1(f, x)` or `c2(f, w, x)`. A specific builtin can be called by looking up the appropriate name in `src/builtins.h` (and adding the `bi_` prefix).
|
Call a BQN function object with `c1(f, x)` or `c2(f, w, x)`. A specific builtin can be called by looking up the appropriate name in `src/builtins.h`, adding the `bi_` prefix, and invoking it with `c1`/`c2`. Note that these functions consume `w` and `x`, but leave the refcout of `f` untouched. (usually, which arguments are consumed is specified in a comment after either the function definition or prototype)
|
||||||
|
|
||||||
Calling a modifier involves deriving it with `m1_d`/`m2_d`, using a regular `c1`/`c2`, and managing the refcounts of everything while at that.
|
Calling a modifier involves deriving it with `m1_d`/`m2_d`, using a regular `c1`/`c2`, and managing the refcounts of everything while at that.
|
||||||
|
|
||||||
@ -152,6 +152,8 @@ For functions, in most cases, the `t` parameter (representing `𝕊`/"this") is
|
|||||||
|
|
||||||
For modifiers, the `d` parameter stores the operands and the modifier itself. Use `d->f` for `𝔽`, `d->g` for `𝔾`, `d->m1` for `_𝕣`, `d->m2` for `_𝕣_`, and `tag(d,FUN_TAG)` for `𝕊`.
|
For modifiers, the `d` parameter stores the operands and the modifier itself. Use `d->f` for `𝔽`, `d->g` for `𝔾`, `d->m1` for `_𝕣`, `d->m2` for `_𝕣_`, and `tag(d,FUN_TAG)` for `𝕊`.
|
||||||
|
|
||||||
|
The implementation should consume the `w`/`x` arguments, but not `t`/`d`.
|
||||||
|
|
||||||
## Inverses
|
## Inverses
|
||||||
|
|
||||||
```C
|
```C
|
||||||
@ -169,7 +171,7 @@ c(BMd2,bi_some2mod)->im = some2mod_im; // you get the idea
|
|||||||
|
|
||||||
## Arrays
|
## Arrays
|
||||||
|
|
||||||
If you know that `x` is an array (e.g. by testing `isArr(x)` beforehand), `a(x)->ia` will give you the product of the shape (aka total element count), `rnk(x)` will give you the rank (`prnk(x)` for an untagged pointer object), and `a(x)->sh` will give you a `usz*` to the full shape.
|
If you know that `x` is an array (e.g. by testing `isArr(x)` beforehand), `a(x)->ia` will give you the product of the shape (aka total element count), `rnk(x)` will give you the rank (use `prnk(x)` for an untagged pointer object), and `a(x)->sh` will give you a `usz*` to the full shape.
|
||||||
|
|
||||||
The shape pointer of a rank 0 or 1 array will point to the object's own `ia` field. Otherwise, it'll point inside a `t_shape` object.
|
The shape pointer of a rank 0 or 1 array will point to the object's own `ia` field. Otherwise, it'll point inside a `t_shape` object.
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user