Appearance
| 1 | namespace Syntax.Parsers is | |
| 2 | use Trees.Definitions.Definition | |
| 3 | use Trees.Statements.Statement | |
| 4 | ||
| 5 | // What the last thing at the root of a parsed file is, for a front end | |
| 6 | // that runs a program as it is typed and wants to know whether what | |
| 7 | // was just finished has a value worth showing or is setting something | |
| 8 | // up for what follows: | |
| 9 | // | |
| 10 | // - `expression`: an expression, or an `if` or `case`, which can end | |
| 11 | // on a value | |
| 12 | // - `loop`: a `for`, `while` or `do` loop | |
| 13 | // - `let`: a local variable definition | |
| 14 | // - `assignment`: an assignment | |
| 15 | // - `function`: a named function written among the statements | |
| 16 | // - `definition`: anything written as a definition - a function, | |
| 17 | // type, `use` or alias at the file root | |
| 18 | // - `statement`: any other statement, such as an `assert` or `throw` | |
| 19 | // | |
| 20 | // Null when the file has nothing at its root. | |
| 21 | class LAST_STATEMENT_KIND is | |
| 22 | init() is si | |
| 23 | ||
| 24 | of(root: Trees.Definitions.LIST) -> string? static is | |
| 25 | let definition = _last_definition(root) | |
| 26 | let statements = root.top_level_statements | |
| 27 | ||
| 28 | let statement: Statement? mut = null | |
| 29 | ||
| 30 | if let list = statements then | |
| 31 | for s in list.statements do | |
| 32 | statement = s | |
| 33 | od | |
| 34 | fi | |
| 35 | ||
| 36 | if let d = definition, s = statement then | |
| 37 | return if d.location.start_line > s.location.start_line \/ | |
| 38 | (d.location.start_line == s.location.start_line /\ d.location.start_column > s.location.start_column) | |
| 39 | then | |
| 40 | "definition" | |
| 41 | else | |
| 42 | of_statement(s) | |
| 43 | fi | |
| 44 | elif definition? then | |
| 45 | return "definition" | |
| 46 | elif let s = statement then | |
| 47 | return of_statement(s) | |
| 48 | fi | |
| 49 | ||
| 50 | return null | |
| 51 | si | |
| 52 | ||
| 53 | of_statement(statement: Statement) -> string static is | |
| 54 | if let labelled = cast Trees.Statements.LABELLED?(statement) then | |
| 55 | return of_statement(labelled.statement) | |
| 56 | fi | |
| 57 | ||
| 58 | if isa Trees.Statements.EXPRESSION(statement) \/ isa Trees.Statements.IF(statement) \/ isa Trees.Statements.CASE(statement) then | |
| 59 | return "expression" | |
| 60 | elif isa Trees.Statements.FOR(statement) \/ isa Trees.Statements.DO(statement) then | |
| 61 | return "loop" | |
| 62 | elif isa Trees.Statements.LET(statement) then | |
| 63 | return "let" | |
| 64 | elif isa Trees.Statements.ASSIGNMENT(statement) then | |
| 65 | return "assignment" | |
| 66 | elif isa Trees.Statements.FUNCTION(statement) then | |
| 67 | return "function" | |
| 68 | fi | |
| 69 | ||
| 70 | return "statement" | |
| 71 | si | |
| 72 | ||
| 73 | _last_definition(root: Trees.Definitions.LIST) -> Definition? static is | |
| 74 | let result: Definition? mut = null | |
| 75 | ||
| 76 | for d in root do | |
| 77 | result = d | |
| 78 | od | |
| 79 | ||
| 80 | return result | |
| 81 | si | |
| 82 | si | |
| 83 | si |