Class: Oppen::Printer
- Inherits:
-
Object
- Object
- Oppen::Printer
- Extended by:
- Mixins
- Defined in:
- lib/oppen/printer.rb
Overview
Oppen pretty-printer.
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#left ⇒ Object
readonly
Ring buffer left index.
-
#left_total ⇒ Object
readonly
Total number of spaces needed to print from start of buffer to the left.
- #print_stack ⇒ Object readonly
-
#right ⇒ Object
readonly
Ring buffer right index.
-
#right_total ⇒ Object
readonly
Total number of spaces needed to print from start of buffer to the right.
-
#scan_stack ⇒ Object
readonly
Potential breaking positions.
-
#size ⇒ Object
readonly
Size buffer, initially filled with nil.
-
#tokens ⇒ Object
readonly
Token buffer, initially filled with nil.
Instance Method Summary collapse
-
#advance_left(token, token_width) ⇒ Nil
Advances the
left
pointer and lets the print stack print some of the tokens it contains. -
#advance_right ⇒ Nil
Advances the
right
pointer. -
#check_stack(depth) ⇒ Nil
Updates the size buffer taking into account the length of the current group.
-
#check_stream ⇒ Nil
Flushes the input if possible.
-
#handle_begin(token) ⇒ Nil
Handle Begin Token.
-
#handle_break(token) ⇒ Nil
Handle Break Token.
-
#handle_end(token) ⇒ Nil
Handle End Token.
-
#handle_eof ⇒ Nil
Handle EOF Token.
-
#handle_string(token) ⇒ Nil
Handle String Token.
-
#initialize(width, new_line, config = Config.oppen, space = ' ', out = StringIO.new) ⇒ Printer
constructor
Some description.
- #output ⇒ String
-
#print(token) ⇒ Nil
Core function of the algorithm responsible for populating the scan and print stack.
Methods included from Mixins
tokens_to_wadler, upsize_circular_array
Constructor Details
#initialize(width, new_line, config = Config.oppen, space = ' ', out = StringIO.new) ⇒ Printer
Some description
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/oppen/printer.rb', line 75 def initialize(width, new_line, config = Config.oppen, space = ' ', out = StringIO.new) # Maximum size if the stacks n = 3 * width @config = config @last_whitespaces_width = 0 @left = 0 @left_total = 1 @print_stack = PrintStack.new width, new_line, config, space, out @right = 0 @right_total = 1 @scan_stack = ScanStack.new n, config @size = Array.new n @tokens = Array.new n end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
15 16 17 |
# File 'lib/oppen/printer.rb', line 15 def config @config end |
#left ⇒ Object (readonly)
Called left as well in the original paper.
Ring buffer left index.
19 20 21 |
# File 'lib/oppen/printer.rb', line 19 def left @left end |
#left_total ⇒ Object (readonly)
Called leftTotal as well in the original paper.
Total number of spaces needed to print from start of buffer to the left.
24 25 26 |
# File 'lib/oppen/printer.rb', line 24 def left_total @left_total end |
#print_stack ⇒ Object (readonly)
Called printStack as well in the original paper.
27 28 29 |
# File 'lib/oppen/printer.rb', line 27 def print_stack @print_stack end |
#right ⇒ Object (readonly)
Called right as well in the original paper.
Ring buffer right index.
32 33 34 |
# File 'lib/oppen/printer.rb', line 32 def right @right end |
#right_total ⇒ Object (readonly)
Called leftTotal as well in the original paper.
Total number of spaces needed to print from start of buffer to the right.
37 38 39 |
# File 'lib/oppen/printer.rb', line 37 def right_total @right_total end |
#scan_stack ⇒ Object (readonly)
Called scanStack as well in the original paper.
Potential breaking positions.
42 43 44 |
# File 'lib/oppen/printer.rb', line 42 def scan_stack @scan_stack end |
#size ⇒ Object (readonly)
Called size as well in the original paper.
Size buffer, initially filled with nil.
47 48 49 |
# File 'lib/oppen/printer.rb', line 47 def size @size end |
#tokens ⇒ Object (readonly)
Called token in the original paper.
Token buffer, initially filled with nil.
52 53 54 |
# File 'lib/oppen/printer.rb', line 52 def tokens @tokens end |
Instance Method Details
#advance_left(token, token_width) ⇒ Nil
Called AdvanceLeft as well in the original paper.
Advances the left
pointer and lets the print stack
print some of the tokens it contains.
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/oppen/printer.rb', line 262 def advance_left(token, token_width) return if token_width.negative? trim_on_break = if token.is_a?(Token::Break) # Find the first previous String token. idx = (left - 1) % tokens.length while idx != right && tokens[idx] && !tokens[idx].is_a?(Token::String) \ && !tokens[idx].is_a?(Token::Break) idx = (idx - 1) % tokens.length end # Sum the widths of the last whitespace tokens. total = 0 while tokens[idx].is_a?(Token::Whitespace) total += tokens[idx].width idx = (idx - 1) % tokens.length end @last_whitespaces_width = 0 total end trim_on_break ||= 0 print_stack.print(token, token_width, trim_on_break:) case token when Token::Break @left_total += token.width when Token::String @left_total += token_width end return if left == right @left = (left + 1) % tokens.length advance_left tokens[left], size[left] end |
#advance_right ⇒ Nil
Called AdvanceRight as well in the original paper.
Advances the right
pointer.
244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/oppen/printer.rb', line 244 def advance_right @right = (right + 1) % @size.length return if right != left raise 'Token queue full' if !config.upsize_stack? @scan_stack.update_indexes(-@left) @size, _left, _right = ScanStack.upsize_circular_array(@size, @left) @tokens, @left, @right = ScanStack.upsize_circular_array(@tokens, @left) end |
#check_stack(depth) ⇒ Nil
Called CheckStack as well in the original paper.
Updates the size buffer taking into account the length of the current group.
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/oppen/printer.rb', line 307 def check_stack(depth) return if scan_stack.empty? x = scan_stack.top case tokens[x] when Token::Begin if depth.positive? size[scan_stack.pop] = size[x] + right_total check_stack depth - 1 end when Token::End size[scan_stack.pop] = 1 check_stack depth + 1 else size[scan_stack.pop] = size[x] + right_total if depth.positive? check_stack depth end end end |
#check_stream ⇒ Nil
Called CheckStream as well in the original paper.
Flushes the input if possible.
227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/oppen/printer.rb', line 227 def check_stream return if right_total - left_total <= print_stack.space if !scan_stack.empty? && left == scan_stack.bottom size[scan_stack.pop_bottom] = Float::INFINITY end advance_left tokens[left], size[left] return if left == right check_stream end |
#handle_begin(token) ⇒ Nil
Handle Begin Token.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/oppen/printer.rb', line 141 def handle_begin(token) if scan_stack.empty? @left = 0 @left_total = 1 @right = 0 @right_total = 1 # config.trim_trailing_whitespaces @tokens[-1] = nil else advance_right end tokens[right] = token size[right] = -right_total scan_stack.push right end |
#handle_break(token) ⇒ Nil
Handle Break Token.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/oppen/printer.rb', line 184 def handle_break(token) if scan_stack.empty? @left = 0 @left_total = 1 @right = 0 @right_total = 1 # config.trim_trailing_whitespaces tokens[-1] = nil print_stack.erase @last_whitespaces_width @last_whitespaces_width = 0 else advance_right end check_stack 0 scan_stack.push right tokens[right] = token size[right] = -right_total @right_total += token.width end |
#handle_end(token) ⇒ Nil
Handle End Token.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/oppen/printer.rb', line 163 def handle_end(token) if scan_stack.empty? print_stack.print token, 0 else advance_right tokens[right] = token size[right] = -1 scan_stack.push right if config&.eager_print? && (!scan_stack.empty? && right_total - left_total < print_stack.space) check_stack 0 advance_left tokens[left], size[left] end end end |
#handle_eof ⇒ Nil
Handle EOF Token.
128 129 130 131 132 133 134 |
# File 'lib/oppen/printer.rb', line 128 def handle_eof if !scan_stack.empty? check_stack 0 advance_left tokens[left], size[left] end print_stack.indent 0 end |
#handle_string(token) ⇒ Nil
Handle String Token.
210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/oppen/printer.rb', line 210 def handle_string(token) if scan_stack.empty? print_stack.print token, token.width else advance_right tokens[right] = token size[right] = token.width @right_total += token.width check_stream if @last_whitespaces_width.zero? end end |
#output ⇒ String
93 94 95 |
# File 'lib/oppen/printer.rb', line 93 def output print_stack.output end |
#print(token) ⇒ Nil
Called PrettyPrint as well in the original paper.
Core function of the algorithm responsible for populating the scan and print stack.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/oppen/printer.rb', line 104 def print(token) case token in Token::EOF handle_eof in Token::Begin handle_begin token in Token::End handle_end token in Token::Break handle_break token in Token::Whitespace @last_whitespaces_width += token.width handle_string token in Token::String @last_whitespaces_width = 0 handle_string token end end |