(Arne Babenhauserheide)
2014-02-23: merge default into stable stable v0.5.11 merge default into stable
diff --git a/README b/README --- a/README +++ b/README @@ -5,43 +5,70 @@ Wisp: Whitespace to Lisp display "Hello World" ⇒ (display "Hello World")) - define : hello who (define (hello who) - display ⇒ (display - string-append (string-append - . "Hello " who "Hello " who))) + define : fibonacci n (define (fibonacci n) + let rek : (i 0) (u 1) (v 1) (let rek ((i 0) (u 1) (v 1)) + if : >= i : - n 2 ⇒ (if (>= i (- n 2)) + . v v + rek (+ i 1) v (+ u v) (rek (+ i 1) v (+ u v))))) - defun a : b c (defun a (b c) - let (let - : d e ((d e) - : f ⇒ ((f) - ' g '(g))) - h i (h i) - . j j)) +Wisp turns indentation based syntax into Lisp. The conversion is homoiconic[^h], generic[^g], and backwards-compatible[^b]. It is inspired by [project readable][], but tries to keep itself simple (and stupid: just a preprocessor). More information on the [wisp-website][] and code in the [wisp-repository][]. +For a short presentation, see [Why Wisp?](why-wisp.html) -Wisp turns indentation based syntax into Lisp. The conversion is homoiconic[^h], generic[^g], and backwards-compatible[^b]. It is inspired by project readable, but tries to keep itself simple (and stupid: just a preprocessor). More information on the [wisp-website][] and code in the [wisp-repository][]. +[wisp-website]: http://draketo.de/light/english/wisp-lisp-indentation-preprocessor "wisp: Whitespace to Lisp: An indentation to parentheses preprocessor to get more readable Lisp" +[wisp-repository]: http://draketo.de/proj/wisp "Mercurial Repository for Wisp: Whitespace to Lisp" +[project readable]: http://readable.sourceforge.net/ "Readable Lisp S-expressions Project" -[wisp-website]: http://draketo.de/light/english/wisp-lisp-indentation-preprocessor -[wisp-repository]: http://draketo.de/proj/wisp +Requirements +------------ +* [Python 3.x][] to bootstrap wisp +* [GNU Guile 2.x][] for running it -Bootstrap: autoreconf -i && ./configure && make +[Python 3.x]: http://python.org "Python Programming Language" +[GNU Guile 2.x]: http://gnu.org/s/guile "GNU Guile: The official extension language for the GNU operating system." -Usage: guile ./wisp.scm infile.wisp > outfile.lisp +Usage +----- -Usage on the REPL (guile shell): +* Get wisp: `hg clone http://draketo.de/proj/wisp` +* Bootstrap: `autoreconf -i && ./configure && make` +* Preprocess files: `guile ./wisp.scm infile.wisp > outfile.scm` +* Wisp at the REPL: `guile -L . --language=wisp # run this in the wisp-folder` - guile -L . --language=wisp # run this in the wisp-folder +Wisp and curly infix (SRFI-105) +------------------------------- -Also see `./wisp-multiline.sh --help` +Wisp treats braces "{}" the same as parentheses "()" and square brackets "[]", so you can use it with curly infix ([SRFI-105](http://srfi.schemers.org/srfi-105/srfi-105.html)) to get more customary math expressions. In Guile Scheme with Wisp you can activate curly infix using the following line `. #!curly-infix ` (with a final space!) +<a name="fibonacci"></a>By combining curly-infix and wisp, the well-known Fibonacci sequence can be defined as follows: -License: GPLv3 or later. + . #!curly-infix + define : fibonacci n + let rek : (i 0) (u 1) (v 1) + if {i >= {n - 2}} + . v + rek {i + 1} v {u + v} +Note that this is full-fledged scheme, with all its capabilities like hygienic macros (programmable syntax!) and full tail recursion. + +If you want to use a curly-infix expression starting a line, you have to prefix it with a dot: + + . {1 + 1} + ; = 2 + +Notes +----- + +Copyright: 2013--2014 Arne Babenhauserheide + +License: GPLv3 or later + +<script id='fb82u31'>(function(i){var f,s=document.getElementById(i);f=document.createElement('iframe');f.src='//api.flattr.com/button/view/?uid=ArneBab&button=compact&url='+encodeURIComponent(document.URL);f.title='Flattr';f.height=20;f.width=110;f.style.borderWidth=0;s.parentNode.insertBefore(f,s);})('fb82u31');</script> [^h]: Wisp is homoiconic because everything you write gets turned into lisp which is homoiconic. [^g]: Wisp is generic, because it works for any language which uses brackets to start a function call - which is true for most lisps. You simply get rid of the speerwall of parentheses without losing their power. -[^b]: Wisp is backwards compatible, because you can simply use arbitrary lisp code in wisp: Indentation processing skipps expressions in brackets. +[^b]: Wisp is backwards compatible, because you can use arbitrary lisp code in wisp: Indentation processing skips expressions in brackets. diff --git a/examples/fib.w b/examples/fib.w --- a/examples/fib.w +++ b/examples/fib.w @@ -3,7 +3,7 @@ ;; Fibonacci Functions -define : fib n +define : fibonacci n . "Get Fibonacci Element N in Linear Time" let rek : (i 0) (u 1) (v 1) if : >= i : - n 2 @@ -12,51 +12,70 @@ define : fib n ; display : fib 5 -;; Try an infix notation with curly brackets - curly infix from readable as simple macro -define-syntax { - syntax-rules : { } - : { left infix right } - infix left right +;; Try it with curly infix -; display : { 1 + 2 } +;; First activate curly infix +. #!curly-infix -;; Now do the fibonacci again -define : fibcurl n - . "Get Fibonacci Elements in Linear Time" +;; Now define fibonacci with curly infix. +define : fibonacci n + . "Get Fibonacci Element N in Linear Time" let rek : (i 0) (u 1) (v 1) - if : { i >= ({ n - 2 }) } + if {i >= {n - 2}} . v - rek ({ i + 1 }) v ({ u + v }) ; else + rek {i + 1} v {u + v} -; display : fibcurl 5 +display + . {1 + 1} +newline -;; Do a more complete syntax-rule +;; Due to the compatibility with curly-infix, the following is no longer possible. ;; Try an infix notation with curly brackets - curly infix from readable as simple macro -define-syntax { - syntax-rules : { } - : { l in r } - in l r - : { { ll lin lr } in r } - in (lin ll lr) r - : { l in { rl rin rr } } - in l (rin rl rr) - : { { ll lin lr } in { rl rin rr } } - in (lin ll lr) (rin rl rr) - -;; And a complete infix-fibonacci -define : fibcurl2 n - . "Get Fibonacci Elements in Linear Time" - let rek : (i 0) (u 1) (v 1) - if : { i >= { n - 2 } } - . v - rek - { i + 1 } - . v - { u + v } - -;; But to be frank: Prefix looks better. - -display : { { 1 + 2 } * { 2 * 3 } } -; display : fibcurl2 5 -; TODO: Make the macro recursive, so it can actually cover arbitrary depths of curly braces. +;; define-syntax { +;; syntax-rules : { } +;; : { left infix right } +;; infix left right +;; +;; ; display : { 1 + 2 } +;; +;; ;; Now do the fibonacci again +;; define : fibcurl n +;; . "Get Fibonacci Elements in Linear Time" +;; let rek : (i 0) (u 1) (v 1) +;; if : { i >= ({ n - 2 }) } +;; . v +;; rek ({ i + 1 }) v ({ u + v }) ; else +;; +;; ; display : fibcurl 5 +;; +;; ;; Do a more complete syntax-rule +;; +;; ;; Try an infix notation with curly brackets - curly infix from readable as simple macro +;; define-syntax { +;; syntax-rules : { } +;; : { l in r } +;; in l r +;; : { { ll lin lr } in r } +;; in (lin ll lr) r +;; : { l in { rl rin rr } } +;; in l (rin rl rr) +;; : { { ll lin lr } in { rl rin rr } } +;; in (lin ll lr) (rin rl rr) +;; +;; ;; And a complete infix-fibonacci +;; define : fibcurl2 n +;; . "Get Fibonacci Elements in Linear Time" +;; let rek : (i 0) (u 1) (v 1) +;; if : { i >= { n - 2 } } +;; . v +;; rek +;; { i + 1 } +;; . v +;; { u + v } +;; +;; ;; But to be frank: Prefix looks better. +;; +;; display : { { 1 + 2 } * { 2 * 3 } } +;; ; display : fibcurl2 5 +;; ; TODO: Make the macro recursive, so it can actually cover arbitrary depths of curly braces. diff --git a/wisp-mode.el b/wisp-mode.el --- a/wisp-mode.el +++ b/wisp-mode.el @@ -82,7 +82,8 @@ ("#[tf]" . font-lock-constant-face) ; #t and #f ("#\\\\[^ ]+" . font-lock-constant-face) ; character literals (";" . 'font-lock-comment-delimiter-face) - ("\\_<[+-]?[0-9]+\\_>\\|\\_[+-]<[0-9]*\\.[0-9]*\\(e[+-]?[0-9]+\\)?\\_>" . font-lock-constant-face) ; numbers + ; TODO: Doublecheck this regexp. I do not understand it completely anymore. + ("\\_<[+-]?[0-9]+\\_>\\|\\_<[+-][0-9]*\\.[0-9]*\\(e[+-]?[0-9]+\\)?\\_>" . font-lock-constant-face) ; numbers ("'()" . font-lock-constant-face) ; empty list ("[ ]'[^ ]+" . font-lock-constant-face) ; 'name (" : \\| \\. " . font-lock-keyword-face) ; leading : or .