Appearance
| 1 | namespace Syntax.Process.Printer is | |
| 2 | use IO.Std | |
| 3 | ||
| 4 | use Trees | |
| 5 | ||
| 6 | class GHUL: Base is | |
| 7 | init() is | |
| 8 | super.init(false) | |
| 9 | si | |
| 10 | ||
| 11 | visit(variable: Variables.VARIABLE) is | |
| 12 | variable.left.accept(self) | |
| 13 | ||
| 14 | let type_expression = variable.type_expression | |
| 15 | ||
| 16 | if !isa TypeExpressions.INFER(type_expression) then | |
| 17 | write(": ") | |
| 18 | type_expression.accept(self) | |
| 19 | fi | |
| 20 | let initializer = variable.initializer | |
| 21 | if initializer? then | |
| 22 | write(" = ") | |
| 23 | initializer.accept(self) | |
| 24 | fi | |
| 25 | si | |
| 26 | ||
| 27 | // A destructure leaf's own `: T` ascription is carried on the | |
| 28 | // `VariableLeft` node itself, not on any wrapping VARIABLE - it can | |
| 29 | // sit on any leaf, at any nesting depth (`(a: int, b)`, or a nested | |
| 30 | // group `(a, b): NODE`). | |
| 31 | _write_leaf_ascription(leaf: Variables.VariableLeft) is | |
| 32 | let type_expression = leaf.type_expression | |
| 33 | ||
| 34 | if type_expression? then | |
| 35 | write(": ") | |
| 36 | type_expression.accept(self) | |
| 37 | fi | |
| 38 | ||
| 39 | // A by-name leaf reads the field it names rather than the | |
| 40 | // element at its position: `(local = field)`. | |
| 41 | if let field_name = leaf.source_field_name then | |
| 42 | write(" = ") | |
| 43 | field_name.accept(self) | |
| 44 | fi | |
| 45 | si | |
| 46 | ||
| 47 | visit(destructure_element: Variables.SIMPLE_VARIABLE_LEFT) is | |
| 48 | destructure_element.name.accept(self) | |
| 49 | _write_leaf_ascription(destructure_element) | |
| 50 | si | |
| 51 | ||
| 52 | visit(literal_leaf: Variables.LITERAL_VARIABLE_LEFT) is | |
| 53 | if literal_leaf.is_marked then | |
| 54 | write("~") | |
| 55 | fi | |
| 56 | ||
| 57 | literal_leaf.expression.accept(self) | |
| 58 | _write_leaf_ascription(literal_leaf) | |
| 59 | si | |
| 60 | ||
| 61 | visit(destructure_element_list: Variables.DESTRUCTURING_VARIABLE_LEFT) is | |
| 62 | write("(") | |
| 63 | ||
| 64 | let seen_any mut = false | |
| 65 | for e in destructure_element_list.elements do | |
| 66 | if seen_any then | |
| 67 | write(", ") | |
| 68 | fi | |
| 69 | ||
| 70 | e.accept(self) | |
| 71 | ||
| 72 | seen_any = true | |
| 73 | od | |
| 74 | ||
| 75 | write(")") | |
| 76 | ||
| 77 | _write_leaf_ascription(destructure_element_list) | |
| 78 | si | |
| 79 | ||
| 80 | visit(`namespace: Definitions.NAMESPACE) is | |
| 81 | write("namespace ") | |
| 82 | `namespace.name.accept(self) | |
| 83 | write_line(" is") | |
| 84 | indent() | |
| 85 | `namespace.body.accept(self) | |
| 86 | outdent() | |
| 87 | write_line("si") | |
| 88 | si | |
| 89 | ||
| 90 | visit(`use: Definitions.USE) is | |
| 91 | write("use ") | |
| 92 | ||
| 93 | if `use.is_default then | |
| 94 | write("default") | |
| 95 | write_terminator() | |
| 96 | ||
| 97 | return | |
| 98 | fi | |
| 99 | ||
| 100 | if `use.name? then | |
| 101 | `use.name.accept(self) | |
| 102 | ||
| 103 | if let `use.arguments? then | |
| 104 | write("[") | |
| 105 | arguments.accept(self) | |
| 106 | write("]") | |
| 107 | fi | |
| 108 | ||
| 109 | write(" = ") | |
| 110 | fi | |
| 111 | ||
| 112 | if `use.`use? then | |
| 113 | `use.`use.accept(self) | |
| 114 | fi | |
| 115 | ||
| 116 | if `use.is_all then | |
| 117 | write(".*") | |
| 118 | write_terminator() | |
| 119 | ||
| 120 | return | |
| 121 | fi | |
| 122 | ||
| 123 | if let `use.target? then | |
| 124 | target.accept(self) | |
| 125 | fi | |
| 126 | ||
| 127 | write_terminator() | |
| 128 | si | |
| 129 | ||
| 130 | visit(`class: Definitions.CLASS) is | |
| 131 | write("class ") | |
| 132 | `class.name.accept(self) | |
| 133 | if `class.arguments? then | |
| 134 | write("[") | |
| 135 | `class.arguments!.accept(self) | |
| 136 | write("]") | |
| 137 | fi | |
| 138 | if `class.ancestors? then | |
| 139 | write(": ") | |
| 140 | `class.ancestors!.accept(self) | |
| 141 | fi | |
| 142 | `class.modifiers.accept(self) | |
| 143 | write_line(" is") | |
| 144 | indent() | |
| 145 | `class.body.accept(self) | |
| 146 | outdent() | |
| 147 | write_line("si") | |
| 148 | si | |
| 149 | ||
| 150 | visit(`partial: Definitions.PARTIAL) is | |
| 151 | write("partial ") | |
| 152 | `partial.name.accept(self) | |
| 153 | if `partial.arguments? then | |
| 154 | write("[") | |
| 155 | `partial.arguments!.accept(self) | |
| 156 | write("]") | |
| 157 | fi | |
| 158 | `partial.modifiers.accept(self) | |
| 159 | write_line(" is") | |
| 160 | indent() | |
| 161 | `partial.body.accept(self) | |
| 162 | outdent() | |
| 163 | write_line("si") | |
| 164 | si | |
| 165 | ||
| 166 | visit(`impl: Definitions.IMPL) is | |
| 167 | write("impl ") | |
| 168 | if `impl.ancestors? then | |
| 169 | `impl.ancestors.accept(self) | |
| 170 | fi | |
| 171 | write(" for ") | |
| 172 | `impl.name.accept(self) | |
| 173 | if `impl.arguments? then | |
| 174 | write("[") | |
| 175 | `impl.arguments!.accept(self) | |
| 176 | write("]") | |
| 177 | fi | |
| 178 | `impl.modifiers.accept(self) | |
| 179 | write_line(" is") | |
| 180 | indent() | |
| 181 | `impl.body.accept(self) | |
| 182 | outdent() | |
| 183 | write_line("si") | |
| 184 | si | |
| 185 | ||
| 186 | visit(`trait: Definitions.TRAIT) is | |
| 187 | write("trait ") | |
| 188 | `trait.name.accept(self) | |
| 189 | if `trait.arguments? then | |
| 190 | write("[") | |
| 191 | `trait.arguments!.accept(self) | |
| 192 | write("]") | |
| 193 | fi | |
| 194 | if `trait.ancestors? then | |
| 195 | write(": ") | |
| 196 | `trait.ancestors!.accept(self) | |
| 197 | fi | |
| 198 | `trait.modifiers.accept(self) | |
| 199 | write_line(" is") | |
| 200 | indent() | |
| 201 | `trait.body.accept(self) | |
| 202 | outdent() | |
| 203 | write_line("si") | |
| 204 | si | |
| 205 | ||
| 206 | visit(`struct: Definitions.STRUCT) is | |
| 207 | write("trait ") | |
| 208 | `struct.name.accept(self) | |
| 209 | ||
| 210 | if `struct.arguments? then | |
| 211 | write("[") | |
| 212 | `struct.arguments!.accept(self) | |
| 213 | write("]") | |
| 214 | fi | |
| 215 | ||
| 216 | `struct.modifiers.accept(self) | |
| 217 | write_line(" is") | |
| 218 | indent() | |
| 219 | `struct.body.accept(self) | |
| 220 | outdent() | |
| 221 | write_line("si") | |
| 222 | si | |
| 223 | ||
| 224 | visit(`union: Definitions.UNION) is | |
| 225 | write("union ") | |
| 226 | `union.name.accept(self) | |
| 227 | if `union.arguments? then | |
| 228 | write("[") | |
| 229 | `union.arguments!.accept(self) | |
| 230 | write("]") | |
| 231 | fi | |
| 232 | `union.modifiers.accept(self) | |
| 233 | write_line(" is") | |
| 234 | indent() | |
| 235 | `union.body.accept(self) | |
| 236 | outdent() | |
| 237 | write_line("si") | |
| 238 | si | |
| 239 | ||
| 240 | visit(variant: Definitions.VARIANT) is | |
| 241 | variant.name.accept(self) | |
| 242 | ||
| 243 | if variant.fields.count > 0 then | |
| 244 | write("(") | |
| 245 | variant.fields.accept(self) | |
| 246 | write(")") | |
| 247 | fi | |
| 248 | ||
| 249 | variant.modifiers.accept(self) | |
| 250 | ||
| 251 | write_line(" is") | |
| 252 | indent() | |
| 253 | variant.body.accept(self) | |
| 254 | outdent() | |
| 255 | write_line("si") | |
| 256 | si | |
| 257 | ||
| 258 | after_body(node: Bodies.Body?) is | |
| 259 | if node==null \/ !node.is_block then | |
| 260 | write_terminator() | |
| 261 | return | |
| 262 | fi | |
| 263 | write_line() | |
| 264 | si | |
| 265 | ||
| 266 | // A body-less function, property accessor or indexer accessor still | |
| 267 | // requires *some* body node, so the parser hands back `Bodies.NULL` | |
| 268 | // rather than leaving the slot absent - `visit(Bodies.NULL)` renders | |
| 269 | // nothing, and `after_body` is what emits the single terminating `;`. | |
| 270 | _has_no_written_body(body: Bodies.Body?) -> bool => | |
| 271 | body? /\ isa Bodies.NULL(body) | |
| 272 | ||
| 273 | visit(function: Definitions.FUNCTION) is | |
| 274 | if let function.name? then | |
| 275 | name.accept(self) | |
| 276 | fi | |
| 277 | write("(") | |
| 278 | ||
| 279 | function.arguments.accept(self) | |
| 280 | write(")") | |
| 281 | ||
| 282 | let type_expression = function.type_expression | |
| 283 | ||
| 284 | if !isa TypeExpressions.INFER(type_expression) then | |
| 285 | write(" -> ") | |
| 286 | type_expression.accept(self) | |
| 287 | function.modifiers.accept(self) | |
| 288 | elif !function.modifiers.is_empty then | |
| 289 | function.modifiers.accept(self) | |
| 290 | fi | |
| 291 | ||
| 292 | let body = function.body | |
| 293 | ||
| 294 | if body? /\ !_has_no_written_body(body) then | |
| 295 | write(" ") | |
| 296 | body.accept(self) | |
| 297 | fi | |
| 298 | ||
| 299 | after_body(body) | |
| 300 | si | |
| 301 | ||
| 302 | write_member_type_and_modifiers(type_expression: TypeExpressions.TypeExpression, modifiers: Modifiers.LIST) is | |
| 303 | if !isa TypeExpressions.INFER(type_expression) then | |
| 304 | write(": ") | |
| 305 | type_expression.accept(self) | |
| 306 | write(" ") | |
| 307 | modifiers.accept(self) | |
| 308 | elif !modifiers.is_empty then | |
| 309 | modifiers.accept(self) | |
| 310 | fi | |
| 311 | si | |
| 312 | ||
| 313 | indent_property(has_getter: bool, has_setter: bool) -> bool is | |
| 314 | if has_getter /\ has_setter then | |
| 315 | write_line() | |
| 316 | indent() | |
| 317 | return true | |
| 318 | elif has_getter \/ has_setter then | |
| 319 | write(" ") | |
| 320 | fi | |
| 321 | return false | |
| 322 | si | |
| 323 | ||
| 324 | visit(property: Definitions.PROPERTY) is | |
| 325 | if property.name? then | |
| 326 | property.name.accept(self) | |
| 327 | fi | |
| 328 | ||
| 329 | write_member_type_and_modifiers(property.type_expression, property.modifiers) | |
| 330 | let out_again = | |
| 331 | indent_property( | |
| 332 | property.read_body? /\ !_has_no_written_body(property.read_body), | |
| 333 | property.assign_body? | |
| 334 | ) | |
| 335 | if property.read_body? then | |
| 336 | property.read_body.accept(self) | |
| 337 | if property.assign_body? then | |
| 338 | write_line(",") | |
| 339 | else | |
| 340 | after_body(property.read_body!) | |
| 341 | fi | |
| 342 | else | |
| 343 | write(" ") | |
| 344 | fi | |
| 345 | if property.assign_body? then | |
| 346 | write("= ") | |
| 347 | property.assign_argument!.accept(self) | |
| 348 | property.assign_body!.accept(self) | |
| 349 | after_body(property.assign_body!) | |
| 350 | fi | |
| 351 | if out_again then | |
| 352 | outdent() | |
| 353 | fi | |
| 354 | si | |
| 355 | ||
| 356 | visit(indexer: Definitions.INDEXER) is | |
| 357 | if indexer.name? then | |
| 358 | indexer.name.accept(self) | |
| 359 | fi | |
| 360 | write("[") | |
| 361 | indexer.index_argument.accept(self) | |
| 362 | write("]") | |
| 363 | write_member_type_and_modifiers(indexer.type_expression, indexer.modifiers) | |
| 364 | let out_again = | |
| 365 | indent_property( | |
| 366 | indexer.read_body? /\ !_has_no_written_body(indexer.read_body), | |
| 367 | indexer.assign_body? | |
| 368 | ) | |
| 369 | if indexer.read_body? then | |
| 370 | indexer.read_body.accept(self) | |
| 371 | if indexer.assign_body? then | |
| 372 | write_line(",") | |
| 373 | else | |
| 374 | after_body(indexer.read_body!) | |
| 375 | fi | |
| 376 | else | |
| 377 | write(' ') | |
| 378 | fi | |
| 379 | if indexer.assign_body? then | |
| 380 | write("= ") | |
| 381 | indexer.assign_argument!.accept(self) | |
| 382 | write(' ') | |
| 383 | indexer.assign_body!.accept(self) | |
| 384 | after_body(indexer.assign_body!) | |
| 385 | fi | |
| 386 | if out_again then | |
| 387 | outdent() | |
| 388 | fi | |
| 389 | si | |
| 390 | ||
| 391 | visit(generic: TypeExpressions.GENERIC) is | |
| 392 | generic.name.accept(self) | |
| 393 | write('[') | |
| 394 | generic.arguments.accept(self) | |
| 395 | write(']') | |
| 396 | si | |
| 397 | ||
| 398 | visit(function: TypeExpressions.FUNCTION) is | |
| 399 | write("(") | |
| 400 | function.arguments.accept(self) | |
| 401 | write(")") | |
| 402 | let result = function.result | |
| 403 | ||
| 404 | if !isa TypeExpressions.INFER(result) then | |
| 405 | write(" -> ") | |
| 406 | result.accept(self) | |
| 407 | fi | |
| 408 | if function.is_pure then | |
| 409 | write(" pure") | |
| 410 | fi | |
| 411 | si | |
| 412 | ||
| 413 | visit(tuple: TypeExpressions.TUPLE) is | |
| 414 | write("(") | |
| 415 | tuple.elements.accept(self) | |
| 416 | write(")") | |
| 417 | si | |
| 418 | ||
| 419 | visit(element: TypeExpressions.NAMED_TUPLE_ELEMENT) is | |
| 420 | element.name.accept(self) | |
| 421 | write(": ") | |
| 422 | element.type_expression.accept(self) | |
| 423 | si | |
| 424 | ||
| 425 | visit(constraint: TypeExpressions.TYPE_PARAMETER_CONSTRAINT) is | |
| 426 | write(constraint.keyword) | |
| 427 | si | |
| 428 | ||
| 429 | visit(`null: Expressions.NULL) is | |
| 430 | write("null") | |
| 431 | si | |
| 432 | ||
| 433 | visit(`self: Expressions.SELF) is | |
| 434 | write("self") | |
| 435 | si | |
| 436 | ||
| 437 | visit(variable: Expressions.VARIABLE) is | |
| 438 | variable.name.accept(self) | |
| 439 | ||
| 440 | let type_expression = variable.type_expression | |
| 441 | ||
| 442 | if !isa TypeExpressions.INFER(type_expression) then | |
| 443 | write(": ") | |
| 444 | type_expression.accept(self) | |
| 445 | fi | |
| 446 | ||
| 447 | if variable.initializer? then | |
| 448 | write(" = ") | |
| 449 | variable.initializer!.accept(self) | |
| 450 | fi | |
| 451 | si | |
| 452 | ||
| 453 | visit(element: Expressions.TUPLE_ELEMENT) is | |
| 454 | element.name.accept(self) | |
| 455 | ||
| 456 | let type_expression = element.type_expression | |
| 457 | ||
| 458 | if !isa TypeExpressions.INFER(type_expression) then | |
| 459 | write(": ") | |
| 460 | type_expression.accept(self) | |
| 461 | fi | |
| 462 | ||
| 463 | if element.initializer? then | |
| 464 | write(" = ") | |
| 465 | element.initializer!.accept(self) | |
| 466 | fi | |
| 467 | si | |
| 468 | ||
| 469 | visit(ambiguous_expression: Expressions.AMBIGUOUS_EXPRESSION) is | |
| 470 | write("(ambiguous ") | |
| 471 | ||
| 472 | if let ambiguous_expression.left? then | |
| 473 | left.accept(self) | |
| 474 | write(".") | |
| 475 | fi | |
| 476 | ambiguous_expression.identifier.accept(self) | |
| 477 | write("[") | |
| 478 | ambiguous_expression.type_arguments.accept(self) | |
| 479 | write("] or ") | |
| 480 | ambiguous_expression.index.accept(self) | |
| 481 | write(")") | |
| 482 | si | |
| 483 | ||
| 484 | visit(generic_application: Expressions.GENERIC_APPLICATION) is | |
| 485 | if let generic_application.left? then | |
| 486 | left.accept(self) | |
| 487 | write(".") | |
| 488 | fi | |
| 489 | generic_application.identifier.accept(self) | |
| 490 | write("[") | |
| 491 | generic_application.type_arguments.accept(self) | |
| 492 | write("]") | |
| 493 | si | |
| 494 | ||
| 495 | visit(function: Syntax.Trees.Expressions.FUNCTION) is | |
| 496 | if let function.nested_name? then | |
| 497 | nested_name.accept(self) | |
| 498 | write("(") | |
| 499 | fi | |
| 500 | ||
| 501 | function.arguments.accept(self) | |
| 502 | ||
| 503 | if function.nested_name? then | |
| 504 | write(")") | |
| 505 | fi | |
| 506 | ||
| 507 | let type_expression = function.type_expression | |
| 508 | ||
| 509 | if !isa TypeExpressions.INFER(type_expression) then | |
| 510 | write(" -> ") | |
| 511 | type_expression.accept(self) | |
| 512 | fi | |
| 513 | ||
| 514 | function.body.accept(self) | |
| 515 | si | |
| 516 | ||
| 517 | visit(sequence: Expressions.SEQUENCE) is | |
| 518 | write('[') | |
| 519 | sequence.elements.accept(self) | |
| 520 | write(']') | |
| 521 | let type_expression = sequence.type_expression | |
| 522 | ||
| 523 | if !isa Trees.TypeExpressions.INFER(type_expression) then | |
| 524 | write(": ") | |
| 525 | type_expression.accept(self) | |
| 526 | fi | |
| 527 | si | |
| 528 | ||
| 529 | visit(unwrap: Expressions.HAS_VALUE) is | |
| 530 | unwrap.left.accept(self) | |
| 531 | write("?") | |
| 532 | si | |
| 533 | ||
| 534 | visit(has_value: Expressions.UNWRAP) is | |
| 535 | has_value.left.accept(self) | |
| 536 | write("!") | |
| 537 | si | |
| 538 | ||
| 539 | visit(has_value: Expressions.REFERENCE) is | |
| 540 | has_value.left.accept(self) | |
| 541 | write(" ref ") | |
| 542 | si | |
| 543 | ||
| 544 | visit(statement: Expressions.STATEMENT) is | |
| 545 | statement.statement.accept(self) | |
| 546 | write(";") | |
| 547 | si | |
| 548 | ||
| 549 | visit(block: Expressions.VAL_BLOCK) is | |
| 550 | if block.is_parenthesised then | |
| 551 | write("(") | |
| 552 | block.body.accept(self) | |
| 553 | write(")") | |
| 554 | else | |
| 555 | write("val ") | |
| 556 | block.body.accept(self) | |
| 557 | write("lav") | |
| 558 | fi | |
| 559 | si | |
| 560 | ||
| 561 | visit(f: Statements.FUNCTION) is | |
| 562 | f.function.accept(self) | |
| 563 | write_terminator() | |
| 564 | si | |
| 565 | ||
| 566 | visit(l: Statements.LET) is | |
| 567 | write("let ") | |
| 568 | l.variables.accept(self) | |
| 569 | write_terminator() | |
| 570 | si | |
| 571 | ||
| 572 | visit(rb: Statements.REFUTABLE_BINDING) is | |
| 573 | let first mut = true | |
| 574 | ||
| 575 | for c in rb.clauses do | |
| 576 | if !first then | |
| 577 | write(", ") | |
| 578 | fi | |
| 579 | ||
| 580 | if c.is_inferred_name then | |
| 581 | // Leaf-name shorthand: `path?` / `path: T`. | |
| 582 | c.scrutinee.accept(self) | |
| 583 | ||
| 584 | if let c.narrow_type_expression? then | |
| 585 | write(": ") | |
| 586 | narrow_type_expression.accept(self) | |
| 587 | else | |
| 588 | write("?") | |
| 589 | fi | |
| 590 | else | |
| 591 | c.pattern.accept(self) | |
| 592 | ||
| 593 | if let c.narrow_type_expression? then | |
| 594 | write(": ") | |
| 595 | narrow_type_expression.accept(self) | |
| 596 | fi | |
| 597 | ||
| 598 | write(" = ") | |
| 599 | c.scrutinee.accept(self) | |
| 600 | fi | |
| 601 | ||
| 602 | if let c.guard? then | |
| 603 | write(" /\\ ") | |
| 604 | guard.accept(self) | |
| 605 | fi | |
| 606 | ||
| 607 | first = false | |
| 608 | od | |
| 609 | si | |
| 610 | ||
| 611 | visit(`for: Statements.FOR) is | |
| 612 | write_line("for ") | |
| 613 | ||
| 614 | let variable = `for.variable | |
| 615 | if variable? then | |
| 616 | variable.accept(self) | |
| 617 | fi | |
| 618 | ||
| 619 | write(" in ") | |
| 620 | ||
| 621 | let expression = `for.expression | |
| 622 | if expression? then | |
| 623 | expression.accept(self) | |
| 624 | fi | |
| 625 | ||
| 626 | write_line(" do") | |
| 627 | indent() | |
| 628 | ||
| 629 | let body = `for.body | |
| 630 | if body? then | |
| 631 | body.accept(self) | |
| 632 | fi | |
| 633 | ||
| 634 | outdent() | |
| 635 | write_line("od") | |
| 636 | si | |
| 637 | ||
| 638 | visit(expression: Bodies.EXPRESSION) is | |
| 639 | write("=> ") | |
| 640 | expression.expression.accept(self) | |
| 641 | si | |
| 642 | ||
| 643 | visit(block: Bodies.BLOCK) is | |
| 644 | write_line("is") | |
| 645 | indent() | |
| 646 | block.statements.accept(self) | |
| 647 | outdent() | |
| 648 | write("si") | |
| 649 | si | |
| 650 | ||
| 651 | visit(`innate: Bodies.INNATE) is | |
| 652 | `innate.name.accept(self) | |
| 653 | si | |
| 654 | si | |
| 655 | si |