wisp
 
(Arne Babenhauserheide)
2015-07-31: merge with evolve improvements

merge with evolve improvements

diff --git a/.bugs/bugs b/.bugs/bugs
--- a/.bugs/bugs
+++ b/.bugs/bugs
@@ -1,4 +1,5 @@
 testsuite: to pass, the tree-il has to match, not the emitted string. This allows for reader-only implementations. | owner:, open:False, id:00b74a730bbf076e73166e817ca7b0a273b376d4, time:1408224636.42
+wisp-scheme: backtraces should show the wisp source.         | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:0475df81a594a52d171a1b811752ca64e5a71df5, time:1426792099.58
 wisp-scheme: unescape \_ and \:                              | owner:, open:False, id:086f61a06e16f1ef56e9917453bbd55b5879d15d, time:1415121255.99
 fails when I add stuff at the end of end of example.w        | owner:, open:False, id:08c68e1ce0c9798184c01806d2661a3220bff3cd, time:1363789693.79
 wisp-mode in quoted lists only the first item is colorized as data, but all words up to the last paren should be colorized. | owner:, open:True, id:1675ca3f894ed8470fa292149a476a2fa0d17140, time:1397196957.45
@@ -6,13 +7,15 @@ add a testsuite for wisp parsers.       
 wisp-mode: export wisp to html fails in org-mode: font-lock-fontify-keywords-region: Invalid regexp | owner:, open:False, id:1e46d8c05580c961c37a32d36c987a5dd1d34943, time:1389371020.39
 an empty line with : should start with double parens         | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:2e188ddf44d36e4605030d3c58607ebfa97d189e, time:1390328674.43
 wisp-in-wisp: remove the leading . for continuation lines after inferring the brackets. | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:2e42e5b64622f0cc383eb8acc3d510912e925bf0, time:1377476687.79
