wisp
 
(drak)
2014-01-05: merge branch support-scheme-macro-paren-quoting.

merge branch support-scheme-macro-paren-quoting.

diff --git a/bootstrap.sh b/bootstrap.sh
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -2,8 +2,8 @@
 
 # Bootstrap wisp-guile with wisp.py
 
-diff=$(python3 wisp.py wisp-guile.w > 1 && guile 1 wisp-guile.w > 2 && guile 2 wisp-guile.w > wisp.scm && diff 2 wisp.scm)
-if [[ x"${diff}" == x ]]; then
+diff=$(python3 wisp.py wisp-guile.w > 1 && guile 1 wisp-guile.w > 2 && guile 2 wisp-guile.w > wisp.scm && diff 2 wisp.scm && echo success)
+if [[ x"${diff}" == x"success" ]]; then
     echo "successfully bootstrapped wisp.scm"
 else
     echo "failed to bootstrap wisp.scm. diff: " ${diff}
diff --git a/examples/tinyenc.w b/examples/tinyenc.w
--- a/examples/tinyenc.w
+++ b/examples/tinyenc.w
@@ -32,25 +32,41 @@ define : v1change k2 v0 sum k3
 ; TODO: Define a macro with-split-kv which executes its body with let bindings to k0 k1 k2 k3 v0 and v1
 ; http://www.gnu.org/software/guile/manual/html_node/Syntax-Case.html#index-with_002dsyntax
 define-syntax with-split-vk
-  lambda : x
-    syntax-case x :
-      : with-split-vk v k exp ...
-        with-syntax
-          : k0 : datum->syntax x 'k0
-            k1 : datum->syntax x 'k1
-            k2 : datum->syntax x 'k2
-            k3 : datum->syntax x 'k3
-            v0 : datum->syntax x 'v0
-            v1 : datum->syntax x 'v1
-          #' let
-            : k0 : uint32 : ash k -96
+    syntax-rules :
+      : with-split-vk v k exp exp* ...
+          let ; TODO: This defines syntmp-v0-# instead of v0. TODO: report bug: this breaks hygiene: (define-syntax with-car-a-cdr-b (syntax-rules () ((_ some-list exp exp* ...) (let ((a (car some-list))(b (cdr some-list))) exp exp* ...)))) (with-car-a-cdr-b (list "1" "2" "3") (display syntmp-a-235)) - adjust syntmp-a-# as needed. To avoid: walk the code to ensure that no used variables are bound.
+            : v0 : uint32 : ash v -32
+              v1 : uint32 v
+              k0 : uint32 : ash k -96
               k1 : uint32 : ash k -64
               k2 : uint32 : ash k -32
               k3 : uint32 k
-              v0 : uint32 : ash v -32
-              v1 : uint32 v
-            . exp ...
-    
+            . exp exp* ...
+
+
+; TODO: Define a macro with-split-kv which executes its body with let bindings to k0 k1 k2 k3 v0 and v1
+; Use syntax-case to be able to break hygiene.
+; http://www.gnu.org/software/guile/manual/html_node/Syntax-Case.html#index-with_002dsyntax
+define-syntax with-split-vk
+  lambda : x
+    syntax-case x :
+      : with-split-vk v k exp exp* ...
+        let
+          : v0 : uint32 : ash v -32
+            v1 : uint32 v
+            k0 : uint32 : ash k -96
+            k1 : uint32 : ash k -64
+            k2 : uint32 : ash k -32
+            k3 : uint32 k
+          with-syntax
+            : k0 : datum->syntax x 'k0
+              k1 : datum->syntax x 'k1
+              k2 : datum->syntax x 'k2
+              k3 : datum->syntax x 'k3
+              v0 : datum->syntax x 'v0
+              v1 : datum->syntax x 'v1
+            . exp exp* ...
+
 
 define : encrypt v k
   . "Encrypt the 64bit (8 byte, big endian) value V with the 128bit key K (16 byte)."
diff --git a/wisp-guile.w b/wisp-guile.w
--- a/wisp-guile.w
+++ b/wisp-guile.w
@@ -16,6 +16,8 @@
 define-module : wisp
    . #:export : wisp2lisp wisp-chunkreader
 
+use-modules : : srfi srfi-1
+
 define : endsinunevenbackslashes text ; comment
        if : = 0 : string-length text
            . #f
@@ -373,7 +375,9 @@ define : wisp2lisp-add-inline-colon-brac
                   ; else
                   let 
                       : lastletter : string-take-right unprocessed 1
-                        lastupto3 : string-take-right unprocessed : min 3 : string-length unprocessed
+                        lastupto3  : string-take-right unprocessed : min 3 : string-length unprocessed
+                        lastupto4  : string-take-right unprocessed : min 4 : string-length unprocessed
+                        lastupto6  : string-take-right unprocessed : min 6 : string-length unprocessed
                       ; check if we’re in a string
                       when
                           or
@@ -395,13 +399,14 @@ define : wisp2lisp-add-inline-colon-brac
                       when : < inbrackets 0
                           throw 'more-inline-brackets-closed-than-opened inbrackets line
                       ; when we’re in a string or in brackets , just skip to the next char
-                      if : or instring : > inbrackets 0
+                      cond
+                        : or instring : > inbrackets 0
                           linebracketizer instring inbrackets bracketstoadd 
                               . : string-drop-right unprocessed 1
                               . : string-append lastletter processed
                           ; else check for " : ": That adds a new inline bracket
                           ; support : at the beginning of a line, too.
-                          if : or (equal? " : "  lastupto3) (equal? ": " lastupto3)
+                        : or (equal? " : "  lastupto3) (equal? ": " lastupto3)
                               ; replace the last 2 chars with "(" and note
                               ; that we need an additional closing bracket
                               ; at the end.
@@ -409,15 +414,46 @@ define : wisp2lisp-add-inline-colon-brac
                                   string-append (string-drop-right unprocessed 2) 
                                   string-append "(" processed
                               ; turn " ' (" into " '(", do not modify unprocessed, except to shorten it!
-                              if : and (string-prefix? "(" processed) : equal? " ' " lastupto3
+                              ; same for ` , #' #` #, #,@,
+                        : and (string-prefix? "(" processed) : equal? " ' " lastupto3
                                   ; leave out the second space
                                   linebracketizer instring inbrackets bracketstoadd 
                                       . (string-append (string-drop-right unprocessed 2) "'")
                                       . processed
-                                  ; else, just go on
+                        : and (string-prefix? "(" processed) : equal? " , " lastupto3
+                                  ; leave out the second space
                                   linebracketizer instring inbrackets bracketstoadd 
-                                      . (string-drop-right unprocessed 1)
-                                      . (string-append lastletter processed)
+                                      . (string-append (string-drop-right unprocessed 2) ",")
+                                      . processed
+                        : and (string-prefix? "(" processed) : equal? " ` " lastupto3
+                                      ; leave out the second space
+                                      linebracketizer instring inbrackets bracketstoadd 
+                                          . (string-append (string-drop-right unprocessed 2) "`")
+                                          . processed
+                        : and (string-prefix? "(" processed) : equal? " #` " lastupto4
+                                      ; leave out the second space
+                                      linebracketizer instring inbrackets bracketstoadd 
+                                          . (string-append (string-drop-right unprocessed 3) "#`")
+                                          . processed
+                        : and (string-prefix? "(" processed) : equal? " #' " lastupto4
+                                      ; leave out the second space
+                                      linebracketizer instring inbrackets bracketstoadd 
+                                          . (string-append (string-drop-right unprocessed 3) "#'")
+                                          . processed
+                        : and (string-prefix? "(" processed) : equal? " #, " lastupto4
+                                      ; leave out the second space
+                                      linebracketizer instring inbrackets bracketstoadd 
+                                          . (string-append (string-drop-right unprocessed 3) "#,")
+                                          . processed
+                        : and (string-prefix? "(" processed) : equal? " #,@, " lastupto6
+                                      ; leave out the second space
+                                      linebracketizer instring inbrackets bracketstoadd 
+                                          . (string-append (string-drop-right unprocessed 5) "#,@,")
+                                          . processed
+                        : . else ; just go on
+                                      linebracketizer instring inbrackets bracketstoadd 
+                                          . (string-drop-right unprocessed 1)
+                                          . (string-append lastletter processed)
                         
 
 define : last-indent levels
@@ -425,14 +461,31 @@ define : last-indent levels
     list-ref levels 0
 
 define : line-add-starting-bracket line
-    . "Add a starting bracket to the line, if it is no continuation line (it is more indented than the previous)."
-    list 
-        line-indent line
-        string-append 
-            . "("
-            line-content line
-        line-comment line
+    . "Add a starting bracket to the line, if it is no continuation line (it is more indented than the previous).
 
+If line starts with one of ' , ` #` #' #, #,@, then turn it into '(... instead of ('..."
+    let loop : : paren-prefixes : list "'" "," "`" "#`" "#'" "#," "#,@,"
+        ; first check whether we are done checking
+        if : null-list? paren-prefixes
+            ; construct the line structure: '(indentation-depth content comment)
+            list 
+                line-indent line
+                string-append 
+                    . "("
+                    line-content line
+                line-comment line
+            ; otherwise check all possible prefixes
+            let : : prefix : car paren-prefixes
+                if : string-prefix? prefix : line-content line
+                    list 
+                        line-indent line
+                        string-append 
+                            . prefix "("
+                            line-content line
+                        line-comment line
+                    ; else
+                    loop : cdr paren-prefixes
+    
 define : line-add-closing-brackets line number
     . "Add a closing bracket to the line."
     list 
diff --git a/wisp-mode.el b/wisp-mode.el
--- a/wisp-mode.el
+++ b/wisp-mode.el
@@ -1,9 +1,9 @@
-;;; wisp-mode.el --- Major mode for editing wisp: Whitespace-to-Lisp
+;;; wisp-mode.el --- Tools for wisp: the Whitespace-to-Lisp preprocessor
 
 ;; Copyright (C) 2013  Arne Babenhauserheide <arne_bab@web.de>
 
 ;; Author: Arne Babenhauserheide <arne_bab@web.de>
-;; Version: 0.1.2
+;; Version: 0.1.5
 ;; Keywords: languages, lisp
 
 ;; This program is free software; you can redistribute it and/or
@@ -21,9 +21,20 @@
 
 ;;; Commentary:
 
+;; To use, add wisp-mode.el to your emacs lisp path and add the following
+;; to your ~/.emacs or ~/.emacs.d/init.el
+;; 
+;; (require 'wisp-mode)
+;; 
 ;; For details on wisp, see 
 ;; http://draketo.de/light/english/wisp-lisp-indentation-preprocessor
-
+;; 
+;; If you came here looking for wisp the lisp-to-javascript compiler[1], have a look at wispjs-mode[2].
+;; 
+;; [1]: http://jeditoolkit.com/try-wisp
+;; 
+;; [2]: http://github.com/krisajenkins/wispjs-mode
+;; 
 ;;; Code:
 
 (require 'scheme)