lib/starlark_compiler/writer.rb in starlark_compiler-0.2.0 vs lib/starlark_compiler/writer.rb in starlark_compiler-0.3.0
- old
+ new
@@ -22,28 +22,31 @@
def write
case ast
when AST
ast.toplevel.each_with_index do |o, i|
- io << "\n\n" unless i.zero?
+ unless i.zero?
+ write_newline
+ write_newline unless o.is_a?(AST::FunctionCall) && o.name == 'load'
+ end
write_node(o)
end
when AST::Node
write_node(ast)
else
raise Error, "Trying to write unknown object #{ast.inspect}"
end
- io << "\n"
+ write_newline
end
- def write_node(node, start_of_line: true)
- write_start_of_line if start_of_line
+ def write_node(node)
delegate('write_%s', node)
end
- def write_start_of_line
- io << ' ' * indent
+ def write_newline
+ io << "\n"
+ io << ' ' * indent
end
def write_string(str)
io << str.str.inspect
end
@@ -71,69 +74,67 @@
end
def write_function_call(call)
single_line = single_line?(call)
io << call.name << '('
- io << "\n" unless single_line
final_index = single_line && call.kwargs.empty? && call.args.size.pred
call.args.each_with_index do |arg, idx|
- indented do
- write_node(arg, start_of_line: !single_line)
- unless final_index == idx
- io << ','
- io << (single_line ? ' ' : "\n")
- end
+ indented(single_line: single_line) do |indenter|
+ indenter.write_newline
+ write_node(arg)
+ indenter.write_comma unless final_index == idx
end
end
final_index = single_line && call.kwargs.size.pred
call.kwargs.each_with_index do |(k, v), idx|
- indented do
- write_start_of_line unless single_line
+ indented(single_line: single_line) do |indenter|
+ indenter.write_newline
io << "#{k} = "
- write_node(v, start_of_line: false)
- unless final_index == idx
- io << ','
- io << (single_line ? ' ' : "\n")
- end
+ write_node(v)
+ indenter.write_comma unless final_index == idx
end
end
- write_start_of_line unless single_line
+ write_newline unless single_line
io << ')'
end
def write_array(array)
single_line = single_line?(array)
io << '['
+ end_index = array.elements.size.pred
array.elements.each_with_index do |node, i|
- unless i.zero?
- io << ','
- io << "\n" unless single_line
+ indented(single_line: single_line) do |indenter|
+ indenter.write_newline
+ write_node(node)
+ indenter.write_comma unless i == end_index && single_line
end
- write_node(node, start_of_line: !single_line)
end
+ write_newline unless single_line
io << ']'
end
def write_dictionary(dictionary)
single_line = single_line?(dictionary)
io << '{'
+ end_index = dictionary.elements.size.pred
dictionary.elements.each_with_index do |(key, value), i|
- unless i.zero?
- io << ','
- io << "\n" unless single_line
+ indented(single_line: single_line) do |indenter|
+ indenter.write_newline
+ write_node(key)
+ io << ': '
+ write_node(value)
+ indenter.write_comma unless i == end_index && single_line
end
- write_node(key, start_of_line: !single_line)
- io << ': '
- write_node(value, start_of_line: false)
end
+ write_newline unless single_line
io << '}'
end
def write_binary_operator(operator)
- write_node(operator.lhs, start_of_line: false)
+ write_node(operator.lhs)
io << " #{operator.operator} "
- write_node(operator.rhs, start_of_line: false)
+ write_node(operator.rhs)
end
def write_none(_none)
io << 'None'
end
@@ -141,18 +142,30 @@
def write_true(_none)
io << 'True'
end
def write_false(_none)
- io << 'True'
+ io << 'False'
end
- def indented
- @indent += 1
- yield
+ Indenter = Struct.new(:writer, :should_indent) do
+ def write_newline
+ writer.write_newline if should_indent
+ end
+
+ def write_comma
+ writer.io << (should_indent ? ',' : ', ')
+ end
+ end
+ private_constant :Indenter
+
+ def indented(single_line:)
+ should_indent = !single_line
+ @indent += 1 if should_indent
+ yield Indenter.new(self, should_indent)
ensure
- @indent -= 1
+ @indent -= 1 if should_indent
end
def single_line?(node)
return true unless node
@@ -180,18 +193,15 @@
(call.args.size == 1 && call.args.first.respond_to?(:elements))
end
end
def single_line_array?(array)
- if array.elements.all? { |e| e.is_a?(AST::String) }
- array.elements.sum { |s| s.str.length } < 50
- else
- array.elements.size <= 1 && array.elements.all?(&method(:single_line?))
- end
+ array.elements.size <= 1 &&
+ array.elements.all?(&method(:single_line?))
end
def single_line_dictionary?(dictionary)
dictionary.elements.size <= 1 &&
- dictionary.elements.each_value.all?(&method(:single_line?))
+ dictionary.elements.each_key.all?(&method(:single_line?))
end
end
end