+interpret ` , : correctly.                                   | owner:, open:True, id:2feb5f048b55274c1bc7c8168c8cb358c0c8dd1d, time:1426777900.6
 '() gives REPR-QUOTE-...                                     | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:30c42de75c137f483245898e2a62af1e65cf19a6, time:1415060388.34
 multiple escaped initial underscores must be unescaped.      | owner:, open:True, id:314e45488da4c7c8298c4c64ece03359918d057b, time:1415959749.14
 wisp: handle general paren prefixes like quote, quasiquote, etc. | owner:, open:False, id:323ff94b5be635742619467e1cb44f4c0d96f63f, time:1379047798.47
 throw an exception when reducing indentation to an unknown indentation level. | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:424186bd85f186b7279c5c59e2bd42f847284719, time:1376003568.91
+LANG=C breaks bootstrap: python encoding error: it uses ascii. | owner:, open:True, id:43c7461bfb6f35a90ff3f4497c8232e2457ce1c7, time:1427819877.7
 wisp-in-wisp: only parses the first 272 lines, for some reason. | owner:, open:False, id:4cb6c556d7136609e2da9ab3fc045a39847f1ef3, time:1377014682.98
 adjust runtests.sh to use testrunner.w                       | owner:, open:False, id:4d4e76343fe09f0ec72a3e5eb0077bd16e12f9d5, time:1415127234.43
-wisp-scheme: REPL: sometimes the output of a command is only shown after typing the next non-empty line. | owner:, open:True, id:56d2f81e9c89accb0b0bc668ddc8feed3b60e9b2, time:1416584789.23
+wisp-scheme: REPL: sometimes the output of a command is only shown after typing the next non-empty line. | owner:, open:False, id:56d2f81e9c89accb0b0bc668ddc8feed3b60e9b2, time:1416584789.23
 implement wisp in wisp                                       | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:6299306916706410702029289bf32edab1e7f17c, time:1367113341.49
 support other types of brackets, like square brackets.       | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:6749f3abcb9455eac9271efd8265797bce114239, time:1389134151.98
 linebreaks in parens still break                             | owner:, open:False, id:6797987c7834a53358fb4ebbd8b9b36c2c4a8f01, time:1379004764.14
@@ -20,7 +23,7 @@ wisp-guile.w does not yet remove the lea
 inline ' : should be '(                                      | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:72d534a8b23b4cb168017f1bb7d8816f0ea170c4, time:1366497335.26
 failing test tests/shebang.w                                 | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:74a851f83af8996465a7b24d8453161beb0f0fd5, time:1379106761.57
 non-nested multiline comments with #! !#. Requires restructuring. | owner:, open:False, id:7a57614fa920b2ddad002d044b144d0bb7c34f84, time:1389364108.01
-wisp-scheme: interpret , : as ,() similar to : ,             | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:85e150dcb10c49d8f51db525e07d24e83bdba0f1, time:1416432201.21
+wisp-scheme: interpret , : as ,() similar to : ,             | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:85e150dcb10c49d8f51db525e07d24e83bdba0f1, time:1416432201.21
 wisp-guile: support nested multi-line comments with #| ... |#: multiline comments (srfi-30). Requires restructuring. | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:8cf6202873d4454f57813dd17cf60432059f7c62, time:1389569421.6
 wisp-scheme: Does not recognize the . #!curly-infix request for curly-infix or other reader syntax. | owner:Arne Babenhauserheide <bab@draketo.de>, open:True, id:91f27adb7d4e378e034b3408b6e4616f707f9587, time:1418162368.88
 wisp-guile: the repl does not require 3 returns when you use a single char as function, or rather only does so every second time | owner:, open:True, id:9cedd0bdbf4a3b17add4bfe86ad5a23e500cfc6c, time:1379064870.78
@@ -36,4 +39,5 @@ comments containing a closing parenthesi
 breaks on empty files                                        | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:e40fa7a93eb2c497dca1af7eed22ad5ed5cfbe7f, time:1390325470.91
 wisp-scheme: breaks on lines with only underscores. These should be treated as empty lines. | owner:, open:False, id:e464b5ce49deb14a80f67d50c6d70043ca9bde25, time:1415124488.16
 quote as only char in a line gets parenthized instead of becoming a paren-prefix. | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:eb7468387e90bb5d13f5a5d81c6f4a704f2ca0fb, time:1390326369.6
-in the REPL output can be delayed by one line: Appears only when submitting the next command. | owner:, open:True, id:f1e42bbd4c17a2dec886c26d9c14e770bcff66d2, time:1415972414.48
+in the REPL output can be delayed by one line: Appears only when submitting the next command. | owner:, open:False, id:f1e42bbd4c17a2dec886c26d9c14e770bcff66d2, time:1415972414.48
+wisp-scheme: parser problem with dotted pair: use-modules : (ice-9 popen) #:select ((open-input-pipe . oip)) | owner:Arne Babenhauserheide <bab@draketo.de>, open:False, id:ff078cba853c1a2fdbd41cf0228ad7920a642c0d, time:1428358435.75
diff --git a/.hgsigs b/.hgsigs
--- a/.hgsigs
+++ b/.hgsigs
@@ -17,3 +17,7 @@ 32659321b29470b5198827eda494d9824cc161ee
 eaf23f42b01382e4ab255abcd34e031b043e1f56 0 iQEcBAABAgAGBQJUP+zuAAoJEFyD82SnDaCeXRkH/iZOiyKj8VcuNJdpSZKqIvzNRMz5JhIiF3G04zzHs8jDxrJiGVVHWPYNXR0p7pChMsq5JanjrnQn2IGcGt7blB1fmjzhq6bwbru+sD2moisP/zFM1HOSKx0j7xsNwB8wd08l0GVbNzgffRZjwQbJkCov8Uvl60OLUHgH5Pro8CRkKwV8/6pG8a9TtGEMlnhdhw/L5wkeSkifFTgg2R/CCHAJDhgfSAUZfjQzPgvtLUMHe+0Og/hwgnMqpI/TMoxAyOSBHbAGiZGDUb3v+sXB84k7kd9gm59A3s805L1PEeqlhTE2FWAGBV8se7NeNIygnUfmXgPFclrZSB2QF1qguz4=
 695e3f4ff4bd2512e2d963c5b21385415c3b6dc3 0 iJsEAAEIAAYFAlRb4xsACgkQ3M8NswvBBUiRugP41O3ZOBViEjB0y4smTiU/yju4b/xJczLBhbNM1ExKu/EB3oQkAPpZhnBQcOPz43TMl2Kk8QKJgFcgeHKQlT+ZyMxZ0j7/GOSBxTH2Q1x5SXwJlnJAdmSH7UE2i5btEsemjkqAuqOlkX+z7QIswFSv7yHoBVh/Qs9AvcY0cCKFYw==
 fed7f4d46a41b0814c81eb08dcdb506b38321c61 0 iQEcBAABAgAGBQJUbMOkAAoJEKMv031G/7TThsYIALXZAJY4Z4n5Be6mTE/CRXE7g3GlDEBPwstnvUBNzXiM5dAQbLHUt71yRx+d2WxxRHxUfuWG8PgrO/beITdjWhwoaM0fhknPRIOZ3Sc3RSrtleTm9gx1DS6CW5sCQvmqRSdyYJlqS30oHiq/gPftmFq2CllrSZWblL+t+/BfBLfG26DN4jy/b0IN5J1qeoi4gP/FwQ3e8A1lUIznjzQa57BVGBc/kKA+pAy/yFAlFvukAOG0BbFGRe0K3Gj6xITLdxfrmndH/688jgefUp+7JhLZZkfIoFAWBosPRQ5a2zaB1YRtUMEKgvvA05UiyTLQdlME2d52X1sSKrS9p69sTUU=
+36b8c0daff2cd8cadb73b0dcc19c16a60f5b58eb 0 iJwEAAEIAAYFAlUKBPEACgkQ3M8NswvBBUgDugP8C6yJk7LyLOFMGoKLmnBin1dc9uuaj7idhx24tjgLjxLoM06I6QxkWPSEoKgVUR01Euu0EbXaoJogAaOUlaUTZPeSeSAZStvTmXveWL4P1VIQoERy1hmia+tMPxQKXkXf5R0YRwdmiqOh1AoH8dVdkCsCfplBc3VGrdDN4caZP00=
+a8ea98c78d90ae3e1b4daaf4bab3e2a7a847a06f 0 iJwEAAEIAAYFAlUoSqEACgkQ3M8NswvBBUihJQP/XB8kHNEcsTj5pgBtMepmIX/3CmVaz6ZNgzhSzJSS1oz2DMbXPJh32QaDwRd5wCoNksD00ch7e9UWhTSZztI/yDY9KwZrTV/OIDFzIdfSsdDO4J0WNxHmgymHSfitCjHcgSvT/C9/mubhNECPrQQUx08FMnNiNvcmGpwVOwakNNw=
+41a3bcb0e07cff2119e6df4574afe7af01231724 0 iQEcBAABAgAGBQJViY75AAoJEFyD82SnDaCexVAH/1TKjisW+ka4V+1Hk6L+rd+35Migij9RzfMYwfaHzi9GtpuqkDrjrRxlh8R6P/b+bHTTXwfcZ1mk6Otstsutg/469qBfF5Mb09Zoi0y4g6xt6O75Jcac8vT3Sx22hUoh0GwqRMd7DZcNjO8tTOwV0Ssraqs2VURXwIF11D9g8weconamgQqs7uWgQ4Ku6qUXFfbzv0Sk3GHCyRfzwu3IZkvXymi+sVBNmq9Wtzn14tTsgOeFSmDL8EREK/yENyckzZbxbLO8TrNmL2VeZ6SidBDOaf9nDoyh2dWYdi10dxt7lbjcaPlYXEdSxm3V7fSp8d/kF5DMuefcGThZfKsE5aM=
+22bf6277df51f10ca9192bde088e6c062f9190a8 0 iQEcBAABAgAGBQJVt5NXAAoJEFyD82SnDaCevQIH/RIYkKQLBklUHMYvHO655PXNAHpU0OSMAjnggTiuNrY6IZqQASj/AWdAopPXMh5KrJ25Sg5ktlnxEw5paA68CFZCsc9HHuBwffkgN1kjOqafyI9FA46obCCnly1Mpo4814R+LbdUtcPerTDy4cJq6FlQal2l130Hi0ASVvfqqT73NbAl3EtBnYF2ecTiklHiUCZLlgMUXSBf3UxF3xzoY1g1tbtktVTVHbh+MDYPjpaM3y2CiYCaicS2kMyFRaNGEmh+4oHSAwEu9i6pZQtuhJItehbT+qNDJMc+Zs5DmYbH60Osv1mVn9MjQTeKoIWuBRHyPwuZXOstaYlNkSNqsvI=
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -25,3 +25,8 @@ 42ab97d010efa7883240f5e5254ea46fd9423239
 b7441736af4dc8f1a7df860d1b064e080a45e1a5 v0.6.6
 0e702c268e6fdc9c52f034b6553c940b09c16400 v0.8.0
 8eaf023f5d3bc20ad4b795cde3a92e3b5c242dba v0.8.1
+327acbae68ef4efbf77734f0ee20359ed559ce0d v0.8.2
+41c48043ca33bf47311a93d0545b13a0578c3cf0 v0.8.3
+a4bca2a0f2f6659d97b1db471ae9803119b80529 v0.8.4
+f0096bf5f3baee5017be94f49c70515fe2a535b3 wisp-mode-0.2.1
+fb551bbe7084d22ef0c8e35df3864eb2aef46005 v0.8.5
diff --git a/Changelog b/Changelog
deleted file mode 100644
--- a/Changelog
+++ /dev/null
@@ -1,32 +0,0 @@
-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/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,39 @@
+wisp 0.8.5 (2015-07-28):
+- wisp-scheme.w now parses : . to nothing. The colon adds parens, the
+  dot removes them. This provides compatibility to the older parser.
+- wisp is now SRFI-119: http://srfi.schemers.org/srfi-119/srfi-119.html
+
+wisp 0.8.4 (2015-06-23):
+- no longer wrap wisp blocks into begin. Fixes missing macro
+  definitions when executed as file.
+- any top-level form ends a wisp block. Required to avoid wrapping in
+  begin. In the REPL code is now executed when entering the first line
+  of the next top-level form.
+- new examples: newbase60 and cli.
+- known issue: To execute a procedure with shell-indirection, you have
+  to define a module.
+- wisp-mode: disable electric-indent-mode which reindented lines
+  wrongly when pressing enter.
+
+wisp 0.8.3 (2015-04-10):
+- add partial source-properties support: show line numbers in backtraces.
+- d20world: start of experiement to plot the results.
+
+wisp 0.8.2 (2015-03-18):
+- resolve REPL delayed output bug.
+- forbid dot at the end of a line and as only symbol in a line to reserve them for future use.
+- generalized the shell-call to guile: It gets the parentdir from $0.
+- note curly braces, neoteric expressions and dual-wisp-sweet syntax.
+- added tests: sxml, self-referencial function, curly-infix.
+- new example: beautiful factorial.
+- new example: ensemble estimation with ensemble square root filter. Uses python driven by an output-pipe as a plotting tool.
+- SRFI 119 in draft.
+
+wisp 0.8.1 (2014-11-19):
+- srfi: polish implementation notes.
+- add the requirements to the syntax-examples.
+- wisp-scheme.w works completely again.
+
 wisp 0.8.0 (2014-11-03):
 - the testsuite is defined in terms of the code-tree, not in terms of
   the readable file. Implemented in testrunner.w
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 dnl run `autoreconf -i` to generate a configure script. 
 dnl Then run ./configure to generate a Makefile.
 dnl Finally run make to generate the project.
-AC_INIT([wisp], [0.8.1],
+AC_INIT([wisp], [0.8.5],
         [arne_bab@web.de])
 # Check for programs I need for my build
 AC_CANONICAL_TARGET
diff --git a/docs/srfi-from-template.html b/docs/srfi-from-template.html
--- a/docs/srfi-from-template.html
+++ b/docs/srfi-from-template.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
 <html>
   <head>
-    <title>SRFI ?: wisp: simpler indentation-sensitive scheme</title>
+    <title>SRFI 119: wisp: simpler indentation-sensitive scheme</title>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   </head>
   <body>
@@ -12,11 +12,31 @@ wisp: simpler indentation-sensitive sche
 
 <H1>Author</H1>
 
-<ul>
-<li>Arne Babenhauserheide
-</li>
+Arne Babenhauserheide
+
+<H1>Status</H1>
+
+<p>
+This SRFI is currently in ``draft'' status.
+To see an explanation of
+each status that a SRFI can hold, see <a
+href="http://srfi.schemers.org/srfi-process.html">here</a>.
+
+To provide input on this SRFI, please
+<a href="mailto:srfi minus 119 at srfi dot schemers dot org">mail to
+<code><srfi minus 119 at srfi dot schemers dot org></code></a>.  See
+<a href="../srfi-list-subscribe.html">instructions here</a> to
+subscribe to the list.  You can access previous messages via
+<a href="mail-archive/maillist.html">the archive of the mailing list</a>.
+</p><ul>
+    <li>Received: <a
+    href="http://srfi.schemers.org/cgi-bin/viewcvs.cgi/*checkout*/srfi/srfi-119/srfi-119.html?rev=1.1">2015/01/25</a></li>
+      <li>Draft: 2015/02/03-2015/04/03</li>
+    <li>Revised: <a
+    href="http://srfi.schemers.org/cgi-bin/viewcvs.cgi/*checkout*/srfi/srfi-119/srfi-119.html?rev=1.2">2015/06/23</a></li>
 </ul>
 
+
 <h3>Acknowledgments</h3>
 <ul>
 <li>Thanks for many constructive discussions goes to Alan Manuel K. Gloria and David A. Wheeler.
@@ -40,27 +60,33 @@ It resolves a limitation of <a href="htt
 </p>
 
 <p>
-Wisp expressions can include any s-expressions and as such provide backwards compatibility.
+Wisp expressions can include arbitrary s-expressions and as such provide backwards compatibility.
 </p>
 
+<blockquote>
 <table><tr><th>wisp</th><th>s-exp</th></tr><tr><td>
-<pre><b>define</b> : <i>hello</i> who   
-  <i>format</i> #t "~A ~A!\n"    
-          . "Hello" who   
-<i>hello</i>       "Wisp"        
+<pre>
+<b>define</b> : <i>factorial</i> n
+__  <b>if</b> : <i>zero?</i> n
+____   . 1
+____   <i>*</i> n : <i>factorial</i> (- n 1)
+
+<i>display</i> : <i>factorial</i> 5 
+<i>newline</i>
 </pre>
+</blockqote>
 </td><td>
-<pre>(<b>define</b> (<i>hello</i> who)
-  (<i>format</i> #t "~A ~A!\n"
-             "Hello" who))
-(<i>hello</i>       "S-exp")
+<pre>
+(<b>define</b> (<i>factorial</i> n)
+    (<b>if</b> (<i>zero?</i> n)
+       1
+       (<i>*</i> n (<i>factorial</i> (- n 1)))))
+
+(<i>display</i> (<i>factorial</i> 5))
+(<i>newline</i>)
 </pre>
 </td></tr></table>
-
-<H1>Issues</H1>
-
-<ul>
-<li>wisp-scheme: REPL: sometimes the output of a command is only shown after typing the next non-empty line.</li></ul>
+</blockquote>
 
 <H1>Rationale</H1>
 
@@ -115,7 +141,7 @@ Wisp expressions can include any s-expre
 
 <h2>Wisp example</h2>
 
-Since an example speaks more than a hundred explanations, the following shows wisp exploiting all its features - including curly-infix from <a href="http://srfi.schemers.org/srfi-105/srfi-105.html">SRFI 105</a>:
+Since an example speaks more than a hundred explanations, the following shows wisp exploiting all its features - including compatibility with curly-infix from <a href="http://srfi.schemers.org/srfi-105/srfi-105.html">SRFI 105</a>:
 
 <blockquote>
 <pre>
@@ -485,6 +511,12 @@ Effectively code in parentheses and stri
 
 <li>The suggested suffix for files using wisp-syntax is <code>.w</code>.
 
+<li>To represent tail notation like <code>(define (foo . args))</code>, either avoid a linebreak before the dot as in <code>define : foo . args</code> or use a double dot to start the line: <code>. . args</code>. The first dot mark the line as continuation, the second enters the scheme code.</li>
+
+<li>A dot as symbol at the end of a line is reserved for potential future use. It should be a syntax error if the next non-empty line starts with non-zero indentation. A lone dot at the end of a line calls for hard to catch errors.</li>
+
+<li>A dot as only symbol in a line has no useful meaning: the line is by definition empty. As such, a dot as only symbol on a line is also reserved for future use and should be treated as a syntax error to avoid locking out future possibilities.</li>
+
 </ul>
 
 
@@ -723,10 +755,10 @@ FROM, OUT OF OR IN CONNECTION WITH THE S
 DEALINGS IN THE SOFTWARE.
 
     <hr>
-    <address>Editor: <a href="mailto:srfi-editors at srfi dot schemers dot org">Dave Mason</a></address>
+    <address>Editor: <a href="mailto:srfi-editors at srfi dot schemers dot org">Michael Sperber</a></address>
 <!-- Created: Tue Sep 29 19:20:08 EDT 1998 -->
 <!-- hhmts start -->
-Last modified: Sun Jan 28 14:21:14 MET 2007
+Last modified: Thu Mar 12 08:52:43 MET 2015
 <!-- hhmts end -->
   </body>
 </html>
diff --git a/examples/cli.w b/examples/cli.w
new file mode 100755
--- /dev/null
+++ b/examples/cli.w
@@ -0,0 +1,16 @@
+#!/usr/bin/env sh
+# -*- wisp -*-
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples cli) main)' -s "$0" "$@"
+; !#
+
+define-module : examples cli
+              . #:use-module : ice-9 match
+
+define : main args
+         match args
+           : prog ; just the program name, empty call
+             display : car args
+           else
+             display args
+         newline
+
diff --git a/examples/d20world.w b/examples/d20world.w
--- a/examples/d20world.w
+++ b/examples/d20world.w
@@ -17,6 +17,9 @@ define-module : examples d20world
               . #:export : world neighbors d20-as-text d20-diffuse
 
 use-modules : ice-9 format
+use-modules 
+  : ice-9 popen
+        . #:select : open-output-pipe close-pipe
 
 define world : make-vector 20 0
 define neighbors : make-vector 20
@@ -211,6 +214,7 @@ define : latlon2cellidx lat lon
 
 display : d20-as-text world
 newline
+
 format #t "Diffuse ~A\n" 0.01
 d20-diffuse world neighbors 0.01
 display : d20-as-text world
@@ -282,3 +286,52 @@ let loop : : steps 1000
         loop : 1- steps
 display : d20-as-text world
 newline
+
+; now plot the result
+let : : port : open-output-pipe "python"
+  format port "from mpl_toolkits.mplot3d import Axes3D, art3d
+import numpy as np
+import scipy as sp
+from matplotlib import cm
+import matplotlib.pyplot as plt
+from scipy.spatial import Delaunay
+
+def Icosahedron():
+    h = 0.5*(1+np.sqrt(5))
+    p1 = np.array([[0,1,h],[0,1,-h],[0,-1,h],[0,-1,-h]])
+    p2 = p1[:,[1,2,0]]
+    p3 = p1[:,[2,0,1]]
+    return np.vstack((p1,p2,p3))
+
+Ico = Icosahedron()
+tri = Delaunay(Ico)
+CH = tri.convex_hull
+points = tri.points
+
+fig = plt.figure(figsize=(4.0,4.0))
+ax = fig.add_subplot(111, projection='3d')
+
+print points
+for i in range(points.shape[0]):
+    neighbors = tri.neighbors[i,:]
+    for n in range(points.shape[0]):
+        pts = []
+        for u in range(points.shape[0]):
+            pt = np.zeros((3,3))
+            pt[0,:] = points[(i),:]
+            pt[1,:] = points[(n),:]
+            pt[2,:] = points[(u),:]
+            # print pt
+            pt *= 0.5
+            pt += 0.5
+            pts.append(pt)
+        tr = art3d.Poly3DCollection(pts)
+        tr.set_color([(0.9*i)/points.shape[0]] + [(0.9*n)/points.shape[0]]*3)
+        ax.add_collection3d(tr)
+# ax.plot_surface(x, y, z, color='g')
+
+plt.show()
+
+exit()\n"
+  close-pipe port
+
diff --git a/examples/d6.w b/examples/d6.w
--- a/examples/d6.w
+++ b/examples/d6.w
@@ -2,7 +2,7 @@
 ; !#
 
 define-module : examples d6
-   . #:export : roll check 
+   . #:export : roll check
 
 ; basic d6 rules, implemented in guile
 
@@ -23,3 +23,5 @@ define : check skill target effect-thres
 display : check 12 9 3
 newline
 display : roll
+
+
diff --git a/examples/ensemble-estimation.w b/examples/ensemble-estimation.w
--- a/examples/ensemble-estimation.w
+++ b/examples/ensemble-estimation.w
@@ -1,4 +1,5 @@
 #!/usr/bin/env sh
+# -*- wisp -*-
 exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples ensemble-estimation) main)' -s "$0" "$@"
 ; !#
 
diff --git a/examples/evolve.w b/examples/evolve.w
--- a/examples/evolve.w
+++ b/examples/evolve.w
@@ -1,4 +1,5 @@
 #!/usr/bin/env sh
+# -*- wisp -*-
 exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples evolve) main)' -s "$0" "$@"
 ; !#
 
@@ -8,10 +9,9 @@ exec guile -L $(dirname $(dirname $(real
 
 ; NOTE: This only works after preprocessing to scheme.
 
-; run via 
-; PATH=../guile-2.0.11/meta:$PATH GUILE_LOAD_PATH=. ./wisp-multiline.sh examples/evolve.w 
+define-module : examples evolve
+              . #:export : main
 
-define-module : examples evolve
 ; Get the eval string which allows for selecting the language.
 use-modules : ice-9 eval-string
 
@@ -145,7 +145,7 @@ define : evolution initialstring steps
                   evolution-step string
 
                     
-define : run 
+define : main args
        ; firstoff, seed the random number generator!
        set! *random-state* : random-state-from-platform
        let 
diff --git a/examples/factorial.w b/examples/factorial.w
new file mode 100755
--- /dev/null
+++ b/examples/factorial.w
@@ -0,0 +1,16 @@
+#!/usr/bin/env sh
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples factorial) main)' -s "$0" "$@"
+; !#
+
+define-module : examples factorial
+              . #:export : factorial
+
+define : factorial n            ;   (define (factorial n)
+    if : zero? n                ;       (if (zero? n)
+       . n                      ; =>        n
+       * n : factorial {n - 1}  ;           (* n (factorial {n - 1}))))
+
+define : main args
+         display : factorial 5
+         newline
+
diff --git a/examples/fizzbuzz.w b/examples/fizzbuzz.w
--- a/examples/fizzbuzz.w
+++ b/examples/fizzbuzz.w
@@ -9,16 +9,18 @@ define : divisible? number divisor
          = 0 : remainder number divisor
 
 define : fizzbuzz
-  let : : print_number #f
-    loop : : for i : up-from 1 : to 100
-        set! print_number #t
-        when : divisible? i 3
-            display "Fizz"
-            set! print_number #f
-        when : divisible? i 5
-            display "Buzz"
-            set! print_number #f;
-        when print_number : display i
-        newline
+  let
+    : print_number #f
+    loop
+      : for i : up-from 1 : to 100
+      set! print_number #t
+      when : divisible? i 3
+          display "Fizz"
+          set! print_number #f
+      when : divisible? i 5
+          display "Buzz"
+          set! print_number #f;
+      when print_number : display i
+      newline
 
 fizzbuzz
diff --git a/examples/kit-encode.w b/examples/kit-encode.w
--- a/examples/kit-encode.w
+++ b/examples/kit-encode.w
@@ -1,6 +1,10 @@
-#!./wisp-multiline.sh
+#!/usr/bin/env sh
+# -*- wisp -*-
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples kit-encode) main)' -s "$0" "$@"
 ; !#
 
+define-module : examples kit-encode
+              . #:export : main kittify kittifylarge unkittify kittyfile kittytextfile unkittyfile unkittytextfile
 use-modules 
   srfi srfi-1
   rnrs io ports
@@ -257,55 +261,52 @@ define : unkittytextfile filepath
 ; displaywithnewline : kittyfile ".hg/store/00changelog.i"
 ; displaywithnewline : unkittytextfile "1.kit"
 
-; Now for the ultimate Kittyfication
-
-displaywithnewline "
-     === TEXT MODE ==="
-
-displaywithnewline : kittify : map shiftbytedownfortext : bytevector->u8-list : string->utf8 "Karlsruhe Institut für Technologie (KIT)"
-
-displaywithnewline : utf8->string : u8-list->bytevector : map shiftbyteupfortext : unkittify "
-     A.Y  .p.i    .q.p .s.e .b.3i.8.
-      k.q  .r.  f.r.   s.r. 3i.c.2A.
- 23.p   .3 i.K.b._     .e.k   .m.i
-    .m.d .f .b.3i.3    r.A.   8.K.
-3s..    .... .  ....   ....   ....
-..............    .... ....   ....
-Karlsruher Institut fuer Technologie
-"
-
-
-displaywithnewline "
-
-     === BINARY MODE ==="
-
-displaywithnewline : kittify : bytevector->u8-list : string->utf8 "Karlsruhe Institut für Technologie (KIT)"
-
-displaywithnewline : utf8->string : u8-list->bytevector : unkittify "
-     1F.  1c.1    u.1o .1v. 1u.1x.1j
-      .1g  .Y.  1D.1   q.1v .1w.1k.1
- w.1x   .1 w.Y.1h.     3F.3   8.1u
-    .Y.1 Q. 1g.1e.1    j.1q   .1r.
-1o.1    r.1i .  1k.1   g.Y.   f.1F
-.1D.1Q.g......    .... ....   ....
-Karlsruher Institut fuer Technologie
-"
-
-
-displaywithnewline "
-
-     === KIT, IMK, RemoteC ==="
-
-displaywithnewline : kittify : map shiftbytedownfortext : bytevector->u8-list : string->utf8 "Karlsruhe Institut für Technologie (KIT), IMK-ASF, RemoteC"
-
-
-displaywithnewline "
-
-     === kittifyscript ==="
-
-displaywithnewline : kittytextfile "examples/kit-encode.w"
-
-
-
+define : main args
+  . "The ultimate Kittyfication"
+  displaywithnewline "
+       === TEXT MODE ==="
+  
+  displaywithnewline : kittify : map shiftbytedownfortext : bytevector->u8-list : string->utf8 "Karlsruhe Institut für Technologie (KIT)"
+  
+  displaywithnewline : utf8->string : u8-list->bytevector : map shiftbyteupfortext : unkittify "
+       A.Y  .p.i    .q.p .s.e .b.3i.8.
+        k.q  .r.  f.r.   s.r. 3i.c.2A.
+   23.p   .3 i.K.b._     .e.k   .m.i
+      .m.d .f .b.3i.3    r.A.   8.K.
+  3s..    .... .  ....   ....   ....
+  ..............    .... ....   ....
+  Karlsruher Institut fuer Technologie
+  "
+    
+  displaywithnewline "
+  
+       === BINARY MODE ==="
+  
+  displaywithnewline : kittify : bytevector->u8-list : string->utf8 "Karlsruhe Institut für Technologie (KIT)"
+  
+  displaywithnewline : utf8->string : u8-list->bytevector : unkittify "
+       1F.  1c.1    u.1o .1v. 1u.1x.1j
+        .1g  .Y.  1D.1   q.1v .1w.1k.1
+   w.1x   .1 w.Y.1h.     3F.3   8.1u
+      .Y.1 Q. 1g.1e.1    j.1q   .1r.
+  1o.1    r.1i .  1k.1   g.Y.   f.1F
+  .1D.1Q.g......    .... ....   ....
+  Karlsruher Institut fuer Technologie
+  "
+  
+  displaywithnewline "
+  
+       === KIT, IMK, RemoteC ==="
+  
+  displaywithnewline : kittify : map shiftbytedownfortext : bytevector->u8-list : string->utf8 "Karlsruhe Institut für Technologie (KIT), IMK-ASF, RemoteC"
+  
+  displaywithnewline "
+  
+       === kittifyscript ==="
+  
+  displaywithnewline : kittytextfile "examples/kit-encode.w"
+  
+  
+  
 ; TODO: Final step: Add commandline handling which allows to write into files and set the text flag and so on.
 ; ./kit-encode [-e|--encode|-d|--decode] [--text] [--template file] [--killstring "stringtoremove" (mutliple times)] [-o|--output file] [file|-]
diff --git a/examples/map-product-sums.w b/examples/map-product-sums.w
new file mode 100644
--- /dev/null
+++ b/examples/map-product-sums.w
@@ -0,0 +1,23 @@
+#!/usr/bin/env sh
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples map-product-sums) main)' -s "$0" "$@"
+; !#
+
+use-modules : (srfi srfi-42) 
+
+define-module : examples map-product-sums
+
+define : list-product-sums list-of-numbers
+       . "return a list with the sum of the products of each number with all other numbers.
+
+         >>> map-product-sums '(2 4 6)
+         (list (+ (* 2 4) (* 2 6)) (+ (* 4 2) (* 4 6)) (+ (* 6 2) (* 6 4)))
+         "
+       map (lambda (x) (apply + x))
+           list-ec (: i list-of-numbers)
+               map (lambda (x) (* i x))
+                   cons (- i) list-of-numbers
+
+
+define : main . args
+  write : list-product-sums '(2 4 6)
+
diff --git a/examples/multithreaded-magic.w b/examples/multithreaded-magic.w
--- a/examples/multithreaded-magic.w
+++ b/examples/multithreaded-magic.w
@@ -1,6 +1,9 @@
-#!./wisp-multiline.sh
+#!/usr/bin/env sh
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples multithreaded-magic) main)' -s "$0" "$@"
 ; !#
 
+define-module : examples multithreaded-magic
+
 ; Mathematical magic: Always get one.
 ; 
 ; Via http://www.liv.ac.uk/HPC/HTMLF90Course/HTMLF90CourseQuestionsnode18.html
@@ -8,6 +11,8 @@
 ; 
 ; this is the wisp scheme version which I want to compare with the fortran version.
 
+; Call as PATH=~/guile/meta:$PATH ./examples/multithreaded-magic.w
+
 use-modules 
   ice-9 format
   ice-9 futures
@@ -15,12 +20,17 @@ use-modules
 
 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
+  let
+    :
+      futures
+        cons : future : with-mutex mutex : format #t "~30r\n" integer
+          . futures
+    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
@@ -35,7 +45,8 @@ define : magic-simple integer
       magic-simple : / integer 2
       magic-simple : truncate : + 1 : / integer 3 
 
-display ";;; multithreaded magic ;;;\n"
-magic 456189456156456196152615
-display ";;; simple magic ;;;\n"
-magic-simple 456189456156456196152615
+define : main args
+         display ";;; multithreaded magic ;;;\n"
+         magic 456189456156456196152615
+         display ";;; simple magic ;;;\n"
+         magic-simple 456189456156456196152615
diff --git a/examples/newbase60.w b/examples/newbase60.w
new file mode 100755
--- /dev/null
+++ b/examples/newbase60.w
@@ -0,0 +1,149 @@
+#!/usr/bin/env sh
+# -*- wisp -*-
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples newbase60) main)' -s "$0" "$@"
+; !#
+
+;; Encoding and decoding numbers in New Base 60 as defined by Tantek:
+;; http://tantek.pbworks.com/NewBase60
+
+;; Based on the very elegant implementation from Kevin Marks licensed under CC0:
+;; https://github.com/indieweb/newBase60py/blob/master/newbase60.py
+
+define-module : examples newbase60
+              . #:export : integer->sxg sxg->integer date->sxg sxg->date date->sxgepochdays sxgepochdays->yeardays yeardays->sxgepochdays
+              . #:use-module : srfi srfi-1
+
+define base60letters "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz"
+define base60numbers
+       append
+         map cons (string->list base60letters) : iota : string-length base60letters
+         quote
+           : #\l . 1 ; typo lowercase l to 1
+             #\I . 1 ; typo capital I to 1
+             #\O . 0 ; typo capital O to 0
+
+define : positive-integer->sxg num
+       . "Convert a positive integer to Tanteks new base 60."
+       if : equal? 0 num
+          . "0"
+          let loop
+              : s '()
+                n num
+              if : equal? n 0
+                 list->string s
+                 loop
+                   cons (string-ref base60letters (remainder n 60)) s
+                   quotient n 60
+
+define : positive-sxg->integer string
+       . "Convert a positive new base 60 string into a positive integer."
+       let loop
+         : n 0
+           s string
+         cond 
+           : equal? "" s
+             . n
+           else
+             loop
+               + : assoc-ref base60numbers : string-ref s 0
+                 * n 60
+               string-drop s 1
+
+define : integer->sxg num
+       . "Convert an integer to Tanteks new base 60."
+       if : >= num 0
+          positive-integer->sxg num
+          string-append "-" : positive-integer->sxg : - num
+
+define : sxg->integer str
+       . "Convert a new base 60 string into an integer."
+       if : and (>= (string-length str) 1) (equal? #\- (string-ref str 0))
+          - : positive-sxg->integer : string-drop str 1
+          positive-sxg->integer str
+
+define : date->sxgepochdays year month day hour minute second
+       let 
+         : tm : gmtime 0 ; initialize 
+         set-tm:year tm : - year 1900
+         set-tm:mon tm month
+         set-tm:mday tm day
+         set-tm:hour tm hour
+         set-tm:min tm minute
+         set-tm:sec tm second
+         let* 
+           : epochseconds : car : mktime tm "+0" ; 0: UTC
+             epochdays : quotient epochseconds : * 24 60 60
+           integer->sxg epochdays
+
+define : yeardays->sxgepochdays year yeardays
+       let 
+         : tm : car : strptime "%Y %j" : string-join : map number->string : list year yeardays
+         let* 
+           : epochseconds : car : mktime tm "+0" ; 0: UTC
+             epochdays : quotient epochseconds : * 24 60 60
+           integer->sxg epochdays
+
+define : sxgepochdays->yeardays str
+       . "Turn sexagesimal days since epoch into year (YYYY) and day of year (DDD)."
+       let*
+         : epochdays : sxg->integer str
+           epochseconds : * epochdays 24 60 60
+           tm : gmtime epochseconds
+           year : + 1900 : tm:year tm
+           yeardays : tm:yday tm
+         list year (+ yeardays 1)
+
+define : date->sxg year month day hour minute second
+       . "Convert a date into new base 60 format:
+          yyyymmdd hhmmss -> YYMD-hms (can extend till 3599)
+         "
+       format #f "~A-~A" 
+           apply string-append
+             map integer->sxg
+                 list year month day
+           apply string-append 
+             map integer->sxg
+                 list hour minute second
+
+define : sxg->date str
+       . "Convert a new base 60 date into a list:
+          YYMD-hms -> (year month day hour minute second)
+         "
+       let*
+         : centeridx : string-rindex str #\- ; rindex because the year could be negative
+           getstr : lambda (s di) : string : string-ref str : + centeridx di
+         let
+           : year : substring/read-only str 0 : - centeridx 2
+             month : getstr str -2
+             day : getstr str -1
+             hour : getstr str 1
+             minute : getstr str 2
+             second : getstr str 3
+           map sxg->integer 
+             list year month day hour minute second
+
+define : main args
+       let
+         : help : lambda () : format #t "usage: ~A [integer | -d string | --datetime | --datetime year month day hour minute second | --help]\n" : list-ref args 0
+         cond
+           : or (= 1 (length args)) (member "--help" args)
+             help
+           : and (= 8 (length args)) : equal? "--datetime" : list-ref args 1
+             format #t "~A\n" : apply date->sxg : map string->number : drop args 2
+           : and (= 8 (length args)) : equal? "--sxgepochdays" : list-ref args 1
+             format #t "~A\n" : apply date->sxgepochdays : map string->number : drop args 2
+           : and (= 4 (length args)) : equal? "--sxgepochdays-from-yearday" : list-ref args 1
+             format #t "~A\n" : apply yeardays->sxgepochdays : map string->number : drop args 2
+           : and (= 2 (length args)) : equal? "--datetime" : list-ref args 1
+             let : : tm : localtime : current-time
+               format #t "~A\n" : apply date->sxg : list (+ 1900 (tm:year tm)) (+ 1 (tm:mon tm)) (tm:mday tm) (tm:hour tm) (tm:min tm) (tm:sec tm)
+           : and (= 3 (length args)) : equal? "--decode-datetime" : list-ref args 1
+             format #t "~A\n" : sxg->date : list-ref args 2
+           : and (= 3 (length args)) : equal? "--decode-sxgepochdays" : list-ref args 1
+             format #t "~A\n" : sxgepochdays->yeardays : list-ref args 2
+           : and (= 3 (length args)) : equal? "-d" : list-ref args 1
+             format #t "~A\n" : sxg->integer : list-ref args 2
+           : = 2 : length args
+             format #t "~A\n" : integer->sxg : string->number : list-ref args 1
+           else
+             help
diff --git a/examples/property.w b/examples/property.w
new file mode 100755
--- /dev/null
+++ b/examples/property.w
@@ -0,0 +1,29 @@
+#!/usr/bin/env sh
+# -*- wisp -*-
+exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples property) main)' -s "$0" "$@"
+; !#
+
+define-module : examples property
+              . #:export : main
+
+; FIXME: this does not work when called from guile, but it works when
+; first translating it to scheme and then calling the scheme file.
+
+; The following works:
+
+; guile ../wisp.scm property.w > property.scm; guile -e '(@@ (examples property) main)' -s property.scm 
+
+define y 5
+define-syntax z
+  identifier-syntax : var y
+                    : set! var val
+                      set! y : + 1 val
+
+define : main args
+         write args
+         newline
+         write z
+         newline
+         set! z 5
+         write z
+         newline
diff --git a/guildhall-packages/newbase60/newbase60.scm b/guildhall-packages/newbase60/newbase60.scm
new file mode 100644
--- /dev/null
+++ b/guildhall-packages/newbase60/newbase60.scm
@@ -0,0 +1,151 @@
+#!/usr/bin/env sh
+# -*- scheme -*-
+exec guile -e '(@@ (examples newbase60) main)' -s "$0" "$@"
+; !#
+
+;; Encoding and decoding numbers in New Base 60 as defined by Tantek:
+;; http://tantek.pbworks.com/NewBase60
+
+;; Based on the very elegant implementation from Kevin Marks licensed under CC0:
+;; https://github.com/indieweb/newBase60py/blob/master/newbase60.py
+
+(define-module (examples newbase60)
+              #:export (integer->sxg sxg->integer date->sxg sxg->date date->sxgepochdays sxgepochdays->yeardays yeardays->sxgepochdays)
+              #:use-module (srfi srfi-1))
+
+(define base60letters "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz")
+(define base60numbers
+       (append
+         (map cons (string->list base60letters) (iota (string-length base60letters)))
+         (quote
+           ((#\l . 1 ); typo lowercase l to 1
+             (#\I . 1 ); typo capital I to 1
+             (#\O . 0 ))))); typo capital O to 0
+
+(define (positive-integer->sxg num)
+       "Convert a positive integer to Tanteks new base 60."
+       (if (equal? 0 num)
+          "0"
+          (let loop
+              ((s '())
+                (n num))
+              (if (equal? n 0)
+                 (list->string s)
+                 (loop
+                   (cons (string-ref base60letters (remainder n 60)) s)
+                   (quotient n 60))))))
+
+(define (positive-sxg->integer string)
+       "Convert a positive new base 60 string into a positive integer."
+       (let loop
+         ((n 0)
+           (s string))
+         (cond 
+           ((equal? "" s)
+             n)
+           (else
+             (loop
+               (+ (assoc-ref base60numbers (string-ref s 0))
+                 (* n 60))
+               (string-drop s 1))))))
+
+(define (integer->sxg num)
+       "Convert an integer to Tanteks new base 60."
+       (if (>= num 0)
+          (positive-integer->sxg num)
+          (string-append "-" (positive-integer->sxg (- num)))))
+
+(define (sxg->integer str)
+       "Convert a new base 60 string into an integer."
+       (if (and (>= (string-length str) 1) (equal? #\- (string-ref str 0)))
+          (- (positive-sxg->integer (string-drop str 1)))
+          (positive-sxg->integer str)))
+
+(define (date->sxgepochdays year month day hour minute second)
+       (let 
+         ((tm (gmtime 0 ))); initialize 
+         (set-tm:year tm (- year 1900))
+         (set-tm:mon tm month)
+         (set-tm:mday tm day)
+         (set-tm:hour tm hour)
+         (set-tm:min tm minute)
+         (set-tm:sec tm second)
+         (let* 
+           ((epochseconds (car (mktime tm "+0" ))); 0: UTC
+             (epochdays (quotient epochseconds (* 24 60 60))))
+           (integer->sxg epochdays))))
+
+(define (yeardays->sxgepochdays year yeardays)
+       (let 
+         ((tm (car (strptime "%Y %j" (string-join (map number->string (list year yeardays)))))))
+         (let* 
+           ((epochseconds (car (mktime tm "+0" ))); 0: UTC
+             (epochdays (quotient epochseconds (* 24 60 60))))
+           (integer->sxg epochdays))))
+
+(define (sxgepochdays->yeardays str)
+       "Turn sexagesimal days since epoch into year (YYYY) and day of year (DDD)."
+       (let*
+         ((epochdays (sxg->integer str))
+           (epochseconds (* epochdays 24 60 60))
+           (tm (gmtime epochseconds))
+           (year (+ 1900 (tm:year tm)))
+           (yeardays (tm:yday tm)))
+         (list year (+ yeardays 1))))
+
+(define (date->sxg year month day hour minute second)
+       "Convert a date into new base 60 format:
+          yyyymmdd hhmmss -> YYMD-hms (can extend till 3599)
+         "
+       (format #f "~A-~A" 
+           (apply string-append
+             (map integer->sxg
+                 (list year month day)))
+           (apply string-append 
+             (map integer->sxg
+                 (list hour minute second)))))
+
+(define (sxg->date str)
+       "Convert a new base 60 date into a list:
+          YYMD-hms -> (year month day hour minute second)
+         "
+       (let*
+         ((centeridx (string-rindex str #\- )); rindex because the year could be negative
+           (getstr (lambda (s di) (string (string-ref str (+ centeridx di))))))
+         (let
+           ((year (substring/read-only str 0 (- centeridx 2)))
+             (month (getstr str -2))
+             (day (getstr str -1))
+             (hour (getstr str 1))
+             (minute (getstr str 2))
+             (second (getstr str 3)))
+           (map sxg->integer 
+             (list year month day hour minute second)))))
+
+(define (main args)
+       (let
+         ((help (lambda () (format #t "usage: ~A [integer | -d string | --datetime | --datetime year month day hour minute second | --help]\n" (list-ref args 0)))))
+         (cond
+           ((or (= 1 (length args)) (member "--help" args))
+             (help))
+           ((and (= 8 (length args)) (equal? "--datetime" (list-ref args 1)))
+             (format #t "~A\n" (apply date->sxg (map string->number (drop args 2)))))
+           ((and (= 8 (length args)) (equal? "--sxgepochdays" (list-ref args 1)))
+             (format #t "~A\n" (apply date->sxgepochdays (map string->number (drop args 2)))))
+           ((and (= 4 (length args)) (equal? "--sxgepochdays-from-yearday" (list-ref args 1)))
+             (format #t "~A\n" (apply yeardays->sxgepochdays (map string->number (drop args 2)))))
+           ((and (= 2 (length args)) (equal? "--datetime" (list-ref args 1)))
+             (let ((tm (localtime (current-time))))
+               (format #t "~A\n" (apply date->sxg (list (+ 1900 (tm:year tm)) (+ 1 (tm:mon tm)) (tm:mday tm) (tm:hour tm) (tm:min tm) (tm:sec tm))))))
+           ((and (= 3 (length args)) (equal? "--decode-datetime" (list-ref args 1)))
+             (format #t "~A\n" (sxg->date (list-ref args 2))))
+           ((and (= 3 (length args)) (equal? "--decode-sxgepochdays" (list-ref args 1)))
+             (format #t "~A\n" (sxgepochdays->yeardays (list-ref args 2))))
+           ((and (= 3 (length args)) (equal? "-d" (list-ref args 1)))
+             (format #t "~A\n" (sxg->integer (list-ref args 2))))
+           ((= 2 (length args))
+             (format #t "~A\n" (integer->sxg (string->number (list-ref args 1)))))
+           (else
+             (help)))))
+
+
diff --git a/guildhall-packages/newbase60/pkg-list.scm b/guildhall-packages/newbase60/pkg-list.scm
new file mode 100644
--- /dev/null
+++ b/guildhall-packages/newbase60/pkg-list.scm
@@ -0,0 +1,6 @@
+(package (newbase60 (0))
+         (synopsis "Implementation of Tanteks New Base 60")
+         (libraries
+          (scm -> "newbase60"))
+         (programs
+          ("newbase60.scm")))
diff --git a/tests/dotted-pair.scm b/tests/dotted-pair.scm
new file mode 100644
--- /dev/null
+++ b/tests/dotted-pair.scm
@@ -0,0 +1,3 @@
+(use-modules ((ice-9 popen) #:select ((open-input-pipe . oip))))
+
+
diff --git a/tests/dotted-pair.w b/tests/dotted-pair.w
new file mode 100644
--- /dev/null
+++ b/tests/dotted-pair.w
@@ -0,0 +1,1 @@
+use-modules : (ice-9 popen) #:select ((open-input-pipe . oip))
diff --git a/tests/quotecolon.scm b/tests/quotecolon.scm
--- a/tests/quotecolon.scm
+++ b/tests/quotecolon.scm
@@ -9,4 +9,4 @@
   (a b)
   (c))
 
-
+(define a (quasiquote ,(+ 2 2)))
diff --git a/tests/quotecolon.w b/tests/quotecolon.w
--- a/tests/quotecolon.w
+++ b/tests/quotecolon.w
@@ -8,3 +8,5 @@ define a ' : 1 2 3
 define
   a b
   c
+
+define a : quasiquote , : + 2 2
diff --git a/wisp-guile.w b/wisp-guile.w
--- a/wisp-guile.w
+++ b/wisp-guile.w
@@ -19,6 +19,29 @@
 ;; 
 ;; -Author: Arne Babenhauserheide
 
+;; Copyright (C) Arne Babenhauserheide (2013--2015). All Rights Reserved.
+
+;; Permission is hereby granted, free of charge, to any person
+;; obtaining a copy of this software and associated documentation
+;; files (the "Software"), to deal in the Software without
+;; restriction, including without limitation the rights to use, copy,
+;; modify, merge, publish, distribute, sublicense, and/or sell copies
+;; of the Software, and to permit persons to whom the Software is
+;; furnished to do so, subject to the following conditions:
+;; 
+;; The above copyright notice and this permission notice shall be
+;; included in all copies or substantial portions of the Software.
+;; 
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+;; SOFTWARE.
+
+
 define-module : wisp
    . #:export : wisp2lisp wisp-chunkreader
 
diff --git a/wisp-mode.el b/wisp-mode.el
--- a/wisp-mode.el
+++ b/wisp-mode.el
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2013  Arne Babenhauserheide <arne_bab@web.de>
 
 ;; Author: Arne Babenhauserheide <arne_bab@web.de>
-;; Version: 0.2
+;; Version: 0.2.1
 ;; Keywords: languages, lisp
 
 ;; This program is free software; you can redistribute it and/or
@@ -37,6 +37,7 @@
 ;; 
 ;; ChangeLog:
 ;; 
+;;  - 0.2.1: Disable electric-indent-local-mode in wisp-mode buffers.
 ;;  - 0.2: Fixed the regular expressions. Now org-mode HTML export works with wisp-code.
 ;; 
 ;;; Code:
@@ -49,6 +50,10 @@
 ; use this mode automatically
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.w\\'" . wisp-mode))
+;;;###autoload
+(add-hook 'wisp-mode-hook
+          (lambda ()
+            (electric-indent-local-mode -1)))
 
 ; see http://www.emacswiki.org/emacs/DerivedMode
 
diff --git a/wisp-reader.w b/wisp-reader.w
--- a/wisp-reader.w
+++ b/wisp-reader.w
@@ -14,6 +14,8 @@ define-module : language wisp spec
   . #:use-module : wisp-scheme
   . #:use-module : system base compile
   . #:use-module : system base language
+  . #:use-module : language scheme compile-tree-il
+  . #:use-module : language scheme decompile-tree-il
   . #:export : wisp
 
 ; Set locale to something which supports unicode. Required to avoid using fluids.
@@ -23,59 +25,26 @@ setlocale LC_ALL ""
 ;;; Language definition
 ;;;
 
-define : compile-scheme x e opts
-       values x e e
-
-define : decompile-scheme x e opts
-       values x e
-
-define wisp-pending-port : make-object-property
-
-; Code thanks to Mark Weaver
-; define : read-one-wisp-sexp port env
-;   define : read-wisp-chunk
-;     if : eof-object? : peek-char port
-;       read-char port ; return eof: we’re done
-;       let : : s : wisp2lisp : wisp-chunkreader port
-;         set! : wisp-pending-port port
-;                open-input-string s
-;         try-pending
-;   define : try-pending
-;     let : : pending-port : wisp-pending-port port
-;       if pending-port
-;           let : : x : read pending-port
-;              if : eof-object? x
-;                 read-wisp-chunk
-;                 . x
-;           read-wisp-chunk
-;   try-pending
-
-
 define wisp-pending-sexps : list
 
 define : read-one-wisp-sexp port env
-  define : wisp-scheme-read-chunk-env
-           cond 
-              : eof-object? : peek-char port
-                read-char port ; return eof: we’re done
-              else
-                set! wisp-pending-sexps
-                     append wisp-pending-sexps : wisp-scheme-read-chunk port
-                try-pending
-  define : try-pending
-    if : null? wisp-pending-sexps
-         wisp-scheme-read-chunk-env
-         let : : sexp : car wisp-pending-sexps
-            set! wisp-pending-sexps : cdr wisp-pending-sexps
-            . sexp
-  try-pending
+         cond
+            : eof-object? : peek-char port
+              read-char port ; return eof: we’re done
+            else
+              let : : chunk : wisp-scheme-read-chunk port
+                cond
+                  : not : null? chunk
+                    car chunk
+                  else
+                    . #f
 
 define-language wisp
-  . #:title "Wisp Scheme Syntax THIS IS EXPERIMENTAL, USE AT YOUR OWN RISK"
+  . #:title "Wisp Scheme Syntax. See SRFI-119 for details. THIS IS EXPERIMENTAL, USE AT YOUR OWN RISK"
   ; . #:reader read-one-wisp-sexp
   . #:reader : lambda (port env) : let ((x (read-one-wisp-sexp port env))) x
-  . #:compilers `((scheme . ,compile-scheme))
-  . #:decompilers `((scheme . ,decompile-scheme))
+  . #:compilers `((tree-il . ,compile-tree-il))
+  . #:decompilers `((tree-il . ,decompile-tree-il))
   . #:evaluator : lambda (x module) : primitive-eval x
   . #:printer write ; TODO: backtransform to wisp? Use source-properties?
   . #:make-default-environment
