module WLang class Compiler class Autospacing < Filter def on_strconcat(*exps) optimized = [] exps.each_with_index do |exp,i| optimized[i] = call(exp) if exp.first == :wlang and multiline?(exp) and i != 0 optimized[i-1] = RightStrip.new.call(optimized[i-1]) end end [:strconcat] + optimized end def on_wlang(symbols, *fns) fns.inject [:wlang, symbols] do |rw,fn| if multiline?(fn) fn = Unindent.new.call(fn) fn = RightStrip.new.call(fn) end rw << call(fn) end end private def multiline?(who) case who.first when :static who.last =~ /\n/ when :wlang, :modulo who[2..-1].any?{|s| s && multiline?(s)} else who[1..-1].any?{|s| s && multiline?(s)} end end class RightStrip < Filter def on_strconcat(*exps) exps[-1] = call(exps[-1]) [:strconcat] + exps end def on_static(text) [:static, text.gsub(/\s+\Z/m, '')] end end # class RightStrip class Unindent < Filter def on_static(text) [:static, text.gsub(/^ /m, '')] end end # class Unindent end # class Autospacing end # class Compiler end # module WLang