X-Git-Url: http://nitlanguage.org diff --git a/src/parser/parser_nodes.nit b/src/parser/parser_nodes.nit index 5204376..0c535c2 100644 --- a/src/parser/parser_nodes.nit +++ b/src/parser/parser_nodes.nit @@ -18,10 +18,11 @@ module parser_nodes import location import ordered_tree +private import console # Root of the AST class-hierarchy abstract class ANode - # Location is set during AST building. Once built, location cannon be null. + # Location is set during AST building. Once built, location can not be null. # However, manual instantiated nodes may need more care. var location: Location is writable, noinit @@ -34,15 +35,28 @@ abstract class ANode sys.stderr.write "{hot_location} {self.class_name}: {message}\n{hot_location.colored_line("0;32")}\n" end + # Is `self` a token or a pure-structural production like `AQId`? + fun is_structural: Bool do return false + # Write the subtree on stdout. - # See `ASTDump` - fun dump_tree + # + # Visit the subtree and display it with additional and useful information. + # + # By default, this displays all kind of nodes and the corresponding lines of codes. + # + # See `ASTDump` for details. + fun dump_tree(display_structural, display_line: nullable Bool) do - var d = new ASTDump + var d = new ASTDump(display_structural or else true, display_line or else true) d.enter_visit(self) d.write_to(sys.stdout) end + # Information to display on a node + # + # Refine this method to add additional information on each node type. + fun dump_info(v: ASTDump): String do return "" + # Parent of the node in the AST var parent: nullable ANode = null @@ -177,8 +191,22 @@ class ASTDump # Is used to handle the initial node parent and workaround possible inconsistent `ANode::parent` private var last_parent: nullable ANode = null + # Display tokens and structural production? + # + # Should tokens (and structural production like AQId) be displayed? + var display_structural: Bool + + # Display lines? + # + # Should each new line be displayed (numbered and in gray)? + var display_line: Bool + + # Current line number (when printing lines) + private var line = 0 + redef fun visit(n) do + if not display_structural and n.is_structural then return var p = last_parent add(p, n) last_parent = n @@ -186,14 +214,35 @@ class ASTDump last_parent = p end - redef fun display(n) + redef fun write_line(o, n, p) do - if n isa Token then - return "{n.class_name} \"{n.text.escape_to_c}\" @{n.location}" - else - return "{n.class_name} @{n.location}" + if display_line then + var ls = n.location.line_start + var file = n.location.file + var line = self.line + if ls > line and file != null then + if line == 0 then line = ls - 1 + while line < ls do + line += 1 + o.write "{line}\t{file.get_line(line)}\n".light_gray + end + self.line = ls + end end + + super end + + redef fun display(n) + do + return "{n.class_name} {n.dump_info(self)} @{n.location}" + end + + # `s` as yellow + fun yellow(s: String): String do return s.yellow + + # `s` as red + fun red(s: String): String do return s.red end # A sequence of nodes @@ -331,6 +380,10 @@ abstract class Token # See `blank_before` to get the whitespace that separate tokens. var is_loose = false + redef fun is_structural do return true + + redef fun dump_info(v) do return " {text.escape_to_c}" + # Loose tokens that precede `self`. # # These tokens start the line or belong to a line with only loose tokens. @@ -481,11 +534,16 @@ class TKwinterface super TokenKeyword end -# The keywords `enum` ane `universal` +# The keywords `enum` and `universal` class TKwenum super TokenKeyword end +# The keyword `subset` +class TKwsubset + super TokenKeyword +end + # The keyword `end` class TKwend super TokenKeyword @@ -521,6 +579,11 @@ class TKwdo super TokenKeyword end +# The keyword `catch` +class TKwcatch + super TokenKeyword +end + # The keyword `var` class TKwvar super TokenKeyword @@ -696,6 +759,11 @@ class TKwwith super TokenKeyword end +# The keyword `yield` +class TKwyield + super TokenKeyword +end + # The special keyword `__DEBUG__` class TKwdebug super Token @@ -1010,6 +1078,11 @@ class TBadString end end +# A malformed triple quoted string +class TBadTString + super TBadString +end + # A malformed char class TBadChar super Token @@ -1024,6 +1097,15 @@ class TExternCodeSegment super Token end +# A malformed extern code block +class TBadExtern + super Token + redef fun to_s + do + do return "malformed extern segment {text}" + end +end + # A end of file class EOF super Token @@ -1126,7 +1208,7 @@ end class APublicVisibility super AVisibility # The `public` keyword, if any - var n_kwpublic: nullable TKwpublic is writable + var n_kwpublic: nullable TKwpublic = null is writable end # An explicit private visibility modifier class APrivateVisibility @@ -1148,8 +1230,9 @@ class AIntrudeVisibility end # A class definition -# While most definition are `AStdClassdef` -# There is tow special case of class definition +# +# While most definitions are `AStdClassdef`s, +# there are 2 special cases of class definitions. abstract class AClassdef super Prod # All the declared properties (including the main method) @@ -1165,7 +1248,7 @@ class AStdClassdef var n_classkind: AClasskind is writable, noinit # The name of the class - var n_id: nullable TClassid = null is writable + var n_qid: nullable AQclassid = null is writable # The `[` symbol var n_obra: nullable TObra = null is writable @@ -1186,7 +1269,7 @@ class AStdClassdef return [for d in n_propdefs do if d isa ASuperPropdef then d] end - redef fun hot_location do return n_id.location + redef fun hot_location do return n_qid.location end # The implicit class definition of the implicit main method @@ -1250,6 +1333,18 @@ class AExternClasskind var n_kwclass: nullable TKwclass = null is writable end +class ASubsetClasskind + super AClasskind + + # The `subset` keyword. + var n_kwsubset: TKwsubset is writable, noinit + + redef fun visit_all(v) do + # TODO: Remove this redefinition once generated from the grammar. + v.enter_visit(n_kwsubset) + end +end + # The definition of a formal generic parameter type. eg `X: Y` class AFormaldef super Prod @@ -1311,6 +1406,9 @@ class AMethPropdef # The `init` keyword, if any var n_kwinit: nullable TKwinit = null is writable + # The `isa` keyword, if any + var n_kwisa: nullable TKwisa = null is writable + # The `new` keyword, if any var n_kwnew: nullable TKwnew = null is writable @@ -1491,7 +1589,7 @@ class ATypePropdef var n_kwtype: TKwtype is writable, noinit # The name of the virtual type - var n_id: TClassid is writable, noinit + var n_qid: AQclassid is writable, noinit # The bound of the virtual type var n_type: AType is writable, noinit @@ -1657,6 +1755,20 @@ class AQid # The final identifier var n_id: TId is writable, noinit + + redef fun is_structural do return true +end + +# A potentially qualified class identifier `foo::bar::Baz` +class AQclassid + super Prod + # The qualifier, if any + var n_qualified: nullable AQualified = null is writable + + # The final identifier + var n_id: TClassid is writable, noinit + + redef fun is_structural do return true end # A signature in a method definition. eg `(x,y:X,z:Z):T` @@ -1697,7 +1809,7 @@ class AType var n_kwnullable: nullable TKwnullable = null is writable # The name of the class or of the formal type - var n_id: TClassid is writable, noinit + var n_qid: AQclassid is writable, noinit # The opening bracket var n_obra: nullable TObra = null is writable @@ -1761,10 +1873,18 @@ end # A `return` statement. eg `return x` class AReturnExpr - super AExpr + super AEscapeExpr # The `return` keyword var n_kwreturn: nullable TKwreturn = null is writable +end + +# A `yield` statement. eg `yield x` +class AYieldExpr + super AExpr + + # The `yield` keyword + var n_kwyield: nullable TKwyield = null is writable # The return value, if any var n_expr: nullable AExpr = null is writable @@ -1821,6 +1941,12 @@ class ADoExpr # The list of statements of the `do`. var n_block: nullable AExpr = null is writable + + # The `catch` keyword + var n_kwcatch: nullable TKwcatch = null is writable + + # The do catch block + var n_catch: nullable AExpr = null is writable end # A `if` statement @@ -1907,6 +2033,23 @@ class AForExpr # The `for` keyword var n_kwfor: TKwfor is writable, noinit + # The list of groups to iterate + var n_groups = new ANodes[AForGroup](self) + + # The `do` keyword + var n_kwdo: TKwdo is writable, noinit + + # The body of the loop + var n_block: nullable AExpr = null is writable +end + +# A collection iterated by a for, its automatic variables and its implicit iterator. +# +# Standard `for` iterate on a single collection. +# Multiple `for` can iterate on more than one collection at once. +class AForGroup + super Prod + # The list of name of the automatic variables var n_ids = new ANodes[TId](self) @@ -1915,12 +2058,6 @@ class AForExpr # The expression used as the collection to iterate on var n_expr: AExpr is writable, noinit - - # The `do` keyword - var n_kwdo: TKwdo is writable, noinit - - # The body of the loop - var n_block: nullable AExpr = null is writable end # A `with` statement @@ -2920,7 +3057,8 @@ abstract class AAtid super Prod # The identifier of the annotation. - # Can be a TId of a keyword + # + # Can be a TId or a keyword. var n_id: Token is writable, noinit end