syntax: add lambda construction with the fun keyword
[nit.git] / src / parser / parser_nodes.nit
index 6d7233e..f19547d 100644 (file)
@@ -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
@@ -203,6 +252,7 @@ class ANodes[E: ANode]
        private var parent: ANode
        private var items = new Array[E]
        redef fun iterator do return items.iterator
+       redef fun reverse_iterator do return items.reverse_iterator
        redef fun length do return items.length
        redef fun is_empty do return items.is_empty
        redef fun push(e)
@@ -330,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.
@@ -480,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
@@ -520,6 +579,11 @@ class TKwdo
        super TokenKeyword
 end
 
+# The keyword `catch`
+class TKwcatch
+       super TokenKeyword
+end
+
 # The keyword `var`
 class TKwvar
        super TokenKeyword
@@ -695,6 +759,11 @@ class TKwwith
        super TokenKeyword
 end
 
+# The keyword `yield`
+class TKwyield
+       super TokenKeyword
+end
+
 # The special keyword `__DEBUG__`
 class TKwdebug
        super Token
@@ -914,6 +983,11 @@ class TStarship
        super TokenOperator
 end
 
+# The operator `?`
+class TQuest
+       super TokenOperator
+end
+
 # The operator `!`
 class TBang
        super TokenOperator
@@ -965,13 +1039,8 @@ abstract class TokenLiteral
        end
 end
 
-# A literal decimal integer
-class TNumber
-       super TokenLiteral
-end
-
-# A literal hexadecimal integer
-class THexNumber
+# A literal integer
+class TInteger
        super TokenLiteral
 end
 
@@ -1014,6 +1083,11 @@ class TBadString
        end
 end
 
+# A malformed triple quoted string
+class TBadTString
+       super TBadString
+end
+
 # A malformed char
 class TBadChar
        super Token
@@ -1028,6 +1102,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
@@ -1130,7 +1213,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
@@ -1152,8 +1235,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)
@@ -1169,7 +1253,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
@@ -1190,7 +1274,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
@@ -1254,6 +1338,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
@@ -1315,6 +1411,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
 
@@ -1495,7 +1594,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
@@ -1653,6 +1752,30 @@ class ABraassignMethid
        var n_assign: TAssign is writable, noinit
 end
 
+# A potentially qualified simple identifier `foo::bar::baz`
+class AQid
+       super Prod
+       # The qualifier, if any
+       var n_qualified: nullable AQualified = null is writable
+
+       # 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`
 class ASignature
        super Prod
@@ -1691,7 +1814,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
@@ -1755,10 +1878,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
@@ -1815,6 +1946,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
@@ -1901,6 +2038,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)
 
@@ -1909,12 +2063,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
@@ -2064,15 +2212,22 @@ class ANotExpr
        var n_expr: AExpr is writable, noinit
 end
 
+# A `==` or a `!=` expression
+#
+# Both have a similar effect on adaptive typing, so this class factorizes the common behavior.
+class AEqFormExpr
+       super ABinopExpr
+end
+
 # A `==` expression
 class AEqExpr
-       super ABinopExpr
+       super AEqFormExpr
        redef fun operator do return "=="
 end
 
 # A `!=` expression
 class ANeExpr
-       super ABinopExpr
+       super AEqFormExpr
        redef fun operator do return "!="
 end
 
@@ -2187,7 +2342,7 @@ class AAmpExpr
 end
 
 # A unary operation on a method
-class AUnaryopExpr
+abstract class AUnaryopExpr
        super ASendExpr
 
        # The operator
@@ -2226,7 +2381,7 @@ class ANewExpr
        var n_type: AType is writable, noinit
 
        # The name of the named-constructor, if any
-       var n_id: nullable TId = null is writable
+       var n_qid: nullable AQid = null is writable
 
        # The arguments of the `new`
        var n_args: AExprs is writable, noinit
@@ -2260,7 +2415,7 @@ abstract class ACallFormExpr
        super ASendExpr
 
        # The name of the method
-       var n_id: TId is writable, noinit
+       var n_qid: AQid is writable, noinit
 
        # The arguments of the call
        var n_args: AExprs is writable, noinit
@@ -2301,6 +2456,27 @@ class ACallReassignExpr
        super ASendReassignFormExpr
 end
 
+# A reference to a method with a captured receiver. eg. `&x.foo` or just `&foo` is self is captured.
+#
+# Currently, the syntax is analogous to a simple call (`recv.foo`) with a prefix `&`.
+# On chains, only the last call is captured (`.` has a higher precedence than `&`).
+#
+# The syntax is analogous to a call (except the &), there is always a receiver (including the implicit self or sys) and arguments are accepted by the parser.
+#
+# TODO There is no clear syntax proposal
+#
+# * to avoid the capture of a receiver since a receiver is statically expected to resolve the method name
+# * for special method names (setters, brackets and operators)
+#
+# Note: The class specializes `ASendExpr` (trough `ACallFormExpr`) so some behavior of a genuine send expression must be redefined.
+class ACallrefExpr
+       super ACallFormExpr
+
+       # The `&` operator
+       var n_amp: TAmp is writable, noinit
+end
+
+
 # A call to `super`. OR a call of a super-constructor
 class ASuperExpr
        super AExpr
@@ -2471,24 +2647,11 @@ class ANullExpr
 end
 
 # An integer literal
-class AIntExpr
+class AIntegerExpr
        super AExpr
-end
 
-# An integer literal in decimal format
-class ADecIntExpr
-       super AIntExpr
-
-       # The decimal token
-       var n_number: TNumber is writable, noinit
-end
-
-# An integer literal in hexadecimal format
-class AHexIntExpr
-       super AIntExpr
-
-       # The hexadecimal token
-       var n_hex_number: THexNumber is writable, noinit
+       # The integer token
+       var n_integer: TInteger is writable, noinit
 end
 
 # A float literal
@@ -2544,6 +2707,14 @@ class ASuperstringExpr
        var n_exprs = new ANodes[AExpr](self)
 end
 
+class ALambdaExpr
+       super AExpr
+       var n_kwmeth: TKwmeth is writable, noinit
+       var n_signature: ASignature is writable, noinit
+       var n_kwdo: TKwdo is writable, noinit
+       var n_expr: AExpr is writable, noinit
+end
+
 # A simple parenthesis. eg `(x)`
 class AParExpr
        super AExpr
@@ -2613,6 +2784,17 @@ class AVarargExpr
        var n_dotdotdot: TDotdotdot is writable, noinit
 end
 
+# A receiver with a `?` suffix used in safe call operator.
+class ASafeExpr
+       super AExpr
+
+       # The expression made safe
+       var n_expr: AExpr is writable, noinit
+
+       # The `?` symbol
+       var n_quest: TQuest is writable, noinit
+end
+
 # An named notation used to pass an expression by name in a parameter
 class ANamedargExpr
        super AExpr
@@ -2811,7 +2993,7 @@ class AModuleName
        # The starting quad (`::`)
        var n_quad: nullable TQuad = null is writable
 
-       # The list of quad-separated project/group identifiers
+       # The list of quad-separated package/group identifiers
        var n_path = new ANodes[TId](self)
 
        # The final module identifier
@@ -2847,7 +3029,7 @@ class AQualified
        # The starting quad (`::`)
        var n_quad: nullable TQuad = null is writable
 
-       # The list of quad-separated project/group/module identifiers
+       # The list of quad-separated package/group/module identifiers
        var n_id = new ANodes[TId](self)
 
        # A class identifier
@@ -2920,7 +3102,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