From f093ad4d4f6650119793976e8a912215ed5c36fc Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 29 Oct 2022 10:56:48 +0200 Subject: [PATCH 01/12] Update documentation --- doc/lisp.md | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/doc/lisp.md b/doc/lisp.md index 48df2d45..07cb797a 100644 --- a/doc/lisp.md +++ b/doc/lisp.md @@ -19,24 +19,33 @@ of strings to the language and reading from the filesystem. - Basics: `bool`, `list`, `symbol`, `string` - Numbers: `float`, `int`, `bigint` -## Seven Primitive Operators +## Built-in Operators - `quote` (with the `'` syntax) +- `quasiquote` (with the `` ` ``) +- `unquote` (with the `,` syntax) +- `unquote-splicing` (with the `,@` syntax) - `atom` (aliased to `atom?`) - `eq` (aliased to `eq?`) - `car` (aliased to `first`) - `cdr` (aliased to `rest`) - `cons` +- `if` - `cond` - -## Two Special Forms -- `label` (aliased to `define` and `def`) -- `lambda` (aliased to `function`, `fun`, and `fn`) - -## Additional Builtins -- `defun` (aliased to `defn`) -- `set` - `while` +- `set` +- `define` (aliased to `def` and `label`) +- `function` (aliased to `fun` and `lambda`) +- `macro` (aliased to `mac`) +- `define-function` (aliased to `def-fun`) +- `define-macro` (aliased to `def-mac`) - `apply` +- `eval` +- `expand` +- `do` (aliased to `begin` and `progn`) +- `load` + +## Primitive Operators +- `append` - `type` - `string` - `string->number` @@ -44,20 +53,18 @@ of strings to the language and reading from the filesystem. - `number->bytes` and `bytes->number` - `regex-find` - `system` -- `load` - Arithmetic operations: `+`, `-`, `*`, `/`, `%`, `^` - Trigonometric functions: `acos`, `asin`, `atan`, `cos`, `sin`, `tan` - Comparisons: `>`, `<`, `>=`, `<=`, `=` -- Boolean operations: `not`, `and`, `or` - String operations: `lines` - File IO: `read-file`, `read-file-bytes`, `write-file-bytes`, `append-file-bytes` ## Core Library - `nil`, `nil?`, `eq?` -- `atom?`, `string?`, `boolean?`, `symbol?`, `number?`, `list?`, `function?`, `lambda?` +- `atom?`, `string?`, `boolean?`, `symbol?`, `number?`, `list?`, `function?`, `macro?` - `first`, `second`, `third`, `rest` -- `map`, `reduce`, `append`, `reverse` +- `map`, `reduce`, `reverse`, `range` - `string-join` - `read-line`, `read-char` - `print`, `println` @@ -65,6 +72,8 @@ of strings to the language and reading from the filesystem. - `uptime`, `realtime` - `regex-match?` +- Boolean operations: `not`, `and`, `or` + ## Usage The interpreter can be invoked from the shell: From a7d9074cb692f92de41483d4e2d7743ea77b379d Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 29 Oct 2022 10:56:54 +0200 Subject: [PATCH 02/12] Add macro? --- dsk/lib/lisp/core.lsp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index 43ac82f2..c13785a2 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -22,6 +22,9 @@ (def (function? x) (eq? (type x) "function")) +(def (macro? x) + (eq? (type x) "macro")) + (def nil '()) (def (nil? x) From f6b044f29c2f1f38ec3fe5fd584c9f3b80c9590f Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 29 Oct 2022 10:57:19 +0200 Subject: [PATCH 03/12] Rewrite and and or with macros --- dsk/lib/lisp/core.lsp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index c13785a2..19375fbc 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -33,11 +33,11 @@ (def (not x) (if x false true)) -(def (or x y) - (if x true (if y true false))) +(def-mac (or x y) + `(if ,x true (if ,y true false))) -(def (and x y) - (if x (if y true false) false)) +(def-mac (and x y) + `(if ,x (if ,y true false) false)) (def (rest x) (cdr x)) From 2eddb3f667d56fa5386e0a76aaef003fa1f59afa Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 29 Oct 2022 10:57:31 +0200 Subject: [PATCH 04/12] Move string-join --- dsk/lib/lisp/core.lsp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index 19375fbc..b1310606 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -55,9 +55,6 @@ (if (nil? (rest ls)) (first ls) (f (first ls) (reduce f (rest ls))))) -(def (string-join ls s) - (reduce (fn (x y) (string x s y)) ls)) - (def (map f ls) (if (nil? ls) nil (cons @@ -72,6 +69,9 @@ (if (= i n) nil (append (list i) (range (+ i 1) n)))) +(def (string-join ls s) + (reduce (fn (x y) (string x s y)) ls)) + (def (read-line) (bytes->string (reverse (rest (reverse (read-file-bytes "/dev/console" 256)))))) From 944ddfd0cb560ff9497439da463a41534822ffc6 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 29 Oct 2022 10:57:43 +0200 Subject: [PATCH 05/12] Update built-in autocompletion --- src/usr/lisp/eval.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/usr/lisp/eval.rs b/src/usr/lisp/eval.rs index e81fdf3c..16019607 100644 --- a/src/usr/lisp/eval.rs +++ b/src/usr/lisp/eval.rs @@ -148,10 +148,19 @@ pub fn eval_args(args: &[Exp], env: &mut Rc>) -> Result, E args.iter().map(|x| eval(x, env)).collect() } -pub const BUILT_INS: [&str; 24] = [ - "quote", "atom", "eq", "car", "cdr", "cons", "cond", "label", "lambda", "define", "def", - "function", "fun", "fn", "if", "while", "defun", "defn", "apply", "eval", "progn", "begin", - "do", "load" +pub const BUILT_INS: [&str; 32] = [ + "quote", "quasiquote", "unquote", "unquote-splicing", + "atom", "eq", "car", "cdr", "cons", + "if", "cond", "while", + "set", + "define", "def", "label", + "function", "fun", "lambda", + "macro", "mac", + "define-function", "def-fun", + "define-macro", "def-mac", + "apply", "eval", "expand", + "do", "begin", "progn", + "load" ]; pub fn eval(exp: &Exp, env: &mut Rc>) -> Result { From 711c00645d533bc25246983243d58b2d204b0890 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 29 Oct 2022 11:01:43 +0200 Subject: [PATCH 06/12] Use define instead of def in core and examples --- doc/lisp.md | 16 +++++----- dsk/lib/lisp/core.lsp | 64 +++++++++++++++++++------------------- dsk/tmp/lisp/factorial.lsp | 4 +-- dsk/tmp/lisp/fibonacci.lsp | 2 +- dsk/tmp/lisp/pi.lsp | 22 ++++++------- dsk/tmp/lisp/sum.lsp | 2 +- src/usr/lisp/mod.rs | 2 +- 7 files changed, 56 insertions(+), 56 deletions(-) diff --git a/doc/lisp.md b/doc/lisp.md index 07cb797a..959bef43 100644 --- a/doc/lisp.md +++ b/doc/lisp.md @@ -94,7 +94,7 @@ with the following content: ```lisp (load "/lib/lisp/core.lsp") -(def (fibonacci n) +(define (fibonacci n) (if (< n 2) n (+ (fibonacci (- n 1)) (fibonacci (- n 2))))) @@ -115,21 +115,21 @@ Would produce the following output: ```lisp (load "/lib/lisp/core.lsp") -(def foo 42) # Variable definition +(define foo 42) # Variable definition -(def double (fun (x) (* x 2))) # Function definition -(def (double x) (* x 2)) # Shortcut +(define double (fun (x) (* x 2))) # Function definition +(define (double x) (* x 2)) # Shortcut (double foo) # => 84 -(def (map f ls) +(define (map f ls) (if (nil? ls) nil (cons (f (first ls)) (map f (rest ls))))) -(def bar (quote (1 2 3))) -(def bar '(1 2 3)) # Shortcut +(define bar (quote (1 2 3))) +(define bar '(1 2 3)) # Shortcut (map double bar) # => (2 4 6) @@ -144,7 +144,7 @@ Would produce the following output: (= foo 10) # => true -(def name "Alice") +(define name "Alice") (string "Hello, " name) # => "Hello, Alice" diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index b1310606..c9c3bf4e 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -1,102 +1,102 @@ -(def (eq? x y) +(define (eq? x y) (eq x y)) -(def (atom? x) +(define (atom? x) (atom x)) -(def (string? x) +(define (string? x) (eq? (type x) "string")) -(def (boolean? x) +(define (boolean? x) (eq? (type x) "boolean")) -(def (symbol? x) +(define (symbol? x) (eq? (type x) "symbol")) -(def (number? x) +(define (number? x) (eq? (type x) "number")) -(def (list? x) +(define (list? x) (eq? (type x) "list")) -(def (function? x) +(define (function? x) (eq? (type x) "function")) -(def (macro? x) +(define (macro? x) (eq? (type x) "macro")) -(def nil '()) +(define nil '()) -(def (nil? x) +(define (nil? x) (eq? x nil)) -(def (not x) +(define (not x) (if x false true)) -(def-mac (or x y) +(define-macro (or x y) `(if ,x true (if ,y true false))) -(def-mac (and x y) +(define-macro (and x y) `(if ,x (if ,y true false) false)) -(def (rest x) +(define (rest x) (cdr x)) -(def (first x) +(define (first x) (car x)) -(def (second x) +(define (second x) (first (rest x))) -(def (third x) +(define (third x) (second (rest x))) -(def (reduce f ls) +(define (reduce f ls) (if (nil? (rest ls)) (first ls) (f (first ls) (reduce f (rest ls))))) -(def (map f ls) +(define (map f ls) (if (nil? ls) nil (cons (f (first ls)) (map f (rest ls))))) -(def (reverse x) +(define (reverse x) (if (nil? x) x (append (reverse (rest x)) (cons (first x) '())))) -(def (range i n) +(define (range i n) (if (= i n) nil (append (list i) (range (+ i 1) n)))) -(def (string-join ls s) +(define (string-join ls s) (reduce (fn (x y) (string x s y)) ls)) -(def (read-line) +(define (read-line) (bytes->string (reverse (rest (reverse (read-file-bytes "/dev/console" 256)))))) -(def (read-char) +(define (read-char) (bytes->string (read-file-bytes "/dev/console" 4))) -(def (print exp) +(define (print exp) (do (append-file-bytes "/dev/console" (string->bytes (string exp))) '())) -(def (println exp) +(define (println exp) (print (string exp "\n"))) -(def (uptime) +(define (uptime) (bytes->number (read-file-bytes "/dev/clk/uptime" 8) "float")) -(def (realtime) +(define (realtime) (bytes->number (read-file-bytes "realtime" 8) "float")) -(def (write-file path str) +(define (write-file path str) (write-file-bytes path (string->bytes str))) -(def (append-file path str) +(define (append-file path str) (append-file-bytes path (string->bytes str))) -(def (regex-match? pattern str) +(define (regex-match? pattern str) (not (nil? (regex-find pattern str)))) diff --git a/dsk/tmp/lisp/factorial.lsp b/dsk/tmp/lisp/factorial.lsp index 847fd75b..4fec0242 100644 --- a/dsk/tmp/lisp/factorial.lsp +++ b/dsk/tmp/lisp/factorial.lsp @@ -1,10 +1,10 @@ (load "/lib/lisp/core.lsp") -(def (factorial-helper n acc) +(define (factorial-helper n acc) (if (< n 2) acc (factorial-helper (- n 1) (* acc n)))) -(def (factorial n) +(define (factorial n) (factorial-helper n 1)) (println diff --git a/dsk/tmp/lisp/fibonacci.lsp b/dsk/tmp/lisp/fibonacci.lsp index a63513c6..7add019c 100644 --- a/dsk/tmp/lisp/fibonacci.lsp +++ b/dsk/tmp/lisp/fibonacci.lsp @@ -1,6 +1,6 @@ (load "/lib/lisp/core.lsp") -(def (fibonacci n) +(define (fibonacci n) (if (< n 2) n (+ (fibonacci (- n 1)) (fibonacci (- n 2))))) diff --git a/dsk/tmp/lisp/pi.lsp b/dsk/tmp/lisp/pi.lsp index 3d9c3c8c..f20eb24d 100644 --- a/dsk/tmp/lisp/pi.lsp +++ b/dsk/tmp/lisp/pi.lsp @@ -1,26 +1,26 @@ (load "/lib/lisp/core.lsp") -(def (pi-digits digits) +(define (pi-digits digits) (do - (def i 0) - (def q 1) - (def r 0) - (def t 1) - (def k 1) - (def n 3) - (def l 3) + (define i 0) + (define q 1) + (define r 0) + (define t 1) + (define k 1) + (define n 3) + (define l 3) (while (<= i digits) (if (< (- (+ (* q 4) r) t) (* n t)) (do (print (string n (if (= i 0) "." ""))) (set i (+ i 1)) - (def nr (* 10 (- r (* n t)))) + (define nr (* 10 (- r (* n t)))) (set n (- (/ (* 10 (+ (* 3 q) r)) t) (* 10 n))) (set q (* q 10)) (set r nr)) (do - (def nr (* (+ (* 2 q) r) l)) - (def nn (/ (+ 2 (* q k 7) (* r l)) (* t l))) + (define nr (* (+ (* 2 q) r) l)) + (define nn (/ (+ 2 (* q k 7) (* r l)) (* t l))) (set q (* q k)) (set t (* t l)) (set l (+ l 2)) diff --git a/dsk/tmp/lisp/sum.lsp b/dsk/tmp/lisp/sum.lsp index abf1bc79..25d3b6db 100644 --- a/dsk/tmp/lisp/sum.lsp +++ b/dsk/tmp/lisp/sum.lsp @@ -1,6 +1,6 @@ (load "/lib/lisp/core.lsp") -(def (sum n acc) +(define (sum n acc) (if (= n 0) acc (sum (- n 1) (+ n acc)))) (println diff --git a/src/usr/lisp/mod.rs b/src/usr/lisp/mod.rs index 0434c22e..1f5b1273 100644 --- a/src/usr/lisp/mod.rs +++ b/src/usr/lisp/mod.rs @@ -343,7 +343,7 @@ fn test_lisp() { assert_eq!(eval!("(if (> 2 4) 1 2)"), "2"); // while - assert_eq!(eval!("(do (def i 0) (while (< i 5) (set i (+ i 1))) i)"), "5"); + assert_eq!(eval!("(do (define i 0) (while (< i 5) (set i (+ i 1))) i)"), "5"); // define eval!("(define a 2)"); From b285d50f6b1bbe1d24b9d5f64aa83ee44fb9eb3f Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 30 Oct 2022 09:08:21 +0100 Subject: [PATCH 07/12] Add changelog to doc --- doc/lisp.md | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/doc/lisp.md b/doc/lisp.md index 959bef43..62b19d9c 100644 --- a/doc/lisp.md +++ b/doc/lisp.md @@ -5,21 +5,44 @@ of the Shell. MOROS Lisp is a Lisp-1 dialect inspired by Scheme and Clojure. -It started from [Risp](https://github.com/stopachka/risp) and was extended to -include the seven primitive operators and the two special forms of John -McCarthy's paper "Recursive Functions of Symbolic Expressions and Their +## Changelog + +### 0.1.0 (2021-07-21) +MOROS Lisp started from [Risp](https://github.com/stopachka/risp) and was +extended to include the seven primitive operators and the two special forms of +John McCarthy's paper "Recursive Functions of Symbolic Expressions and Their Computation by Machine" (1960) and "The Roots of Lisp" (2002) by Paul Graham. -In version 0.2.0 the whole implementation was refactored and the parser was -rewritten to use [Nom](https://github.com/Geal/nom). This allowed the addition -of strings to the language and reading from the filesystem. +### 0.2.0 (2021-12-04) +The whole implementation was refactored and the parser was rewritten to use +[Nom](https://github.com/Geal/nom). This allowed the addition of strings to the +language and reading from the filesystem. + +### 0.3.0 (2022-12-12) +Rewrite the evaluation code, add new functions and a core library. + +### 0.3.1 (2022-06-06) +Rewrite parts of the code and add new functions and examples. + +### 0.3.2 (2022-07-02) +- Add new functions + +### 0.3.2 (2022-08-25) +- Add new functions + +### 0.4.0 (2022-08-25) +- Rewrite a lot of the code +- Add integer and big integer support +- Add tail call optimization (TCO) +- Add macro support +## Overview -## Types +### Types - Basics: `bool`, `list`, `symbol`, `string` - Numbers: `float`, `int`, `bigint` -## Built-in Operators +### Built-in Operators - `quote` (with the `'` syntax) - `quasiquote` (with the `` ` ``) - `unquote` (with the `,` syntax) @@ -44,7 +67,7 @@ of strings to the language and reading from the filesystem. - `do` (aliased to `begin` and `progn`) - `load` -## Primitive Operators +### Primitive Operators - `append` - `type` - `string` @@ -60,7 +83,7 @@ of strings to the language and reading from the filesystem. - String operations: `lines` - File IO: `read-file`, `read-file-bytes`, `write-file-bytes`, `append-file-bytes` -## Core Library +### Core Library - `nil`, `nil?`, `eq?` - `atom?`, `string?`, `boolean?`, `symbol?`, `number?`, `list?`, `function?`, `macro?` - `first`, `second`, `third`, `rest` From 88077db83a51c3812e793e21c849336b8eaf4d9c Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 30 Oct 2022 10:06:44 +0100 Subject: [PATCH 08/12] Move aliases to lib --- dsk/lib/lisp/alias.lsp | 28 ++++++++++++++++++++++++++++ dsk/lib/lisp/core.lsp | 2 ++ src/usr/install.rs | 1 + src/usr/lisp/expand.rs | 24 ++---------------------- 4 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 dsk/lib/lisp/alias.lsp diff --git a/dsk/lib/lisp/alias.lsp b/dsk/lib/lisp/alias.lsp new file mode 100644 index 00000000..b7973e30 --- /dev/null +++ b/dsk/lib/lisp/alias.lsp @@ -0,0 +1,28 @@ +(define def + (macro args `(define ,@args))) + +(define mac + (macro args `(macro ,@args))) + +(define fun + (macro args `(function ,@args))) + +(define def-mac + (macro args `(define-macro ,@args))) + +(define def-fun + (macro args `(define-function ,@args))) + + +(define label + (macro args `(define ,@args))) + +(define lambda + (macro args `(function ,@args))) + +(define progn + (macro args `(do ,@args))) + + +(define begin + (macro args `(do ,@args))) diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index c9c3bf4e..83e9e259 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -1,3 +1,5 @@ +(load "/lib/lisp/alias.lsp") + (define (eq? x y) (eq x y)) diff --git a/src/usr/install.rs b/src/usr/install.rs index 64e81f3b..60f6ee21 100644 --- a/src/usr/install.rs +++ b/src/usr/install.rs @@ -48,6 +48,7 @@ pub fn copy_files(verbose: bool) { create_dir("/lib/lisp", verbose); copy_file("/lib/lisp/core.lsp", include_bytes!("../../dsk/lib/lisp/core.lsp"), verbose); + copy_file("/lib/lisp/alias.lsp", include_bytes!("../../dsk/lib/lisp/alias.lsp"), verbose); copy_file("/tmp/alice.txt", include_bytes!("../../dsk/tmp/alice.txt"), verbose); copy_file("/tmp/machines.txt", include_bytes!("../../dsk/tmp/machines.txt"), verbose); diff --git a/src/usr/lisp/expand.rs b/src/usr/lisp/expand.rs index d6c6b790..f8c25866 100644 --- a/src/usr/lisp/expand.rs +++ b/src/usr/lisp/expand.rs @@ -55,27 +55,7 @@ pub fn expand(exp: &Exp, env: &mut Rc>) -> Result { ensure_length_eq!(list, 2); expand_quasiquote(&list[1]) } - Exp::Sym(s) if s == "begin" || s == "progn" => { - let mut res = vec![Exp::Sym("do".to_string())]; - res.extend_from_slice(&list[1..]); - expand(&Exp::List(res), env) - } - Exp::Sym(s) if s == "def" || s == "label" => { - let mut res = vec![Exp::Sym("define".to_string())]; - res.extend_from_slice(&list[1..]); - expand(&Exp::List(res), env) - } - Exp::Sym(s) if s == "fun" || s == "fn" || s == "lambda" => { - let mut res = vec![Exp::Sym("function".to_string())]; - res.extend_from_slice(&list[1..]); - expand(&Exp::List(res), env) - } - Exp::Sym(s) if s == "mac" => { - let mut res = vec![Exp::Sym("macro".to_string())]; - res.extend_from_slice(&list[1..]); - expand(&Exp::List(res), env) - } - Exp::Sym(s) if s == "define-function" || s == "def-fun" || s == "define" => { + Exp::Sym(s) if s == "define-function" || s == "define" => { ensure_length_eq!(list, 3); match (&list[1], &list[2]) { (Exp::List(args), Exp::List(_)) => { @@ -93,7 +73,7 @@ pub fn expand(exp: &Exp, env: &mut Rc>) -> Result { _ => Err(Err::Reason("Expected first argument to be a symbol or a list".to_string())) } } - Exp::Sym(s) if s == "define-macro" || s == "def-mac" => { + Exp::Sym(s) if s == "define-macro" => { ensure_length_eq!(list, 3); match (&list[1], &list[2]) { (Exp::List(args), Exp::List(_)) => { From 20a1805541de98839a64e46a22678dbbf0405804 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 30 Oct 2022 10:32:05 +0100 Subject: [PATCH 09/12] Add let macro --- dsk/lib/lisp/core.lsp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index 83e9e259..0b372a0e 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -41,6 +41,9 @@ (define-macro (and x y) `(if ,x (if ,y true false) false)) +(define-macro (let params values body) + `((function ,params ,body) ,values)) + (define (rest x) (cdr x)) From 21ca04d580075ae2688dbc10e88c99a92a644ea3 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 30 Oct 2022 13:08:05 +0100 Subject: [PATCH 10/12] Add caar cadr cdar cddr functions --- doc/lisp.md | 3 ++- dsk/lib/lisp/core.lsp | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/lisp.md b/doc/lisp.md index 62b19d9c..f73eae77 100644 --- a/doc/lisp.md +++ b/doc/lisp.md @@ -86,8 +86,9 @@ Rewrite parts of the code and add new functions and examples. ### Core Library - `nil`, `nil?`, `eq?` - `atom?`, `string?`, `boolean?`, `symbol?`, `number?`, `list?`, `function?`, `macro?` -- `first`, `second`, `third`, `rest` +- `caar`, `cadr`, `cdar`, `cddr`, `first`, `second`, `third`, `rest` - `map`, `reduce`, `reverse`, `range` +- `let` - `string-join` - `read-line`, `read-char` - `print`, `println` diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index 0b372a0e..ce305507 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -44,6 +44,18 @@ (define-macro (let params values body) `((function ,params ,body) ,values)) +(define (caar x) + (car (car x))) + +(define (cadr x) + (car (cdr x))) + +(define (cdar x) + (cdr (car x))) + +(define (cddr x) + (cdr (cdr x))) + (define (rest x) (cdr x)) From f7e9be6b3c8c818e7eea170df3b77fe69e6a2a28 Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 30 Oct 2022 14:40:53 +0100 Subject: [PATCH 11/12] Add fixme --- src/usr/lisp/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/usr/lisp/mod.rs b/src/usr/lisp/mod.rs index 1f5b1273..2f3beabf 100644 --- a/src/usr/lisp/mod.rs +++ b/src/usr/lisp/mod.rs @@ -169,6 +169,7 @@ fn parse_eval(exp: &str, env: &mut Rc>) -> Result { } fn strip_comments(s: &str) -> String { + // FIXME: This doesn't handle `#` inside a string s.split('#').next().unwrap().into() } From f5b295c3469dc0a11bca77aa391c4000dd64871b Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sun, 30 Oct 2022 23:00:05 +0100 Subject: [PATCH 12/12] Fix let macro --- dsk/lib/lisp/core.lsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsk/lib/lisp/core.lsp b/dsk/lib/lisp/core.lsp index ce305507..8124462f 100644 --- a/dsk/lib/lisp/core.lsp +++ b/dsk/lib/lisp/core.lsp @@ -42,7 +42,7 @@ `(if ,x (if ,y true false) false)) (define-macro (let params values body) - `((function ,params ,body) ,values)) + `((function ,params ,body) ,@values)) (define (caar x) (car (car x)))