update links in readme
This commit is contained in:
parent
9631f84fc5
commit
eba113b034
1 changed files with 45 additions and 44 deletions
89
Readme.org
89
Readme.org
|
|
@ -7,8 +7,7 @@ Note: this document is best read using a dedicated ORG mode editor
|
||||||
The purpose of Relish is to create a highly portable, easy to integrate language that can be used in many environments.
|
The purpose of Relish is to create a highly portable, easy to integrate language that can be used in many environments.
|
||||||
|
|
||||||
* Goals
|
* Goals
|
||||||
- Iterate on the ideas and designs that were tested with SHS
|
- Iterate on the ideas and designs that were tested with [[https://gitlab.com/whom/shs][SHS]]
|
||||||
https://gitlab.com/whom/shs
|
|
||||||
- Create a usable POSIX shell
|
- Create a usable POSIX shell
|
||||||
- Create usable applications/scripts
|
- Create usable applications/scripts
|
||||||
- To have quality code coverage
|
- To have quality code coverage
|
||||||
|
|
@ -44,7 +43,7 @@ top-level -> element1 -> "element2" -> 3 -> [] -> [] ->
|
||||||
|
|
||||||
Each node in memory has type information and potentially a cooresponding entry in a global symbol table.
|
Each node in memory has type information and potentially a cooresponding entry in a global symbol table.
|
||||||
|
|
||||||
**** Data types
|
*** Data types
|
||||||
Relish leverages the following data types:
|
Relish leverages the following data types:
|
||||||
- Strings: delimited by ~'~, ~"~, or ~`~
|
- Strings: delimited by ~'~, ~"~, or ~`~
|
||||||
- Integers: up to 128 bit signed integers
|
- Integers: up to 128 bit signed integers
|
||||||
|
|
@ -55,7 +54,7 @@ Relish leverages the following data types:
|
||||||
Symbols and Functions can contain data of any type. there is no restriction on what can be set/passed to what.....
|
Symbols and Functions can contain data of any type. there is no restriction on what can be set/passed to what.....
|
||||||
However, internally Relish is typed, and many builtin functions will get very picky about what types are passed to them.
|
However, internally Relish is typed, and many builtin functions will get very picky about what types are passed to them.
|
||||||
|
|
||||||
**** Calling a function
|
*** Calling a function
|
||||||
S-Expressions can represent function calls in addition to trees of data. A function call is a list of data starting with a symbol that is defined to be a function:
|
S-Expressions can represent function calls in addition to trees of data. A function call is a list of data starting with a symbol that is defined to be a function:
|
||||||
#+BEGIN_SRC lisp
|
#+BEGIN_SRC lisp
|
||||||
(dothing arg1 arg2 arg3)
|
(dothing arg1 arg2 arg3)
|
||||||
|
|
@ -68,8 +67,8 @@ Function calls are executed as soon as the tree is evaluated. See the following
|
||||||
|
|
||||||
In this example, ~(add 5 2)~ is evaluated first, its result is then passed to ~(add 3 ...)~. In infix form: ~3 + (5 + 2)~.
|
In this example, ~(add 5 2)~ is evaluated first, its result is then passed to ~(add 3 ...)~. In infix form: ~3 + (5 + 2)~.
|
||||||
|
|
||||||
*** Control flow
|
** Control flow
|
||||||
**** If
|
*** If
|
||||||
An *if form* is the most basic form of conditional evaluation offered by Relish.
|
An *if form* is the most basic form of conditional evaluation offered by Relish.
|
||||||
It is a function that takes lazily evaluated arguments: a condition, a then clause, and an else clause.
|
It is a function that takes lazily evaluated arguments: a condition, a then clause, and an else clause.
|
||||||
If the condition evaluates to true, the then clause is evaluated and the result returned.
|
If the condition evaluates to true, the then clause is evaluated and the result returned.
|
||||||
|
|
@ -88,7 +87,7 @@ If the condition evaluates to neither true nor false (a non-boolean value) a typ
|
||||||
(turn-on-my-flag global-state))
|
(turn-on-my-flag global-state))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
**** While
|
*** While
|
||||||
Another popular control flow structure is the *while loop*.
|
Another popular control flow structure is the *while loop*.
|
||||||
This is implemented as a condition followed by one or more bodies that are lazily evaluated only if the condition is true.
|
This is implemented as a condition followed by one or more bodies that are lazily evaluated only if the condition is true.
|
||||||
Like the *if form*, if the conditional returns a non-boolean value the *while loop* will return an error.
|
Like the *if form*, if the conditional returns a non-boolean value the *while loop* will return an error.
|
||||||
|
|
@ -100,7 +99,7 @@ Like the *if form*, if the conditional returns a non-boolean value the *while lo
|
||||||
(toggle-my-flag global-state)) ;; this is also evaluated
|
(toggle-my-flag global-state)) ;; this is also evaluated
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
**** Let
|
*** Let
|
||||||
*Let* is one of the most powerful forms Relish offers. The first body in a call to let is a list of lists.
|
*Let* is one of the most powerful forms Relish offers. The first body in a call to let is a list of lists.
|
||||||
Specifically, a list of variable declarations that look like this: ~(name value)~.
|
Specifically, a list of variable declarations that look like this: ~(name value)~.
|
||||||
|
|
||||||
|
|
@ -122,7 +121,7 @@ Here you can see the usefulness of being able to declare multiple variables in q
|
||||||
Each variable is in scope for the duration of the let statement and then dropped when the statement has concluded.
|
Each variable is in scope for the duration of the let statement and then dropped when the statement has concluded.
|
||||||
Thus, it is little cost to break complex calculations down into reusable parts.
|
Thus, it is little cost to break complex calculations down into reusable parts.
|
||||||
|
|
||||||
**** Circuit
|
*** Circuit
|
||||||
*Circuit* is useful to run a sequence of commands in order.
|
*Circuit* is useful to run a sequence of commands in order.
|
||||||
A call to *circuit* comprises of one or more forms in a sequence.
|
A call to *circuit* comprises of one or more forms in a sequence.
|
||||||
All forms in the call to *circuit* are expected to evaluate to a boolean.
|
All forms in the call to *circuit* are expected to evaluate to a boolean.
|
||||||
|
|
@ -137,7 +136,7 @@ Example:
|
||||||
(eq? (some-big-calculation) expected-result))
|
(eq? (some-big-calculation) expected-result))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
**** Not quite control flow
|
*** Not quite control flow
|
||||||
Several other functions use lazy evaluation of their arguments. The below list is non-exhaustive:
|
Several other functions use lazy evaluation of their arguments. The below list is non-exhaustive:
|
||||||
- toggle
|
- toggle
|
||||||
- inc
|
- inc
|
||||||
|
|
@ -227,7 +226,7 @@ Here is the lambda bound to a variable inside a let statement:
|
||||||
(adder 1 2)) ;; local var (the lambda 'adder') called here
|
(adder 1 2)) ;; local var (the lambda 'adder') called here
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** Defining variables and functions
|
** Defining variables and functions
|
||||||
In Relish, both variables and functions are stored in a table of symbols.
|
In Relish, both variables and functions are stored in a table of symbols.
|
||||||
All Symbols defined with ~def~ are *GLOBAL*. The only cases when symbols are local is when they are defined as part of *let* forms or as arguments to functions.
|
All Symbols defined with ~def~ are *GLOBAL*. The only cases when symbols are local is when they are defined as part of *let* forms or as arguments to functions.
|
||||||
In order to define a symbol, the following arguments are required:
|
In order to define a symbol, the following arguments are required:
|
||||||
|
|
@ -250,13 +249,13 @@ In this case, the value derived from the final form in the function will be retu
|
||||||
|
|
||||||
Make sure to read the *Configuration* section for information on how symbols are linked to environment variables.
|
Make sure to read the *Configuration* section for information on how symbols are linked to environment variables.
|
||||||
|
|
||||||
**** Naming conventions
|
*** Naming conventions
|
||||||
- Symbol names are case sensitive
|
- Symbol names are case sensitive
|
||||||
- Symbols may contain alphanumeric characters
|
- Symbols may contain alphanumeric characters
|
||||||
- Symbols may contain one or more of the following: ~- _ ?~
|
- Symbols may contain one or more of the following: ~- _ ?~
|
||||||
- The idiomatic way to name symbols is ~all-single-case-and-hyphenated~
|
- The idiomatic way to name symbols is ~all-single-case-and-hyphenated~
|
||||||
|
|
||||||
**** Undefining variables and functions
|
*** Undefining variables and functions
|
||||||
Removing a symbol consists of a call to ~def~ with no additional arguments:
|
Removing a symbol consists of a call to ~def~ with no additional arguments:
|
||||||
|
|
||||||
#+BEGIN_SRC lisp
|
#+BEGIN_SRC lisp
|
||||||
|
|
@ -270,14 +269,13 @@ Removing a symbol consists of a call to ~def~ with no additional arguments:
|
||||||
As opposed to listing every builtin function here, it is suggested to the user to do one of two things:
|
As opposed to listing every builtin function here, it is suggested to the user to do one of two things:
|
||||||
- Call ~env~ from a fresh shell: ~(env)~
|
- Call ~env~ from a fresh shell: ~(env)~
|
||||||
This will output all variables and functions defined
|
This will output all variables and functions defined
|
||||||
- Read the std library declaration code:
|
- Read the [[file:src/stl.rs][std library declaration code]]
|
||||||
file:src/stl.rs
|
|
||||||
|
|
||||||
** Documentation
|
** Documentation
|
||||||
*** Tests
|
*** Tests
|
||||||
Most of the tests evaluate small scripts (single forms) and check their output.
|
Most of the tests evaluate small scripts (single forms) and check their output.
|
||||||
Perusing them may yield answers on all the cases a given builtin can handle.
|
Perusing them may yield answers on all the cases a given builtin can handle.
|
||||||
file:tests/
|
[[file:tests][The test directory]]
|
||||||
|
|
||||||
*** Help function
|
*** Help function
|
||||||
Relish is self documenting. The *help* function can be used to inspect any variable or function.
|
Relish is self documenting. The *help* function can be used to inspect any variable or function.
|
||||||
|
|
@ -320,12 +318,13 @@ It also contains considerably subpar implementations of Relish's internals that
|
||||||
|
|
||||||
*** Userlib
|
*** Userlib
|
||||||
The *Userlib* was added as a script containing many valuable functions such as ~set~ and ~prepend~.
|
The *Userlib* was added as a script containing many valuable functions such as ~set~ and ~prepend~.
|
||||||
You can use it by calling it in your shell config (See file:snippets/basic_minimal_configuration.rls for more info).
|
You can use it by calling it in your shell config
|
||||||
|
(See [[file:snippets/basic_minimal_configuration.rls][The minimal shell configuration example]] for more info).
|
||||||
|
|
||||||
** Easy patterns
|
** Easy patterns
|
||||||
This section contains examples of common composites of control flow that can be used to build more complex or effective applications
|
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.
|
More ideas may be explored in the [[file:snippets][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.
|
The author encourages any users to contribute their own personal favorites not already in this section either by adding them to the [[file:snippets][snippets]] folder, or to extend the documentation here.
|
||||||
|
|
||||||
*** while-let combo
|
*** while-let combo
|
||||||
#+BEGIN_SRC lisp
|
#+BEGIN_SRC lisp
|
||||||
|
|
@ -378,12 +377,12 @@ Alternatively this combination can be used to process flags in a script or appli
|
||||||
|
|
||||||
** Configuration
|
** Configuration
|
||||||
By default Relish will read from ~/.relishrc for configuration, but the default shell will also accept a filename from the RELISH_CFG_FILE environment variable.
|
By default Relish will read from ~/.relishrc for configuration, but the default shell will also accept a filename from the RELISH_CFG_FILE environment variable.
|
||||||
See file:snippets/basic_minimal_configuration.rls for an example of a basic minimal configuration file.
|
See [[file:snippets/basic_minimal_configuration.rls][the minimal shell configuration example]] for an example of a basic configuration file.
|
||||||
Other snippets, including mood-prompt and avas-laptop-prompt demonstrate more complex configurations.
|
Other snippets, including mood-prompt and avas-laptop-prompt demonstrate more complex configurations.
|
||||||
|
|
||||||
*** The configuration file
|
*** The configuration file
|
||||||
The configuration file is a script containing arbitrary Relish code.
|
The configuration file is a script containing arbitrary Relish code.
|
||||||
On start, any shell which leverages the configuration code in the config module (file:src/config.rs) will create a clean seperate context, including default configuration values, within which the standard library will be initialized.
|
On start, any shell which leverages the configuration code in the config module ([[file:src/run.rs][run.rs]]) will create a clean seperate context, including default configuration values, within which the standard library will be initialized.
|
||||||
The configuration file is evaluated and run as a standalone script and may include arbitrary executable code.
|
The configuration file is evaluated and run as a standalone script and may include arbitrary executable code.
|
||||||
Afterwards, configuration values found in the variable map will be used to configure the standard library function mappings that the shell will use.
|
Afterwards, configuration values found in the variable map will be used to configure the standard library function mappings that the shell will use.
|
||||||
Errors during configuration are non-terminal. In such a case any defaults which have not been overwritten will remain present.
|
Errors during configuration are non-terminal. In such a case any defaults which have not been overwritten will remain present.
|
||||||
|
|
@ -402,8 +401,8 @@ Errors during configuration are non-terminal. In such a case any defaults which
|
||||||
- CFG_RELISH_PROMPT_DELIMITER (default '>'): a function that is called with no arguments to output the delimiter separating prompt from user input
|
- CFG_RELISH_PROMPT_DELIMITER (default '>'): a function that is called with no arguments to output the delimiter separating prompt from user input
|
||||||
|
|
||||||
*** Prompt design
|
*** Prompt design
|
||||||
For an example of prompt design see file:snippets/mood-prompt.rls
|
For an example of prompt design see [[file:snippets/mood-prompt.rls][the mood prompt]]
|
||||||
For a more complex example see file:snippets/avas-laptop-prompt.rls
|
For a more complex example see [[file:snippets/avas-laptop-prompt.rls][Ava's laptop prompt]]
|
||||||
|
|
||||||
*** Further configuration
|
*** Further configuration
|
||||||
Further configuration can be done by loading scripts that contain more functions and data to evaluate.
|
Further configuration can be done by loading scripts that contain more functions and data to evaluate.
|
||||||
|
|
@ -415,7 +414,7 @@ Variables and functions defined in an external script loaded by your interpreter
|
||||||
|
|
||||||
** Using Relish as your shell
|
** Using Relish as your shell
|
||||||
As of version 0.3.0 Relish implements all the features of an interactive shell.
|
As of version 0.3.0 Relish implements all the features of an interactive shell.
|
||||||
See further documentation in file:Shell.org.
|
See further documentation in [[file:Shell.org][the shell documentation]].
|
||||||
|
|
||||||
** Compilation
|
** Compilation
|
||||||
#+BEGIN_SRC sh
|
#+BEGIN_SRC sh
|
||||||
|
|
@ -433,55 +432,57 @@ See further documentation in file:Shell.org.
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
* The codebase
|
* The codebase
|
||||||
** file:tests directory
|
** The [[file:tests][tests directory]]
|
||||||
Start here if you are new.
|
Start here if you are new.
|
||||||
|
|
||||||
*** Eval tests: file:tests/test_eval.rs
|
*** [[file:tests/test_eval.rs][Eval tests]]
|
||||||
These are particularly easy to read and write tests.
|
These are particularly easy to read and write tests.
|
||||||
|
They primarily cover execution paths in the evaluation process.
|
||||||
|
|
||||||
*** Func tests: file:tests/test_func.rs
|
*** [[file:tests/test_func.rs][Func tests]]
|
||||||
You can consider these to extend the eval tests to cover the co-recursive nature between eval and func calls.
|
These tests extend the eval tests to cover the co-recursive nature between eval and func calls.
|
||||||
|
|
||||||
*** Lex tests: file:tests/test_lex.rs
|
*** [[file:tests/test_lex.rs][Lex tests]]
|
||||||
These tests verify the handling of syntax.
|
These tests verify the handling of syntax.
|
||||||
|
|
||||||
*** Lib tests: (tests/test_lib*)
|
*** Lib tests: (tests/test_lib*)
|
||||||
These tests are unique per stdlib module and work to prove the functionality of builtin functions in the language.
|
These tests are unique per stdlib module and work to prove the functionality of builtin functions in the language.
|
||||||
|
|
||||||
** file:src directory
|
** [[file:src][Source directory]]
|
||||||
This directory contains all of the user facing code in relish.
|
This directory contains all of the user facing code in relish.
|
||||||
|
|
||||||
Just a few entries of note:
|
Just a few entries of note:
|
||||||
*** segment: file:src/segment.rs
|
*** [[file:src/segment.rs][Segment module]]
|
||||||
This file lays out the data structures that the interpreter operates on.
|
This file lays out the data structures that the interpreter operates on.
|
||||||
Representation of code trees, traversals, and type annotations all live here.
|
Representation of code trees, traversals, and type annotations all live here.
|
||||||
|
|
||||||
*** lib: file:src/lib.rs
|
*** [[file:src/lib.rs][lib.rs]]
|
||||||
This defines a library that can be included to provide an interpreter interface within any Rust project.
|
This defines a library that can be included to provide an interpreter interface within any Rust project.
|
||||||
The components defined here can certainly be used to support language development for other LISP (or non LISP) langauges.`
|
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.
|
Your project can use or not use any number of these components.
|
||||||
|
|
||||||
*** sym: file:src/sym.rs
|
*** [[file:src/sym.rs][Symbol module]]
|
||||||
This file contains all code related to symbol expansion and function calling.
|
This file contains all code related to symbol expansion and function calling.
|
||||||
The types defined in this file include SymTable, Args, Symbol, and more.
|
The types defined in this file include SymTable, Args, Symbol, and more.
|
||||||
|
Code to call Lambda functions also exists in here.
|
||||||
|
|
||||||
*** config: file:src/config.rs
|
*** [[file:src/run.rs][Run module]]
|
||||||
This file contains default configuration values as well as functions which load and run the configuration file script.
|
This file contains functions which load and run the configuration file script.
|
||||||
For more information see the configuraiton section above in this Readme.
|
For more information see the configuraiton section above in this Readme.
|
||||||
|
|
||||||
*** stl: file:src/stl.rs
|
*** [[file:src/stl.rs][Standard library module]]
|
||||||
This defines the ~static_stdlib~ function and the ~dynamic_stdlib~ function.
|
This defines the ~static_stdlib~ function and the ~dynamic_stdlib~ function.
|
||||||
The ~static_stdlib~ function loads all symbols in the standard library which do not need further configuration into the symbol table.
|
The ~static_stdlib~ function loads all symbols in the standard library which do not need further configuration into the symbol table.
|
||||||
The ~dyanmic_stdlib~ function loads all symbols in the standard library which *do* need configuration into the symbol table.
|
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.
|
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.
|
This file also contains default configuration values.
|
||||||
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).
|
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 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/.
|
You can view the code for standard library functions in [[file:src/stl/][the standard library directory]].
|
||||||
|
|
||||||
*** bin: file:src/bin/
|
*** [[file:src/bin/][binary directory]]
|
||||||
This contains any executable target of this project. Notably the main shell file:src/bin/main.rs.
|
This contains any executable target of this project. Notably [[file:src/bin/relish.rs][the main shell]].
|
||||||
|
|
||||||
* Current Status / TODO list
|
* Current Status / TODO list
|
||||||
Note: this section will not show the status of each item unless you are viewing it with a proper orgmode viewer.
|
Note: this section will not show the status of each item unless you are viewing it with a proper orgmode viewer.
|
||||||
|
|
@ -490,7 +491,7 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt
|
||||||
** TODO alpha tasks
|
** TODO alpha tasks
|
||||||
- exit function (causes program to shut down and return code)
|
- exit function (causes program to shut down and return code)
|
||||||
- probably push the symtable inserts into functions in individual stl modules (like posix.rs does)
|
- probably push the symtable inserts into functions in individual stl modules (like posix.rs does)
|
||||||
- fix the links in the readme like the ones in shell.org
|
- tag and release v0.3.0
|
||||||
|
|
||||||
** TODO v1.0 tasks
|
** TODO v1.0 tasks
|
||||||
- Be able to use features to compile without env or posix stuff
|
- Be able to use features to compile without env or posix stuff
|
||||||
|
|
@ -498,7 +499,7 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt
|
||||||
- I think you'll need to refactor userlib to hide set behind a conditional
|
- I think you'll need to refactor userlib to hide set behind a conditional
|
||||||
based on whether CFG_RELISH_POSIX is set or not
|
based on whether CFG_RELISH_POSIX is set or not
|
||||||
- add a compilation task to CI
|
- add a compilation task to CI
|
||||||
- finish basic goals in file:snippets/interactive-devel.rls
|
- finish basic goals in the [[file:snippets/interactive-devel.rls][interactive development library]]
|
||||||
- Investigate has_next member function for &Seg and maybe simplify stdlib and probably also eval/sym
|
- Investigate has_next member function for &Seg and maybe simplify stdlib and probably also eval/sym
|
||||||
- Rename to Flesh
|
- Rename to Flesh
|
||||||
- Can pass args to relish scripts (via interpreter)
|
- Can pass args to relish scripts (via interpreter)
|
||||||
|
|
@ -510,7 +511,7 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt
|
||||||
- Make an icon if you feel like it
|
- Make an icon if you feel like it
|
||||||
|
|
||||||
** TODO v1.1 tasks (Stable 1)
|
** TODO v1.1 tasks (Stable 1)
|
||||||
- finish stretch goals in file:snippets/interactive-devel.rls
|
- finish stretch goals in the [[file:snippets/interactive-devel.rls][interactive development library]]
|
||||||
- execute configurable function on cd
|
- execute configurable function on cd
|
||||||
- Post to relevant channels
|
- Post to relevant channels
|
||||||
- Implement Compose for lambdas
|
- Implement Compose for lambdas
|
||||||
|
|
@ -538,4 +539,4 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt
|
||||||
- UDP Listener
|
- UDP Listener
|
||||||
|
|
||||||
* Special thanks
|
* Special thanks
|
||||||
Special thanks to [[https://nul.srht.site/]['Underscore Nul']] for consulting with me in the early stages of this project. Meeting my goal of only using safe rust (with the exception of the posix module) would have been a much bigger challenge if not for having someone to experiment with design ideas with.
|
Special thanks to [[https://nul.srht.site/]['Underscore Nul']] for consulting with me in the early stages of this project. Meeting my goal of only using safe rust (with the exception of the posix module) would have been a much bigger challenge if not for having someone to experiment on design ideas with.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue