wisp
 
(Arne Babenhauserheide)
2013-04-23: merge wisp.w

merge wisp.w

diff --git a/.bugs/bugs b/.bugs/bugs
--- a/.bugs/bugs
+++ b/.bugs/bugs
@@ -1,1 +1,3 @@
 fails when I add stuff at the end of end of example.w        | owner:, open:False, id:08c68e1ce0c9798184c01806d2661a3220bff3cd, time:1363789693.79
+inline ' : should be '(                                      | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:72d534a8b23b4cb168017f1bb7d8816f0ea170c4, time:1366497335.26
+make this work: let : : origfile ( open-file : nth 1 : command-line ) r | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:d6de2074a5017f1f29f34d142ce797981ed270a0, time:1366529287.67
diff --git a/hello-world-server.w b/hello-world-server.w
--- a/hello-world-server.w
+++ b/hello-world-server.w
@@ -1,19 +1,21 @@
-#!/home/arne/Quell/Programme/wisp/wisp-multiline.sh   !#
+#!/home/arne/Quell/Programme/wisp/wisp-multiline.sh   
+; !#
 
 define : hello-world-handler request request-body
   values 
+    ; header
     ' : content-type . : text/plain
-
+    ; content
     let : : text "Hello World!"
       if : string? : getlogin
-         set! text : string-append text : getlogin
-         set! text : string-append text " Sucker!"
+        set! text : string-append text : getlogin
+        set! text : string-append text " Sucker!"
 
       set! text 
-         string-append text " "
-           number->string : tm:hour : gmtime : current-time
-           . ":"
-           number->string : tm:min : gmtime : current-time
+        string-append text " "
+          number->string : tm:hour : gmtime : current-time
+          . ":"
+          number->string : tm:min : gmtime : current-time
 
       . text
 
@@ -24,3 +26,5 @@ display : string-append "Server starting
 newline
 
 run-server hello-world-handler 'http ' : #:port 8081
+
+
diff --git a/wisp-mode.el b/wisp-mode.el
new file mode 100644
--- /dev/null
+++ b/wisp-mode.el
@@ -0,0 +1,43 @@
+;;; wisp-mode.el --- Major mode for editing wisp: Whitespace-to-Lisp
+
+;; Copyright (C) 2013  Arne Babenhauserheide <arne_bab@web.de>
+
+;; Author: Arne Babenhauserheide <arne_bab@web.de>
+;; Version: 0.0
+;; Keywords: languages, lisp
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 3
+;; of the License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(define-derived-mode wisp-mode
+  emacs-lisp-mode "Wisp" 
+  "Major mode for whitespace-to-lisp files.
+
+  \\{wisp-mode-map}"
+  ; :group wisp
+  (set (make-local-variable 'indent-tabs-mode) nil)
+  (set (make-local-variable 'comment-start) "; ")
+  (set (make-local-variable 'font-lock-comment-start-skip) ";+ *")
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'font-lock-defaults)
+              '((scheme-font-lock-keywords
+                 scheme-font-lock-keywords-1 scheme-font-lock-keywords-2)
+                nil nil nil nil))
+  (set (make-local-variable 'mode-require-final-newline) t))
+
+(provide 'wisp-mode)
+;;; wisp-mode.el ends here
diff --git a/wisp.py b/wisp.py
--- a/wisp.py
+++ b/wisp.py
@@ -48,7 +48,7 @@ def replaceinwisp(code, string, replacem
     for n in range(len(code) - strlen):
         i = code[n]
         # comments start with a ; - but only in regular wisp code.
-        if not incomment and not instring and not inbrackets and i == ";":
+        if not incomment and not instring and not inbrackets and i == ";" and not code[n-2:n] == "#\\":
             incomment = not incomment
         # a linebreak ends the comment
         if incomment:
@@ -56,14 +56,14 @@ def replaceinwisp(code, string, replacem
                 incomment = not incomment
             # all processing stops in comments
             continue
-        if i == '"':
+        if i == '"' and not code[n-1:n] == "\\":
             instring = not instring
         # all processing stops in strings
         if instring:
             continue
-        if i == "(":
+        if i == "("  and not code[n-2:n] == "#\\":
             inbrackets += 1
-        elif i == ")":
+        elif i == ")" and not code[n-2:n] == "#\\":
             inbrackets -= 1
         # all processing stops in brackets
         if inbrackets:
@@ -137,9 +137,9 @@ class Line:
         self.comment = ""
         instring = False
         for n, i in enumerate(self.content):
-            if i == '"': 
+            if i == '"' and not self.content[n-1:n] == "\\": 
                 instring = not instring
-            if not instring and i == ";":
+            if not instring and i == ";" and not self.content[n-2:n] == "#\\":
                 self.comment = self.content[n+1:]
                 self.content = self.content[:n]
                 break
@@ -154,11 +154,11 @@ class Line:
         # go backwards through the content to be able to leave out the
         # space after a colon without breaking later colons.
         for n, i in reversed(list(enumerate(self.content))):
-            if i == '"':
+            if i == '"' and not self.content[n-1:n] == "\\":
                 instring = not instring
-            if not instring and i == ")":
+            if not instring and i == ")" and not self.content[n-2:n] == "#\\":
                 inbrackets += 1
-            elif not instring and i == "(":
+            elif not instring and i == "(" and not self.content[n-2:n] == "#\\":
                 inbrackets -= 1
             if (not instring and 
                 not inbrackets and 
@@ -202,8 +202,8 @@ def nostringbreaks(code):
     """remove linebreaks inside strings (will be readded at the end)"""
     instring = False
     nostringbreaks = []
-    for char in code:
-        if char == '"':
+    for n, char in enumerate(code):
+        if char == '"' and not code[n-1:n] == "\\":
             instring = not instring
         if instring and char == "\n":
             nostringbreaks.append("\\LINEBREAK")
@@ -214,12 +214,15 @@ def nostringbreaks(code):
 
 def nobracketbreaks(code):
     """remove linebreaks inside brackets (will be readded at the end)."""
+    instring = False
     inbracket = 0
     nostringbreaks = []
-    for char in code:
-        if char == '(':
+    for n, char in enumerate(code):
+        if char == '"' and not code[n-1:n] == "\\":
+            instring = not instring
+        if char == '(' and not instring and not code[n-2:n] == "#\\":
             inbracket += 1
-        elif char == ')':
+        elif char == ')' and not instring and not code[n-2:n] == "#\\":
             inbracket -= 1
         if inbracket and char == "\n":
             nostringbreaks.append("\\LINEBREAK")
diff --git a/wisp.w b/wisp.w
--- a/wisp.w
+++ b/wisp.w
@@ -1,4 +1,58 @@
-#!/home/arne/wisp/wisp-multiline.sh 
+#!/usr/bin/env guile
 ; !#
 
-; first step to a wisp preprocessor in wisp: output a file on stdout.
+; first step: Be able to mirror a file to stdout
+
+let ((i (display 
+  1)))
+  display 1
+
+let : : a "rcie
+rcie
+crie"
+  display "
+"
+
+let* 
+    : filename : list-ref ( command-line ) 1
+      origfile : open-file filename "r" ; mode
+      nextchar : read-char origfile
+
+    ; Replace end of line characters in brackets and strings
+    let* 
+        : text ""
+          incomment #f
+          instring #f
+          inbrackets 0
+        while : not : eof-object? nextchar
+            when : and ( char=? nextchar #\" ) ( not incomment )
+                set! instring : not instring
+                display instring
+            when : and ( char=? nextchar #\; ) ( not incomment ) ( not instring )
+                set! incomment #t
+            when
+                and incomment 
+                    not instring
+                    or 
+                        char=? nextchar #\newline
+                        char=? nextchar #\linefeed
+                set! incomment #f
+            ; TODO: This still treats cod as in brackets which is not, possibly because it cannot cope with char literals: #\( and #\)
+            when : and ( char=? nextchar #\( ) ( not instring ) ( not incomment ) 
+                set! inbrackets : + inbrackets 1
+            when : and ( char=? nextchar #\) ) ( not instring ) ( not incomment ) 
+                set! inbrackets : - inbrackets 1
+
+            if : or instring : > inbrackets 0
+                if : char=? nextchar #\linefeed
+                    set! text : string-append text "\\LINE_BREAK_N"
+                    if : char=? nextchar #\newline
+                        set! text : string-append text "\\LINE_BREAK_R"
+                        set! text : string-append text : string nextchar
+                ; when not in brackets or string: just append the char
+                set! text : string-append text : string nextchar
+
+            set! nextchar : read-char origfile
+        display text
+
+newline