Eval enhancements. Rewrote store to be significantly better

This commit is contained in:
Ava Apples Affine 2023-03-17 11:42:36 -07:00
parent 20821057f2
commit 3848d3bcfa
Signed by: affine
GPG key ID: 3A4645B8CF806069
6 changed files with 363 additions and 327 deletions

View file

@ -317,9 +317,10 @@ It is sort of like a lint roller.
It also contains considerably subpar implementations of Relish's internals that are kept around for historical reasons.
** Easy patterns
This section can serve as a sort of cookbook for a user who is new to leveraging LISP languages or unsure of where to start with ~relish~.
This section contains examples of common composites of control flow that can be used to build more complex or effective applications
More ideas may be explored in the file:snippets directory of this project.
The author encourages any users to contribute their own personal favorites not already in this section either by adding them to the file:snippets folder, or to extend the documentation here.
*** while-let combo
#+BEGIN_SRC lisp
;; myiter = (1 (2 3 4 5 6))
@ -334,15 +335,7 @@ The author encourages any users to contribute their own personal favorites not a
#+END_SRC
The while-let pattern can be used for many purposes. Above it is used to iterate over elements in a list. It can also be used to receive connections to a socket and write data to them.
*** TODO main loop application
- state switch (while-toggle)
- state calculation
*** TODO callback model via eval and passed-in functions
*** TODO quote/eval for pseudo-anonymous pseudo-functions
*** TODO short-circuit guard
- circuit example
- while-not-circuit-do-more-work
*** TODO shell capabilities check
*** let destructuring
~let~ is very useful for destructuring complex return types. If you have a function that may return a whole list of values you can then call it from ~let~ to consume the result data.
In this example a let form is used to destructure a call to ~head~. ~head~ returns a list consisting of ~(first-element rest-of-list)~ (for more information see ~(help head)~).
@ -356,6 +349,7 @@ Finally, the bodies evaluated in the ~let~ form are able to operate on the head
(echo "this is 1: " first)
(echo "this is 2, 3: " rest))
#+END_SRC
*** if-set?
One common pattern seen in bash scripts and makefiles is the set-variable-if-not-set pattern.
#+BEGIN_SRC shell
@ -421,11 +415,10 @@ Variables and functions defined in an external script loaded by your interpreter
cargo run src/bin/main.rs
#+END_SRC
* Guide to codebase
* The codebase
** file:tests directory
Start here if you are new.
Most of these files have unimplemented tests commented out in them.
Contributions that help fill out all of these tests
*** Eval tests: file:tests/test_eval.rs
These are particularly easy to read and write tests.
@ -436,23 +429,24 @@ You can consider these to extend the eval tests to cover the co-recursive nature
These tests verify the handling of syntax.
*** Lib tests: (tests/test_lib*)
These tests are unique per stdlib module.
These tests are unique per stdlib module and work to prove the functionality of builtin functions in the language.
** file:src directory
This directory contains all of the user facing code in relish.
Just a few entries of note:
*** segment: file:src/segment.rs
This file lays out the +spiritual+ +theological+ +ideological+ +theoretical+ mechanical underpinnings of the entire interpreter.
The entire LISP machine centers around a singlet or pairing of datum.
The ~Ctr~ datatype provides an abstraction for which any type of data, including a ~Seg~ can be a datum.
The ~Seg~ datatype provides a mechanism to hold a single datum or a pair of datum. It is implemented as two ~Ctr~s: ~car~ and ~cdr~.
A primitive type system is provided through the Rust Enum datatype. A number of utility functions follow.
This file lays out the data structures that the interpreter operates on.
Representation of code trees, traversals, and type annotations all live here.
*** lib: file:src/lib.rs
This defines a library that can be included to provide an interpreter interface within any Rust project.
It includes the core interpreter mechanisms, full stdlib, and the configuration system.
Your project can use or not use any number of these components. They can certainly be used to support language development for other LISP machines,
or even other languages.
The components defined here can certainly be used to support language development for other LISP (or non LISP) langauges.
Your project can use or not use any number of these components.
*** sym: file:src/sym.rs
This file contains all code related to symbol expansion and function calling.
The types defined in this file include SymTable, Args, Symbol, and more.
*** config: file:src/config.rs
This file contains default configuration values as well as functions which load and run the configuration file script.
@ -464,8 +458,8 @@ The ~static_stdlib~ function loads all symbols in the standard library which do
The ~dyanmic_stdlib~ function loads all symbols in the standard library which *do* need configuration into the symbol table.
The ~dynamic_stdlib~ function uses variables saved in the symbol table to configure the functions and variables it loads.
For more information see file:src/config.
Any new addition to the stdlib must make its way here to be included in the main shell (and any other shell using the included ~get_stdlib~ function).
You may choose to override these functions if you would like to include your own special functions in your own special interpreter, or if you would like to pare down the stdlib to a small minimal subet of what it is.
Any new addition to the stdlib must make its way here to be included in the main shell (and any other shell using the included stdlib functions).
You may choose to override these functions if you would like to include your own special functions in your own special interpreter, or if you would like to pare down the stdlib to a lighter subet of what it is.
You can view the code for standard library functions in file:src/stl/.
@ -476,20 +470,20 @@ This contains any executable target of this project. Notably the main shell file
Note: this section will not show the status of each item unless you are viewing it with a proper orgmode viewer.
Note: this section only tracks the state of incomplete TODO items. Having everything on here would be cluttered.
*** TODO set function
*** TODO list contains via circuit
*** TODO Input function
*** TODO Lex function
*** TODO Read function (Input + Lex)
*** TODO Caps function (list functions in table)
*** TODO Default prompt says "<minimum shell> LAMBDA:"
*** TODO Symbols defined within let by def statements must be pulled out and made global
*** TODO Def must eval args for symbol and doc
*** TODO Shell prompt is fully configurable (L, R, and Delim)
*** TODO Load (load a script) function
Pull/Refactor the logic out of the configure functions.
Optionally return a list of new variables and/or functions?
Will need a concatenate function for tables
*** TODO not-builtin set function
*** TODO not-builtin list contains
*** TODO Main shell calls Load function on arg and exits
*** TODO Ship a relish-based stdlib
*** TODO Map library written in relish ("slowmap")
*** TODO Input function
*** TODO Lex function
*** TODO Read function (Input + Lex)
*** TODO get type function
*** TODO FINISH DOCUMENTATION
*** TODO Shell module-
**** TODO only loadable via POSIX config var
@ -501,16 +495,16 @@ Overload Load function to call a binary too
**** TODO Foreground process TTY (fg function)
**** TODO list jobs (j function)
**** TODO ESSENTIAL: DOCUMENT POSIX MODULE
*** TODO Configurable RPROMPT
*** TODO logging library
*** TODO make const all the error messages
*** TODO Rename to Flesh
*** TODO Create a dedicated community channel on matrix.sunnypup.io
*** TODO Post to relevant channels
*** TODO Custom ast pretty print
*** TODO Implement Compose for lambdas
*** TODO Map function
- DOCUMENTATION + TEST:
apply a lambda to a list
*** TODO Reduce function
DOCUMENT AS WELL
*** TODO non built in Map function
*** TODO non built in Reduce function
*** TODO file operations
**** TODO read-to-string
**** TODO write-to-file