# Use it as 'ed wisp-file.w < /path/to/wisp.ed # The wisp-file.w is overwritten with resulting Scheme forms # You can change the "w" line in the bottom of the script with ",p" to # print the new contents to stdout instead. # Comments are stripped in the process, unfortunately H # Remove trailing periods (REPL-friendly ones) g/ \.$/s/// # Replace leading underscores with spaces g/^__/s// /g g/^__/s// /g g/^__/s// /g g/^__/s// /g g/^__/s// /g g/^_/s// /g # Remove comments g/;/s/\([^;]*\);*.*/\1/ # Remove trailing spaces (after comments) g/./s/[[:space:]]*$// # Convert parens to double square brackets # (for now, to not break the parsing rules) # Useful for inline parenthesized forms: # setf (slot-value stream 'buffer) nil g/(/s/(/[[/g g/)/s/)/]]/g # Remove resulting empty lines g/^[ ]*$/d # Join lines with semicolons (there are none left) # Also add one semicolon to the front (useful in wrapping forms below) g/$/s//;/ ,j s/^/;/ # Wrapping colons g/./s/\(;[ ]*\): \([^;]*\)\(\(\1[ ]\{1,\}[^;]*\)*\)/\1( \2\3)/g # Un-join the lines s/;/\ /g # Wrap every (non-parenthesized) line in parens v/(.*)/s/\([( ]*\)\(.*\)/\1(\2)/g # Un-wrap wrapped (above) dots # Otherwise we end up with # (. 3) g/(\./s/(\(\..*\))/\1/ # Join the lines back g/$/s//;/ ,j s/^/;/ # Wrapping forms (repeated for 10x nesting (too little?)) g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g g/./s/\(;[ ]*\)(\([^;()]*\))\(\(\1[ ]\{1,\}[^;]*\)*\)/\1(\2\3)/g # Curly-infix syntax (only the {a op b} form, no nesting) g/{ *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *}/s//(\2 \1 \3)/g # Block-prefixing colon g/(:/s//(/g # Inline colons (x5) g/./s/\([^\\]\):\([^;]*\);/\1(\2);/g g/./s/\([^\\]\):\([^;]*\);/\1(\2);/g g/./s/\([^\\]\):\([^;]*\);/\1(\2);/g g/./s/\([^\\]\):\([^;]*\);/\1(\2);/g g/./s/\([^\\]\):\([^;]*\);/\1(\2);/g # Dot-prefixed pass-through forms g/./s/\(;[ ]*\)\. /\1/g # Fix pass # - Convert double square brackets to parens again (for now, to not break the parsing rules) g/./s/\[\[/(/g g/./s/\]\]/)/g # - space-suffixed opening parens g/./s/( /(/g # Reader macros g/[',`#]/s/(\('*`*\(,@*\)*\(#[',`@]*\)*\) \{1,\}/\1(/g # Empty lists (due to introduced semicolons) g/./s/;();/;/g # Split the lines back out g/./s/;/\ /g w Q