wisp
 
(Arne Babenhauserheide)
2013-01-30: first version, still bugs.

first version, still bugs.

diff --git a/example.w b/example.w
--- a/example.w
+++ b/example.w
@@ -1,7 +1,11 @@
 defun a
+  b c
   let
-    : d e
-      : f
-      : g
+    : 
+      d e
+      : 
+        f
+      : 
+        g
   h i
   . j
diff --git a/wisp.py b/wisp.py
new file mode 100644
--- /dev/null
+++ b/wisp.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+
+class Line:
+    def __init__(self, content, indent, continues=False):
+        self.content, self.indent, self.continues = content, indent, continues
+
+def wisp2lisp(code):
+    """Turn wisp code to lisp code."""
+    # first get rid of linebreaks in strings
+    instring = False
+    nostringbreaks = []
+    for char in code:
+        if char == '"':
+            instring = not instring
+        if instring and char == "\n":
+            nostringbreaks.append("\\n")
+        else:
+            nostringbreaks.append(char)
+    code = "".join(nostringbreaks)
+    
+    # now read the indentation
+    lines = []
+    for line in code.splitlines():
+        lines.append(Line(content = line.lstrip(), 
+                          indent = len(line) - len(line.lstrip()),
+                          continues = line.lstrip().startswith(". ")))
+
+    # finally emit matching lisp code
+    # write into the lisp lines with a delay of 1 line
+    lisplines = []
+    levels = []
+    prev = lines[0]
+    for line in lines[1:]:
+        # continuing lines do not get a leading bracket.
+        if not line.continues:
+            line.content = "(" + line.content
+        # rising indent: sibling function or variable
+        if line.indent > prev.indent:
+            levels.append(line.indent)
+            lisplines.append(prev.indent * " " + prev.content)
+        # same indent: neighbour function of variable: close the previour lines bracket
+        if line.indent == prev.indent:
+            lisplines.append(prev.indent * " " + prev.content + ")")
+        # lower indent: parent funtion or variable. Find the number of brackets to close
+        if prev.indent > line.indent:
+            bracketstoclose = 1 + len([level for level in levels if level > line.indent])
+            levels = levels[:-bracketstoclose]
+            lisplines.append(prev.indent * " " + prev.content + ")" * bracketstoclose)
+        
+        prev = line
+    
+    lisplines.append(prev.indent * " " + prev.content + ")" * len(levels))
+    
+    return "\n".join(lisplines)
+            
+
+
+if __name__ == "__main__":
+    print()
+    with open("example.w") as f:
+        wisp = f.read()
+    print(wisp2lisp(wisp))
+