wisp
 
(Arne Babenhauserheide)
2013-08-08: merge

merge

diff --git a/.bugs/bugs b/.bugs/bugs
--- a/.bugs/bugs
+++ b/.bugs/bugs
@@ -1,4 +1,5 @@
 fails when I add stuff at the end of end of example.w        | owner:, open:False, id:08c68e1ce0c9798184c01806d2661a3220bff3cd, time:1363789693.79
 implement wisp in wisp                                       | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:6299306916706410702029289bf32edab1e7f17c, time:1367113341.49
-inline ' : should be '(                                      | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:72d534a8b23b4cb168017f1bb7d8816f0ea170c4, time:1366497335.26
+inline ' : should be '(                                      | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:72d534a8b23b4cb168017f1bb7d8816f0ea170c4, time:1366497335.26
 make this work: let : : origfile ( open-file : nth 1 : command-line ) r | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:d6de2074a5017f1f29f34d142ce797981ed270a0, time:1366529287.67
+comments containing a closing parenthesis can break the parser. | owner:, open:False, id:d9147504868960e5fbc2648474d48ce5c9bd1a02, time:1374838747.22
diff --git a/.bugs/details/d9147504868960e5fbc2648474d48ce5c9bd1a02.txt b/.bugs/details/d9147504868960e5fbc2648474d48ce5c9bd1a02.txt
new file mode 100644
--- /dev/null
+++ b/.bugs/details/d9147504868960e5fbc2648474d48ce5c9bd1a02.txt
@@ -0,0 +1,28 @@
+# Lines starting with '#' and sections without content
+# are not displayed by a call to 'details'
+#
+[paths]
+# Paths related to this bug.
+# suggested format: REPO_PATH:LINENUMBERS
+
+
+[details]
+# Additional details
+
+
+[expected]
+# The expected result
+
+
+[actual]
+# What happened instead
+
+
+[reproduce]
+# Reproduction steps
+    echo "define ; )
+      a ' : b
+    " | ./wisp.py -
+
+[comments]
+# Comments and updates - leave your name
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -1,3 +1,4 @@
 220ce60600a7424ec2a167c6c4174b1e43570738 v0.1
 d72216a3aeab91f60f0004264e329fc636da32b6 v0.2
 60b1c42aae9b4bcef8a3fa1a3e8da04770efa641 v0.3
+5698a4f0fd7090c234732e1dacf38eb3c996f807 v0.3.1
diff --git a/Changelog b/Changelog
new file mode 100644
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,32 @@
+0.3.1
+	* wisp.py: parentheses in comments no longer break the parser
+	* wisp.py: inline " ' : " is turned into " '("
+	* multithreaded-magic.w: New example: Easy multithreading.
+	* hello-world-server.w: Show local time instead of UTC and be a
+	bit more friendly.
+
+0.3
+	* wisp-multiline.sh: started with emacs support. Not yet nice.
+	* wisp.w: renamed to wisp-guile.w to show that it uses guile
+	scheme.
+	* wisp.w: started wisp in wisp. Does not work, yet.
+	* hello-world-server.w: First actually running example code.
+	* wisp-multiline.sh: directly execute the typed script in guile
+	scheme. Robust shell-script commandline parsing.
+	* Readme.txt: Note the license and add references and footnotes.
+	* Readme.txt: Fix the examples and add a stdin-example with guile.
+
+0.2
+	* wisp.py: got more resilient.
+	* wisp.py: condense multiple inline : into multiple brackets
+	without whitespace.
+	* wisp.py: refactored into multiple distinct phases for easier
+	maintainability.
+	* wisp.py: allow escaping : and _ with \.
+	* wisp.py: added websafe indent with _
+	* wisp.py: a colon at the end of the line is interpreted as ()
+	* wisp.py: don’t interpret wisp code in brackets or strings.
+
+0.1
+	* wisp.py: first version.
+	* Readme.txt: Added a readme.
diff --git a/hello-world-server.w b/hello-world-server.w
--- a/hello-world-server.w
+++ b/hello-world-server.w
@@ -1,28 +1,43 @@
-#!/home/arne/Quell/Programme/wisp/wisp-multiline.sh   
+#!./wisp-multiline.sh
 ; !#
 
+; first the plain text header
+define : header
+  ' : content-type . : text/plain
+
+; now content building functions
+define : timestring
+  string-join 
+    list
+        ; use gmtime instead of localtime if you want UTC
+        number->string : tm:hour : localtime : current-time
+        number->string : tm:min : localtime : current-time
+    . ":" ; delimiter
+
+define : greeting
+  if : string? : getlogin
+    getlogin
+    . "Mellon?"
+
+define : content
+  let : : text "Hello World!" ; the let is wisp syntax showoff…
+    string-join
+      list 
+        . text
+        greeting
+        timestring
+      . "\n" ; delimiter
+
+; and the request handler
 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!"
+    header
+    content
 
-      set! text 
-        string-append text " "
-          number->string : tm:hour : gmtime : current-time
-          . ":"
-          number->string : tm:min : gmtime : current-time
-
-      . text
-
-
+; finally run the webserver
 use-modules : web server
 
-display : string-append "Server starting. Test it at http://127.0.0.1:8081"
+display "Server starting. Test it at http://127.0.0.1:8081"
 newline
 
 run-server hello-world-handler 'http ' : #:port 8081
diff --git a/multithreaded-magic.w b/multithreaded-magic.w
new file mode 100755
--- /dev/null
+++ b/multithreaded-magic.w
@@ -0,0 +1,41 @@
+#!./wisp-multiline.sh
+; !#
+
+; Mathematical magic: Always get one.
+; 
+; Via http://www.liv.ac.uk/HPC/HTMLF90Course/HTMLF90CourseQuestionsnode18.html
+; (actually for learning fortran)
+; 
+; this is the wisp scheme version which I want to compare with the fortran version.
+
+use-modules 
+  ice-9 format
+  ice-9 futures
+  ice-9 threads
+
+define : magic-threaded mutex futures integer
+  ; this can cause unordered output. It’s fun anyway : 
+  set! futures : append futures : list : future : with-mutex mutex : format #t "~30r\n" integer
+  if : not : = integer 1
+    if : even? integer
+      magic-threaded mutex futures : / integer 2
+      magic-threaded mutex futures : truncate : + 1 : / integer 3 
+    for-each touch futures
+
+define : magic integer
+  magic-threaded
+    make-mutex
+    list
+    . integer
+
+define : magic-simple integer
+  format #t "~30r\n" integer
+  if : not : = integer 1
+    if : even? integer
+      magic-simple : / integer 2
+      magic-simple : truncate : + 1 : / integer 3 
+
+display ";;; multithreaded magic ;;;\n"
+magic 456189456156456196152615
+display ";;; simple magic ;;;\n"
+magic-simple 456189456156456196152615
diff --git a/tests/quotecolon.w b/tests/quotecolon.w
new file mode 100755
--- /dev/null
+++ b/tests/quotecolon.w
@@ -0,0 +1,10 @@
+#!/home/arne/wisp/wisp-multiline.sh  
+; !#
+define a 1 ; test whether ' : correctly gets turned into '(
+; and whether brackets in commments are treated correctly.
+
+define a ' : 1 2 3
+
+define
+  a b
+  c
diff --git a/wisp.py b/wisp.py
--- a/wisp.py
+++ b/wisp.py
@@ -47,8 +47,8 @@ def replaceinwisp(code, string, replacem
     strlen = len(string)
     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 == ";" and not code[n-2:n] == "#\\":
+        # comments start with a ; - but only in regular wisp code or in brackets.
+        if not incomment and not instring and i == ";" and not code[n-2:n] == "#\\":
             incomment = not incomment
         # a linebreak ends the comment
         if incomment:
@@ -61,7 +61,7 @@ def replaceinwisp(code, string, replacem
         # all processing stops in strings
         if instring:
             continue
-        if i == "("  and not code[n-2:n] == "#\\":
+        if i == "(" and not code[n-2:n] == "#\\":
             inbrackets += 1
         elif i == ")" and not code[n-2:n] == "#\\":
             inbrackets -= 1
@@ -169,10 +169,14 @@ class Line:
                 ):
                 if self.content[n-1:n+2] == " : " or self.content[n-1:] == " :":
                     bracketstoclose += 1
-                    # we have to keep the space after the colon (" : "
-                    # → " ( "), otherwise we cannot use two
-                    # consecutive colons (" : : ") which would be surprising.
-                    self.content = self.content[:n] + "(" + self.content[n+2:]
+                    # treat ' : as '(
+                    if self.content[n-3:n+1] == " ' :":
+                        self.content = self.content[:n-2] + "'(" + self.content[n+2:]
+                    else:
+                        # we have to keep the space after the colon (" : "
+                        # → " ( "), otherwise we cannot use two
+                        # consecutive colons (" : : ") which would be surprising.
+                        self.content = self.content[:n] + "(" + self.content[n+2:]
         
         # after the full line processing, replace " \\: " "\n\\: " and
         # " \\:\n" (inside line, start of a line, end of a line) by "
@@ -215,9 +219,20 @@ def nostringbreaks(code):
 def nobracketbreaks(code):
     """remove linebreaks inside brackets (will be readded at the end)."""
     instring = False
+    incomment = False
     inbracket = 0
     nostringbreaks = []
     for n, char in enumerate(code):
+        # comments start with a ; - but only in regular wisp code or in brackets.
+        if not incomment and not instring and char == ";" and not code[n-2:n] == "#\\":
+            incomment = not incomment
+        # a linebreak ends the comment
+        if incomment:
+            if char == "\n":
+                incomment = not incomment
+            # all processing stops in comments
+            nostringbreaks.append(char)
+            continue
         if char == '"' and not code[n-1:n] == "\\":
             instring = not instring
         if char == '(' and not instring and not code[n-2:n] == "#\\":