Skip to content

Commit

Permalink
Squashed 'lispBM/lispBM/' changes from 6a448aa3..c097f5c6
Browse files Browse the repository at this point in the history
c097f5c6 cleaning pass and refactoring
5384d522 refactoring application experiment
087ede4e refactor: readability, clearity and in some places - to a small degree - correctness
89575d8b small change to one event test
ba6e7fa7 logged change
16ac6bd1 logged change
089468b3 removing make-env. in-env in the interest of keeping core language small
f18015f7 Merge branch 'master' of github.com:svenssonjoel/lispbm
5b19dfda simplification and readability refactoring.
8c492889 Update gotchas.md
754221b9 Update gotchas.md
a0931bac bump version
e49071dc Changed behavior closure application to zero args. Application of a continuation (call-cc) with 0 args still uses the old approach where 0 args is equivalent to application to nil
35f495f3 mini tweak readme
fdd01ff1 update README
b21a3fa7 Update gotchas.md
92d9f561 update gotchas
0d708de7 bugfix in incremental reader and addition of a gotchas.md file for edge-case behaviors
d9a38456 updated lbmref with take and drop
86b1cc1b take, drop, change to make-env returned result
ea29f5ec added take and drop as built-in primitives and change to result env for make-env
55a5b1f5 added some tests and  a small amount of doc
e2d2f745 tweaks
bccdee1f make-env and in-env
3a03232a added make-env and in-env for library-encapsulation
e5b5ba66 mini tweak
dce87812 removed extra ;
190b4d9e mini tweak
6864fa32 fix repl after removal of reading_done callback
ea3aba39 removed reading_done_callback and made the nonsense default variants for all remaining callback
427cb37c bugfix read-program, tightening up,  cleaning
119d9fd3 refactoring and tightening up
10573404 cleaning and readability
63b750b5 small tweaks
d44c8bdc bug fix related to row numbers in error messages while doing incremental read. Now more precise.
d0125bd1 refactoring for readability. setjmp/longjmp for escape from deeply nested errors.

git-subtree-dir: lispBM/lispBM
git-subtree-split: c097f5c66bd539442a48d41a66da1c657af502a1
  • Loading branch information
vedderb committed May 22, 2023
1 parent a39b0a9 commit d664184
Show file tree
Hide file tree
Showing 34 changed files with 901 additions and 1,031 deletions.
128 changes: 0 additions & 128 deletions CODE_OF_CONDUCT.md

This file was deleted.

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ what we call "extensions" which are C functions that can be called from your Lis
### Documentation

