Class: StarlarkCompiler::Writer
- Inherits:
-
Object
- Object
- StarlarkCompiler::Writer
- Defined in:
- lib/starlark_compiler/writer.rb
Instance Attribute Summary collapse
-
#ast ⇒ Object
Returns the value of attribute ast.
-
#indent ⇒ Object
Returns the value of attribute indent.
-
#io ⇒ Object
Returns the value of attribute io.
Class Method Summary collapse
Instance Method Summary collapse
- #delegate(template, obj) ⇒ Object
- #indented(single_line:) ⇒ Object
-
#initialize(ast:, io:) ⇒ Writer
constructor
A new instance of Writer.
- #single_line?(node) ⇒ Boolean
- #single_line_array?(array) ⇒ Boolean
- #single_line_binary_operator?(operator) ⇒ Boolean
- #single_line_dictionary?(dictionary) ⇒ Boolean
- #single_line_function_call?(call) ⇒ Boolean
- #single_line_number?(_) ⇒ Boolean
- #single_line_string?(str) ⇒ Boolean
- #single_line_variable_reference?(_) ⇒ Boolean
- #write ⇒ Object
- #write_array(array) ⇒ Object
- #write_binary_operator(operator) ⇒ Object
- #write_dictionary(dictionary) ⇒ Object
- #write_false(_none) ⇒ Object
- #write_function_call(call) ⇒ Object
- #write_function_declaration(declaration) ⇒ Object
- #write_newline ⇒ Object
- #write_node(node) ⇒ Object
- #write_none(_none) ⇒ Object
- #write_number(number) ⇒ Object
- #write_string(str) ⇒ Object
- #write_true(_none) ⇒ Object
- #write_variable_assignment(assignment) ⇒ Object
- #write_variable_reference(variable) ⇒ Object
Constructor Details
#initialize(ast:, io:) ⇒ Writer
Returns a new instance of Writer.
17 18 19 20 21 |
# File 'lib/starlark_compiler/writer.rb', line 17 def initialize(ast:, io:) @ast = ast @io = io @indent = 0 end |
Instance Attribute Details
#ast ⇒ Object
Returns the value of attribute ast.
15 16 17 |
# File 'lib/starlark_compiler/writer.rb', line 15 def ast @ast end |
#indent ⇒ Object
Returns the value of attribute indent.
15 16 17 |
# File 'lib/starlark_compiler/writer.rb', line 15 def indent @indent end |
#io ⇒ Object
Returns the value of attribute io.
15 16 17 |
# File 'lib/starlark_compiler/writer.rb', line 15 def io @io end |
Class Method Details
.write(ast:, io: nil) ⇒ Object
5 6 7 8 9 10 11 |
# File 'lib/starlark_compiler/writer.rb', line 5 def self.write(ast:, io: nil) if io.nil? end new(ast: ast, io: io).write end |
Instance Method Details
#delegate(template, obj) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/starlark_compiler/writer.rb', line 58 def delegate(template, obj) snake_case = lambda do |str| return str.downcase if str =~ /^[A-Z_]+$/ str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/ $+.downcase end cls = obj.class while cls && (cls != AST::Node) name = cls.name.split('::').last method = template % snake_case[name] return send(method, obj) if respond_to?(method) cls = cls.superclass end raise "No #{template} for #{obj.class}" end |
#indented(single_line:) ⇒ Object
191 192 193 194 195 196 197 |
# File 'lib/starlark_compiler/writer.rb', line 191 def indented(single_line:) should_indent = !single_line @indent += 1 if should_indent yield Indenter.new(self, should_indent) ensure @indent -= 1 if should_indent end |
#single_line?(node) ⇒ Boolean
199 200 201 202 203 |
# File 'lib/starlark_compiler/writer.rb', line 199 def single_line?(node) return true unless node delegate('single_line_%s?', node) end |
#single_line_array?(array) ⇒ Boolean
227 228 229 230 |
# File 'lib/starlark_compiler/writer.rb', line 227 def single_line_array?(array) array.elements.size <= 1 && array.elements.all?(&method(:single_line?)) end |
#single_line_binary_operator?(operator) ⇒ Boolean
213 214 215 |
# File 'lib/starlark_compiler/writer.rb', line 213 def single_line_binary_operator?(operator) single_line?(operator.lhs) && single_line?(operator.rhs) end |
#single_line_dictionary?(dictionary) ⇒ Boolean
232 233 234 235 |
# File 'lib/starlark_compiler/writer.rb', line 232 def single_line_dictionary?(dictionary) dictionary.elements.size <= 1 && dictionary.elements.each_key.all?(&method(:single_line?)) end |
#single_line_function_call?(call) ⇒ Boolean
217 218 219 220 221 222 223 224 225 |
# File 'lib/starlark_compiler/writer.rb', line 217 def single_line_function_call?(call) if call.args.empty? call.kwargs.size <= 1 && call.kwargs.each_value.all? { |v| single_line?(v) } elsif call.kwargs.empty? call.args.size <= 2 && call.args.all? { |v| single_line?(v) } || (call.args.size == 1 && call.args.first.respond_to?(:elements)) end end |
#single_line_number?(_) ⇒ Boolean
209 210 211 |
# File 'lib/starlark_compiler/writer.rb', line 209 def single_line_number?(_) true end |
#single_line_string?(str) ⇒ Boolean
205 206 207 |
# File 'lib/starlark_compiler/writer.rb', line 205 def single_line_string?(str) str.str.size <= 50 end |
#single_line_variable_reference?(_) ⇒ Boolean
237 238 239 |
# File 'lib/starlark_compiler/writer.rb', line 237 def single_line_variable_reference?(_) true end |
#write ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/starlark_compiler/writer.rb', line 23 def write case ast when AST ast.toplevel.each_with_index do |o, i| 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 write_newline end |
#write_array(array) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/starlark_compiler/writer.rb', line 130 def write_array(array) single_line = single_line?(array) io << '[' end_index = array.elements.size.pred array.elements.each_with_index do |node, i| indented(single_line: single_line) do |indenter| indenter.write_newline write_node(node) indenter.write_comma unless i == end_index && single_line end end write_newline unless single_line io << ']' end |
#write_binary_operator(operator) ⇒ Object
162 163 164 165 166 |
# File 'lib/starlark_compiler/writer.rb', line 162 def write_binary_operator(operator) write_node(operator.lhs) io << " #{operator.operator} " write_node(operator.rhs) end |
#write_dictionary(dictionary) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/starlark_compiler/writer.rb', line 145 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| 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 end write_newline unless single_line io << '}' end |
#write_false(_none) ⇒ Object
176 177 178 |
# File 'lib/starlark_compiler/writer.rb', line 176 def write_false(_none) io << 'False' end |
#write_function_call(call) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/starlark_compiler/writer.rb', line 76 def write_function_call(call) single_line = single_line?(call) io << call.name << '(' final_index = single_line && call.kwargs.empty? && call.args.size.pred call.args.each_with_index do |arg, idx| 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(single_line: single_line) do |indenter| indenter.write_newline io << "#{k} = " write_node(v) indenter.write_comma unless final_index == idx end end write_newline unless single_line io << ')' end |
#write_function_declaration(declaration) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/starlark_compiler/writer.rb', line 100 def write_function_declaration(declaration) io << 'def ' << declaration.name << '(' final_index = declaration.args.size.pred declaration.args.each_with_index do |arg, idx| indented(single_line: false) do |indenter| indenter.write_newline write_node(arg) indenter.write_comma unless final_index == idx end end write_newline io << '):' final_index = declaration.body.size.pred declaration.body.each do |arg| indented(single_line: false) do |indenter| indenter.write_newline write_node(arg) end end end |
#write_newline ⇒ Object
45 46 47 48 |
# File 'lib/starlark_compiler/writer.rb', line 45 def write_newline io << "\n" io << ' ' * indent end |
#write_node(node) ⇒ Object
41 42 43 |
# File 'lib/starlark_compiler/writer.rb', line 41 def write_node(node) delegate('write_%s', node) end |
#write_none(_none) ⇒ Object
168 169 170 |
# File 'lib/starlark_compiler/writer.rb', line 168 def write_none(_none) io << 'None' end |
#write_number(number) ⇒ Object
54 55 56 |
# File 'lib/starlark_compiler/writer.rb', line 54 def write_number(number) io << number.number.to_s end |
#write_string(str) ⇒ Object
50 51 52 |
# File 'lib/starlark_compiler/writer.rb', line 50 def write_string(str) io << str.str.inspect end |
#write_true(_none) ⇒ Object
172 173 174 |
# File 'lib/starlark_compiler/writer.rb', line 172 def write_true(_none) io << 'True' end |
#write_variable_assignment(assignment) ⇒ Object
125 126 127 128 |
# File 'lib/starlark_compiler/writer.rb', line 125 def write_variable_assignment(assignment) io << assignment.name << ' = ' write_node(assignment.var) end |
#write_variable_reference(variable) ⇒ Object
121 122 123 |
# File 'lib/starlark_compiler/writer.rb', line 121 def write_variable_reference(variable) io << variable.var end |