diff --git a/wisp-scheme.w b/wisp-scheme.w
--- a/wisp-scheme.w
+++ b/wisp-scheme.w
@@ -1,4 +1,5 @@
 #!/bin/bash
+# -*- wisp -*-
 exec guile -L . --language=wisp -s "$0" "$@"
 ; !#
 
@@ -16,6 +17,28 @@ exec guile -L . --language=wisp -s "$0" 
 ;; then simply reuse the appropriate function from the generic wisp
 ;; preprocessor.
 
+;; Copyright (C) Arne Babenhauserheide (2014--2015). All Rights Reserved.
+
+;; Permission is hereby granted, free of charge, to any person
+;; obtaining a copy of this software and associated documentation
+;; files (the "Software"), to deal in the Software without
+;; restriction, including without limitation the rights to use, copy,
+;; modify, merge, publish, distribute, sublicense, and/or sell copies
+;; of the Software, and to permit persons to whom the Software is
+;; furnished to do so, subject to the following conditions:
+;; 
+;; The above copyright notice and this permission notice shall be
+;; included in all copies or substantial portions of the Software.
+;; 
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+;; SOFTWARE.
+
 
 define-module : wisp-scheme
    . #:export (wisp-scheme-read-chunk wisp-scheme-read-all 
@@ -43,7 +66,11 @@ define : line-real-indent line
                . indent
 
 define : line-code line
