From fb23b204735e7395c238947548d07c93875f2e19 Mon Sep 17 00:00:00 2001 From: VaclavT Date: Wed, 17 Feb 2021 00:10:10 +0100 Subject: [PATCH] docs updates --- Readme.md | 3 +- doc/Doc.md | 109 ------------------------------------- doc/Wisp.md | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 110 deletions(-) create mode 100644 doc/Wisp.md diff --git a/Readme.md b/Readme.md index b8ce95f..353d24b 100644 --- a/Readme.md +++ b/Readme.md @@ -2,7 +2,6 @@ ### TODO - date support - decode-universal-time -- add save-csv - logical operators - documentation - add url of source/inspiration to clib/*.cpp @@ -28,6 +27,8 @@ - add support for nil - conversion functions like parse-integer - list function nth +- in test.lisp some explaining prints +- rename data.csv and add more tickers #### Performance diff --git a/doc/Doc.md b/doc/Doc.md index dcd03b8..de64f23 100644 --- a/doc/Doc.md +++ b/doc/Doc.md @@ -1,65 +1,6 @@ -# wisp - -A light lisp written in C++ -![Wisp](./wisp.png) - -## Why write a lisp? - -Lisp is one of those niche, beautiful languages that people only really use to either - -1. Write a lisp interpreter -2. Show off how "code is data!!!" - -_So why add to the list of infinite lisp interpreters?_ - -The answer is simple: _**I'm bored out of my mind in quarantine.**_ If you were looking to find out why _this particular_ lisp is special, you're fresh out of luck. - ## Syntax and Special Forms -Like every other lisp, this language uses s-expressions for code syntax and data syntax. So, for example, the s-expression `(print 5)` is both a valid code snippet, and a valid list containing the items `print` and `5`. - -When the data `(print 5)` is evaluated by the interpreter, it evaluates `print` and `5`, and then applies `print` to `5`. - -Here's the result. - -```lisp ->>> (print 5) -5 - => 5 -``` - -That's super cool! But what if we want to define our own functions? _We can use the builtin function `defun`!_ - -```lisp -; define a function `fact` that takes an argument `n` -(defun fact (n) - (if (<= n 1) - 1 - (* n (fact (- n 1))) - )) -``` - -Thats awesome! But did you notice anything different about the `defun` function? _It doesn't evaluate its arguments._ If the atom `fact` were evaluated, it would throw an error like so: - -```lisp ->>> fact -error: the expression `fact` failed in scope { } with message "atom not defined" -``` - -This is known as a special form, where certain functions "quote" their arguments. We can quote things ourselves too, but the language _automatically_ quotes arguments to special forms itself. - -If you want to "quote" a value yourself, you can do it like this. - -```lisp -; quote the s-expression (1 2 3) so it's not evaluated ->>> (print '(1 2 3)) -(1 2 3) - => (1 2 3) -``` - -As you can see, quote negates an evaluation. For example, whenever the expression `''a` is evaluated, it becomes `'a`. This can be useful for when you want to write long lists of data or variable names without wanting to evaluate them as code. - |Special Form|Argument Evaluations|Purpose| |:-|-|-| |`(if cond a b)`|`if` only evaluates its `cond` argument. If `cond` is truthy (non-zero), then `a` is evaluated. Otherwise, `b` is evaluated.|This special form is the main method of control flow.| @@ -75,52 +16,6 @@ As you can see, quote negates an evaluation. For example, whenever the expressio ## Examples -Here are some example math-y functions to wrap your head around. - -```lisp -; quicksort -(defun qs (l) - (if (<= (len l) 1) - l - (do - (define pivot (first l)) - (+ - (qs (filter (lambda (n) (> pivot n)) l)) - (list pivot) - (qs (tail (filter (lambda (n) (<= pivot n)) l))) - )) - )) - -; decrement a number -(defun dec (n) (- n 1)) -; increment a number -(defun inc (n) (+ n 1)) -; not a bool -(defun not (x) (if x 0 1)) - -; negate a number -(defun neg (n) (- 0 n)) - -; is a number positive? -(defun is-pos? (n) (> n 0)) -; is a number negative? -(defun is-neg? (n) (< n 0)) -``` - -## Usage - -Using and compiling wisp - -#### Dependencies - -Compile with your C++ compiler of choice. This is compatible with all standard versions of C++ since ANSI C++. - -```bash -$ git clone https://github.com/adam-mcdaniel/wisp -$ cd wisp -$ g++ wisp.cpp -o wisp -``` - #### Using the binary Run wisp in interactive mode: @@ -145,7 +40,3 @@ Interpret from command line argument: $ ./wisp -c '(print "Hello world!")' Hello world! ``` - - -source from : -https://github.com/adam-mcdaniel/wisp diff --git a/doc/Wisp.md b/doc/Wisp.md new file mode 100644 index 0000000..dcd03b8 --- /dev/null +++ b/doc/Wisp.md @@ -0,0 +1,151 @@ +# wisp + +A light lisp written in C++ +![Wisp](./wisp.png) + +## Why write a lisp? + +Lisp is one of those niche, beautiful languages that people only really use to either + +1. Write a lisp interpreter +2. Show off how "code is data!!!" + +_So why add to the list of infinite lisp interpreters?_ + +The answer is simple: _**I'm bored out of my mind in quarantine.**_ If you were looking to find out why _this particular_ lisp is special, you're fresh out of luck. + + +## Syntax and Special Forms + +Like every other lisp, this language uses s-expressions for code syntax and data syntax. So, for example, the s-expression `(print 5)` is both a valid code snippet, and a valid list containing the items `print` and `5`. + +When the data `(print 5)` is evaluated by the interpreter, it evaluates `print` and `5`, and then applies `print` to `5`. + +Here's the result. + +```lisp +>>> (print 5) +5 + => 5 +``` + +That's super cool! But what if we want to define our own functions? _We can use the builtin function `defun`!_ + +```lisp +; define a function `fact` that takes an argument `n` +(defun fact (n) + (if (<= n 1) + 1 + (* n (fact (- n 1))) + )) +``` + +Thats awesome! But did you notice anything different about the `defun` function? _It doesn't evaluate its arguments._ If the atom `fact` were evaluated, it would throw an error like so: + +```lisp +>>> fact +error: the expression `fact` failed in scope { } with message "atom not defined" +``` + +This is known as a special form, where certain functions "quote" their arguments. We can quote things ourselves too, but the language _automatically_ quotes arguments to special forms itself. + +If you want to "quote" a value yourself, you can do it like this. + +```lisp +; quote the s-expression (1 2 3) so it's not evaluated +>>> (print '(1 2 3)) +(1 2 3) + => (1 2 3) +``` + +As you can see, quote negates an evaluation. For example, whenever the expression `''a` is evaluated, it becomes `'a`. This can be useful for when you want to write long lists of data or variable names without wanting to evaluate them as code. + +|Special Form|Argument Evaluations|Purpose| +|:-|-|-| +|`(if cond a b)`|`if` only evaluates its `cond` argument. If `cond` is truthy (non-zero), then `a` is evaluated. Otherwise, `b` is evaluated.|This special form is the main method of control flow.| +|`(do a b c ...)`|`do` takes a list of s-expressions and evaluates them in the order they were given (in the current scope), and then returns the result of the last s-expression.|This special form allows lambda functions to have multi-step bodies.| +|`(scope a b c ...)`|`scope` takes a list of s-expressions and evaluates them in the order they were given _in a new scope_, and then returns the result of the last s-expression.|This special form allows the user to evaluate blocks of code in new scopes.| +|`(defun name params body)`|`defun` evaluates none of its arguments.|This special form allows the user to conveniently define functions.| +|`(define name value)`|`define` evaluates the `value` argument, which is then assigned to `name` in the current scope.|This special form allows the user to bind atoms to values in a scope.| +|`(lambda params body)`|`lambda` evaluates none of its arguments.|This special form allows the user to define anonymous functions.| +|`(quote x)`|`quote` evaluates none of its arguments.|This is equivalent to the `'expr` syntactic sugar.| +|`(for x list ...)`|`for` evaluates only its list argument.|`for` iterates through the list storing each element in `x`, and then evaluating all of the rest of the values in the `for` body. It then returns the last value evaluated.| +|`(while cond ...)`|`while` evaluates only its cond argument.|`while` evaluates its condition expression every iteration before running. If it is true, it continues to evaluate every expression in the `while` body. It then returns the last value evaluated.| + + +## Examples + +Here are some example math-y functions to wrap your head around. + +```lisp +; quicksort +(defun qs (l) + (if (<= (len l) 1) + l + (do + (define pivot (first l)) + (+ + (qs (filter (lambda (n) (> pivot n)) l)) + (list pivot) + (qs (tail (filter (lambda (n) (<= pivot n)) l))) + )) + )) + +; decrement a number +(defun dec (n) (- n 1)) +; increment a number +(defun inc (n) (+ n 1)) +; not a bool +(defun not (x) (if x 0 1)) + +; negate a number +(defun neg (n) (- 0 n)) + +; is a number positive? +(defun is-pos? (n) (> n 0)) +; is a number negative? +(defun is-neg? (n) (< n 0)) +``` + +## Usage + +Using and compiling wisp + +#### Dependencies + +Compile with your C++ compiler of choice. This is compatible with all standard versions of C++ since ANSI C++. + +```bash +$ git clone https://github.com/adam-mcdaniel/wisp +$ cd wisp +$ g++ wisp.cpp -o wisp +``` + +#### Using the binary + +Run wisp in interactive mode: + +```bash +$ ./wisp +>>> (print "Hello world!") +Hello world! + => "Hello world!" +``` + +Interpret a file: + +```bash +$ ./wisp -f "examples/hello_world.lisp" +Hello world! +``` + +Interpret from command line argument: + +```bash +$ ./wisp -c '(print "Hello world!")' +Hello world! +``` + + +source from : +https://github.com/adam-mcdaniel/wisp