- Work in progress [LispBM language reference](./doc/lbmref.md).
- Work in progress [LispBM programming manual](./doc/manual)
- Gotchas and caveats [Gotchas and caveats](./doc/gotchas.md).
- Work in progress [LispBM programming manual](./doc/manual).
- C code documentation can be found [here](http://svenssonjoel.github.io/lbmdoc/html/index.html).
- LispBM's internals are documented as a series of [blog posts](http://svenssonjoel.github.io).
- There are [demonstrations on YouTube](https://youtube.com/playlist?list=PLtf_3TaqZoDOQqZcB9Yj-R1zS2DWDZ9q9).
Expand Down
1 change: 1 addition & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


[Language reference](./lbmref.md)
[Gotchas and caveats](./gotchas.md)


## Programming manual
Expand Down
50 changes: 50 additions & 0 deletions doc/gotchas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# LBM Gotchas and Caveats

This document collects caveats and gotchas as they are discovered. Hopefully these will
also be given efficient solutions at some points in which case the solution to that gotcha
will also be documented here.

If you find any more gotchas, please let me know how to trigger them! Would be much appreciated.

## Environment

In LBM there is a global environment which is an association list of `(symbol . value)` pairs.
There is also a local environment that is carried along in the evaluator while evaluating
expressions. This local environment is also an association list `(symbol . value)` pairs.

### Closure Gotcha!

When a closure is created, a reference to the local environment is stored in the closure object.
This is for efficiency reasons as traversing the expression and pulling in all free variables
would be a somewhat costly operation (order of the size of the expression) while saving a reference
to the local environment is an O(1) operation. This essentially trades some space (as it potentially
prohibits GC from removing some dead values during the life-time of that closure) for improved performance.

Note that the global environment is not "saved" in the same way inside the closure. Given that
`undefine` exists in LBM, this is a potential foot-gun as illustrated by the example below:

```clj
# (define a 10)
> 10
# (define f (lambda (x) (+ x a)))
> (closure (x) (+ x a) nil)
# (undefine 'a)
> ((f closure (x) (+ x a) nil))
# (f 1)
*** Error: variable_not_bound
*** a
#
*** Between rows: (-1 unknown)
*** Start: -1
*** End: -1
#
> variable_not_bound
#
```

Currently no (efficient) solution in mind for this gotcha. Just be careful if you use `undefine`.





96 changes: 95 additions & 1 deletion doc/lbmref.md
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ Example that moves an array to flash storage:
(define a [1 2 3 4 5 6])

(move-to-flash a)
---
```

Example that moves a list to flash storage:

Expand All @@ -1013,6 +1013,66 @@ Functions can be moved to flash storage as well:
(move-to-flash f)
```

### make-env

The `make-env` form allows you to create an environment as a value.
The form of an `make-env` expression is `(make-env exp)`. When
The result of running `(make-env exp)` is the resulting environment after
evaluating the expression `exp`. The resulting environment is an association list.

`make-env` can be used to encapsulate a set of bindings under a name.

Example:

```clj
(define my-env (make-env {
(defun f (x) (+ x 1))
(defun g (x y) (+ x y))
}))
```

See `in-env` for how to evaluate expressions inside of a provided environment.

---


### in-env

The `in-env` form allows the evaluation in an environment that has
been augmented by an environment (association list) provided.
The form of an `in-env` expression is `(in-env env-expr expr)`. Here the
expression `expr` is evaluated with the local environemnt augmented with
the result of `env-expr`. The resulting environment of a `make-env` application
is compatible with the `env-expr` of `in-env` but any association list is ok.

Example:

```clj
(define my-env '( (a . 10) (b . 20)))

(in-env my-env (+ a b))
```

The example above evaluates to 30.

Example combining `in-env` and `make-env`:

```clj
(define lib
(make-env {
(define a 10)
(define b 20)
(define c 30)
}))


(in-env lib (+ a b))
```



---

## Lists and cons cells

Lists are built using cons cells. A cons cell is represented by the lbm_cons_t struct in the
Expand Down Expand Up @@ -1252,6 +1312,40 @@ Now change the value in the cdr field of apa to 42.
```
The `apa` pair is now `(1 . 42)`.

---

### take

`take` creates a list containing the `n` first elements of another list.
The form of a `take` expression is `(take n-exp list-exp)`.

Example that takes 5 elements from a list:
```clj
(define ls (list 1 2 3 4 5 6 7 8 9 10))

(take 5 ls)
```

In the example above, the result of `(take 5 ls)` is `(1 2 3 4 5)`.

---

### drop

`drop` creates a list from another list by dropping the `n` first elements of that list.
The form of a `drop` expression is `(drop n-exp list-exp)`.

Example that drops 5 elements from a list:
```clj
(define ls (list 1 2 3 4 5 6 7 8 9 10))

(drop 5 ls)
```

Here `(drop 5 ls)` evaluates to the list `(6 7 8 9 10)`.

---

## Associations lists (alists)

Association lists (alists) are, just like regular lists, built out
Expand Down
4 changes: 2 additions & 2 deletions examples/profile.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/bin/bash


valgrind --tool=callgrind --callgrind-out-file=cg.out ${*:1}
valgrind --toggle-collect=lbm_run_eval --tool=callgrind --callgrind-out-file=cg.out ${*:1}

gprof2dot -f callgrind cg.out -o cg.dot
gprof2dot -f callgrind cg.out -o cg.dot

dot -Tpdf cg.dot -o cg.pdf

Expand Down
6 changes: 1 addition & 5 deletions include/eval_cps.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,6 @@ void lbm_set_printf_callback(int (*prnt)(const char*, ...));
* an undefined symbol
*/
void lbm_set_dynamic_load_callback(bool (*fptr)(const char *, const char **));
/** Set a callback that is run when reading source is finishes
* within a context
*/
void lbm_set_reader_done_callback(void (*fptr)(lbm_cid));
/** Get the CID of the currently executing context.
* Should be called from an extension where there is
* a guarantee that a context is running
Expand All @@ -326,7 +322,7 @@ bool create_string_channel(char *str, lbm_value *res);
bool lift_char_channel(lbm_char_channel_t *ch, lbm_value *res);

lbm_flash_status request_flash_storage_cell(lbm_value val, lbm_value *res);
bool lift_array_flash(lbm_value flash_cell, char *data, lbm_uint num_elt);
//bool lift_array_flash(lbm_value flash_cell, char *data, lbm_uint num_elt);

/** deliver a message
*
Expand Down
15 changes: 12 additions & 3 deletions include/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,11 @@ lbm_uint lbm_heap_size_bytes(void);
/** Allocate an lbm_cons_t cell from the heap.
*
* \param type A type that can be encoded onto the cell (most often LBM_PTR_TYPE_CONS).
* \param car Value to write into car position of allocated cell.
* \param cdr Value to write into cdr position of allocated cell.
* \return An lbm_value referring to a cons_cell or enc_sym(SYM_MERROR) in case the heap is full.
*/
lbm_value lbm_heap_allocate_cell(lbm_type type);
lbm_value lbm_heap_allocate_cell(lbm_type type, lbm_value car, lbm_value cdr);
/** Allocate a list of n heap-cells.
* \param n The number of heap-cells to allocate.
* \return A list of heap-cells of Memory error if unable to allocate.
Expand Down Expand Up @@ -427,7 +429,7 @@ lbm_value lbm_car(lbm_value cons);
/** Accesses the car field the car field of an lbm_cons_t.
*
* \param cons Value
* \return The car of car field or nil.
* \return The car of car field or nil.
*/
lbm_value lbm_caar(lbm_value c);
/** Accesses the car of the cdr of an cons cell
Expand Down Expand Up @@ -513,10 +515,11 @@ lbm_value lbm_list_destructive_reverse(lbm_value list);
* \warning This is a dangerous function that should be used carefully. Cyclic structures on the heap
* may lead to the function not terminating.
*
* \param m Number of elements to copy or -1 for all.
* \param list A list.
* \return Reversed list or enc_sym(SYM_MERROR) if heap is full.
*/
lbm_value lbm_list_copy(lbm_value list);
lbm_value lbm_list_copy(int m, lbm_value list);

/** A destructive append of two lists
*
Expand All @@ -526,6 +529,12 @@ lbm_value lbm_list_copy(lbm_value list);
*/
lbm_value lbm_list_append(lbm_value list1, lbm_value list2);

/** Drop values from the head of a list.
* \param n Number of values to drop.
* \param ls List to drop values from.
* \return The list with the n first elements removed.
*/
lbm_value lbm_list_drop(unsigned int n, lbm_value ls);

// State and statistics
/** Get a copy of the heap statistics structure.
Expand Down
Loading

0 comments on commit d664184

Please sign in to comment.