-         cdr line
+         let : : code : cdr line
+             ; propagate source properties
+             when : not : null? code
+                    set-source-properties! code : source-properties line
+             . code
 
 ; literal values I need
 define readcolon 
@@ -110,6 +137,16 @@ define : wisp-read port
            cond
              : or (< prefix-maxlen (length peeked)) (eof-object? (peek-char port)) (equal? #\space (peek-char port)) (equal? #\newline (peek-char port)) 
                if repr-symbol ; found a special symbol, return it.
+                  ; TODO: Somehow store source-properties. The commented-out code below does not work.
+                  ; catch #t
+                  ;     lambda ()
+                  ;         write : source-properties symbol-or-symbols
+                  ;         set-source-property! symbol-or-symbols 'filename : port-filename port
+                  ;         set-source-property! symbol-or-symbols 'line : 1+ : port-line port
+                  ;         set-source-property! symbol-or-symbols 'column : port-column port
+                  ;         write : source-properties symbol-or-symbols
+                  ;     lambda : key . arguments
+                  ;         . #f
                   . repr-symbol
                   let unpeek
                     : remaining peeked
@@ -195,16 +232,20 @@ define : wisp-scheme-read-chunk-lines po
              currentindent 0
              currentsymbols '()
              emptylines 0
-           if : <= 2 emptylines ; the chunk end has to be checked
-                                ; before we look for new chars in the
-                                ; port to make execution in the REPL
-                                ; after two empty lines work
-                                ; (otherwise it shows one more line).
+           cond
+            : >= emptylines 2 ; the chunk end has to be checked
+                              ; before we look for new chars in the
+                              ; port to make execution in the REPL
+                              ; after two empty lines work
+                              ; (otherwise it shows one more line).
              . indent-and-symbols
+            else
              let : : next-char : peek-char port
                cond
                  : eof-object? next-char
                    append indent-and-symbols : list : append (list currentindent) currentsymbols
+                 : and inindent (zero? currentindent) (not incomment) (not (null? indent-and-symbols)) (not inunderscoreindent) (not (or (equal? #\space next-char) (equal? #\newline next-char) (equal? (string-ref ";" 0) next-char)))
+                  append indent-and-symbols ; top-level form ends chunk
                  : and inindent : equal? #\space next-char
                    read-char port ; remove char
                    loop
@@ -258,6 +299,10 @@ define : wisp-scheme-read-chunk-lines po
                          if : not : line-empty? parsedline
                             . 0 
                             1+ emptylines
+                     when : not : = 0 : length parsedline
+                         ; set the source properties to parsedline so we can try to add them later.
+                         set-source-property! parsedline 'filename : port-filename port
+                         set-source-property! parsedline 'line : port-line port
                      ; TODO: If the line is empty. Either do it here and do not add it, just
                      ; increment the empty line counter, or strip it later. Replace indent
                      ; -1 by indent 0 afterwards.
@@ -326,6 +371,12 @@ define : line-code-replace-inline-colons
              : null? unprocessed
                ; format #t "inline-colons processed line: ~A\n" processed
                . processed
+             ; replace : . with nothing
+             : and (<= 2 (length unprocessed)) (equal? readcolon (car unprocessed)) (equal? repr-dot (car (cdr unprocessed)))
+               loop
+                 append processed
+                   loop '() (cdr (cdr unprocessed))
+                 . '()
              : equal? readcolon : car unprocessed
                loop
                  ; FIXME: This should turn unprocessed into a list. 
@@ -353,12 +404,53 @@ define : line-strip-lone-colon line
            . line
 
 define : line-finalize line
-         . "Process all wisp-specific information in a line and strip it"
-         line-code-replace-inline-colons 
-           line-strip-indentation-marker
-             line-strip-lone-colon
-               line-strip-continuation line
+       . "Process all wisp-specific information in a line and strip it"
+       let
+         :
+           l
+             line-code-replace-inline-colons 
+               line-strip-indentation-marker
+                 line-strip-lone-colon
+                   line-strip-continuation line
+         when : not : null? : source-properties line
+                catch #t
+                  lambda ()
+                    set-source-properties! l : source-properties line
+                  lambda : key . arguments
+                    . #f
+         . l
 
+define : wisp-add-source-properties-from source target
+       . "Copy the source properties from source into the target and return the target."
+       catch #t
+           lambda ()
+               set-source-properties! target : source-properties source
+           lambda : key . arguments
+               . #f
+       . target
+
+define : wisp-propagate-source-properties code
+       . "Propagate the source properties from the sourrounding list into every part of the code."
+       let loop
+         : processed '()
+           unprocessed code
+         cond
+           : and (null? processed) (not (pair? unprocessed)) (not (list? unprocessed))
+             . unprocessed
+           : and (pair? unprocessed) (not (list? unprocessed))
+             cons
+               wisp-propagate-source-properties (car unprocessed)
+               wisp-propagate-source-properties (cdr unprocessed)
+           : null? unprocessed
+             . processed
+           else
+             let : : line : car unprocessed
+               if : null? : source-properties unprocessed
+                   wisp-add-source-properties-from line unprocessed
+                   wisp-add-source-properties-from unprocessed line
+               loop
+                 append processed : list : wisp-propagate-source-properties line
+                 cdr unprocessed
 
 define : wisp-scheme-indentation-to-parens lines
          . "Add parentheses to lines and remove the indentation markers"
@@ -447,7 +539,7 @@ define : wisp-scheme-indentation-to-pare
                                append processed 
                                  if : line-continues? current-line
                                       . line
-                                      list line
+                                      wisp-add-source-properties-from line : list line
                                cdr unprocessed ; recursion here
                                . indentation-levels
                            : < current-line-indentation next-line-indentation
@@ -537,8 +629,16 @@ define : wisp-replace-paren-quotation-re
                         list : list 'quote : map wisp-replace-paren-quotation-repr b
              : 'REPR-UNQUOTE-e749c73d-c826-47e2-a798-c16c13cb89dd a ...
                 list 'unquote : map wisp-replace-paren-quotation-repr a
+             : a ... 'REPR-UNQUOTE-e749c73d-c826-47e2-a798-c16c13cb89dd b 
+                append
+                        map wisp-replace-paren-quotation-repr a
+                        list : list 'unquote : map wisp-replace-paren-quotation-repr b
              : 'REPR-QUASIQUOTE-e749c73d-c826-47e2-a798-c16c13cb89dd a ...
                 list 'quasiquote : map wisp-replace-paren-quotation-repr a
+             : a ... 'REPR-QUASIQUOTE-e749c73d-c826-47e2-a798-c16c13cb89dd b ; this is the quoted empty list 
+                append
+                        map wisp-replace-paren-quotation-repr a
+                        list : list 'quasiquote : map wisp-replace-paren-quotation-repr b
              : 'REPR-UNQUOTESPLICING-e749c73d-c826-47e2-a798-c16c13cb89dd a ...
                 list 'unquote-splicing : map wisp-replace-paren-quotation-repr a
              : 'REPR-SYNTAX-e749c73d-c826-47e2-a798-c16c13cb89dd a ...
@@ -613,7 +713,6 @@ Match is awesome!"
                a
                  . a
 
-
 define : wisp-scheme-read-chunk port
          . "Read and parse one chunk of wisp-code"
          let : :  lines : wisp-scheme-read-chunk-lines port
@@ -621,7 +720,8 @@ define : wisp-scheme-read-chunk port
                 wisp-replace-empty-eof
                   wisp-unescape-underscore-and-colon
                     wisp-replace-paren-quotation-repr
-                      wisp-scheme-indentation-to-parens lines
+                      wisp-propagate-source-properties
+                        wisp-scheme-indentation-to-parens lines
 
 define : wisp-scheme-read-all port
          . "Read all chunks from the given port"