[ruby/prism] Introduce non-associativility to in
and =>
Fix https://github.com/ruby/prism/pull/1596 Fix https://github.com/ruby/prism/pull/1771 Close https://github.com/ruby/prism/pull/1773 https://github.com/ruby/prism/commit/a3413e5605
This commit is contained in:
parent
64f03460ba
commit
cd91e8e73a
@ -9719,7 +9719,7 @@ parser_lex(pm_parser_t *parser) {
|
||||
typedef enum {
|
||||
PM_BINDING_POWER_UNSET = 0, // used to indicate this token cannot be used as an infix operator
|
||||
PM_BINDING_POWER_STATEMENT = 2,
|
||||
PM_BINDING_POWER_MODIFIER = 4, // if unless until while in
|
||||
PM_BINDING_POWER_MODIFIER = 4, // if unless until while
|
||||
PM_BINDING_POWER_MODIFIER_RESCUE = 6, // rescue
|
||||
PM_BINDING_POWER_COMPOSITION = 8, // and or
|
||||
PM_BINDING_POWER_NOT = 10, // not
|
||||
@ -9758,34 +9758,44 @@ typedef struct {
|
||||
|
||||
/** Whether or not this token can be used as a binary operator. */
|
||||
bool binary;
|
||||
|
||||
/**
|
||||
* Whether or not this token can be used as non associative binary operator.
|
||||
* Usually, non associative operator can be handled by using the above left
|
||||
* and right binding powers, but some operators (e.g. in and =>) need special
|
||||
* treatment since they do not call parse_expression recursively.
|
||||
*/
|
||||
bool nonassoc;
|
||||
} pm_binding_powers_t;
|
||||
|
||||
#define BINDING_POWER_ASSIGNMENT { PM_BINDING_POWER_UNARY, PM_BINDING_POWER_ASSIGNMENT, true }
|
||||
#define LEFT_ASSOCIATIVE(precedence) { precedence, precedence + 1, true }
|
||||
#define RIGHT_ASSOCIATIVE(precedence) { precedence, precedence, true }
|
||||
#define RIGHT_ASSOCIATIVE_UNARY(precedence) { precedence, precedence, false }
|
||||
#define BINDING_POWER_ASSIGNMENT { PM_BINDING_POWER_UNARY, PM_BINDING_POWER_ASSIGNMENT, true, false }
|
||||
#define LEFT_ASSOCIATIVE(precedence) { precedence, precedence + 1, true, false }
|
||||
#define RIGHT_ASSOCIATIVE(precedence) { precedence, precedence, true, false }
|
||||
#define NON_ASSOCIATIVE(precedence) { precedence + 1, precedence + 1, true, true }
|
||||
#define RIGHT_ASSOCIATIVE_UNARY(precedence) { precedence, precedence, false, false }
|
||||
|
||||
pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = {
|
||||
// if unless until while in rescue
|
||||
// if unless until while
|
||||
[PM_TOKEN_KEYWORD_IF_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
|
||||
[PM_TOKEN_KEYWORD_UNLESS_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
|
||||
[PM_TOKEN_KEYWORD_UNTIL_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
|
||||
[PM_TOKEN_KEYWORD_WHILE_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
|
||||
[PM_TOKEN_KEYWORD_IN] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER),
|
||||
|
||||
// rescue modifier
|
||||
// rescue
|
||||
[PM_TOKEN_KEYWORD_RESCUE_MODIFIER] = {
|
||||
PM_BINDING_POWER_ASSIGNMENT,
|
||||
PM_BINDING_POWER_MODIFIER_RESCUE + 1,
|
||||
true
|
||||
true,
|
||||
false
|
||||
},
|
||||
|
||||
// and or
|
||||
[PM_TOKEN_KEYWORD_AND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION),
|
||||
[PM_TOKEN_KEYWORD_OR] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION),
|
||||
|
||||
// =>
|
||||
[PM_TOKEN_EQUAL_GREATER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MATCH),
|
||||
// => in
|
||||
[PM_TOKEN_EQUAL_GREATER] = NON_ASSOCIATIVE(PM_BINDING_POWER_MATCH),
|
||||
[PM_TOKEN_KEYWORD_IN] = NON_ASSOCIATIVE(PM_BINDING_POWER_MATCH),
|
||||
|
||||
// &&= &= ^= = >>= <<= -= %= |= += /= *= **=
|
||||
[PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL] = BINDING_POWER_ASSIGNMENT,
|
||||
@ -9853,7 +9863,7 @@ pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = {
|
||||
|
||||
// -@
|
||||
[PM_TOKEN_UMINUS] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UMINUS),
|
||||
[PM_TOKEN_UMINUS_NUM] = { PM_BINDING_POWER_UMINUS, PM_BINDING_POWER_MAX, false },
|
||||
[PM_TOKEN_UMINUS_NUM] = { PM_BINDING_POWER_UMINUS, PM_BINDING_POWER_MAX, false, false },
|
||||
|
||||
// **
|
||||
[PM_TOKEN_STAR_STAR] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_EXPONENT),
|
||||
@ -16212,6 +16222,12 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, pm_diagn
|
||||
current_binding_powers.binary
|
||||
) {
|
||||
node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right);
|
||||
if (
|
||||
current_binding_powers.nonassoc &&
|
||||
current_binding_powers.right <= pm_binding_powers[parser->current.type].left
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
|
@ -190,3 +190,6 @@ foo in A[
|
||||
value: a
|
||||
]
|
||||
]
|
||||
|
||||
foo in bar => baz
|
||||
foo => bar => baz
|
||||
|
@ -9,3 +9,5 @@ next until true
|
||||
return until true
|
||||
|
||||
foo :a, :b until bar?
|
||||
|
||||
foo while bar in baz
|
||||
|
@ -19,3 +19,5 @@ while class << self; tap do end; end; break; end
|
||||
while class << self; a = tap do end; end; break; end
|
||||
|
||||
while def foo = bar do end; end
|
||||
|
||||
foo while bar in baz
|
||||
|
@ -1,8 +1,8 @@
|
||||
@ ProgramNode (location: (1,0)-(192,1))
|
||||
@ ProgramNode (location: (1,0)-(195,17))
|
||||
├── locals: [:bar, :baz, :qux, :b, :a]
|
||||
└── statements:
|
||||
@ StatementsNode (location: (1,0)-(192,1))
|
||||
└── body: (length: 170)
|
||||
@ StatementsNode (location: (1,0)-(195,17))
|
||||
└── body: (length: 172)
|
||||
├── @ MatchRequiredNode (location: (1,0)-(1,10))
|
||||
│ ├── value:
|
||||
│ │ @ CallNode (location: (1,0)-(1,3))
|
||||
@ -4449,12 +4449,87 @@
|
||||
│ │ ├── opening_loc: (184,5)-(184,6) = "["
|
||||
│ │ └── closing_loc: (186,0)-(186,1) = "]"
|
||||
│ └── operator_loc: (184,2)-(184,4) = "=>"
|
||||
└── @ MatchPredicateNode (location: (188,0)-(192,1))
|
||||
├── @ MatchPredicateNode (location: (188,0)-(192,1))
|
||||
│ ├── value:
|
||||
│ │ @ CallNode (location: (188,0)-(188,3))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (188,0)-(188,3) = "foo"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: variable_call
|
||||
│ │ └── name: :foo
|
||||
│ ├── pattern:
|
||||
│ │ @ HashPatternNode (location: (188,7)-(192,1))
|
||||
│ │ ├── constant:
|
||||
│ │ │ @ ConstantReadNode (location: (188,7)-(188,8))
|
||||
│ │ │ └── name: :A
|
||||
│ │ ├── elements: (length: 1)
|
||||
│ │ │ └── @ AssocNode (location: (189,2)-(191,3))
|
||||
│ │ │ ├── key:
|
||||
│ │ │ │ @ SymbolNode (location: (189,2)-(189,6))
|
||||
│ │ │ │ ├── opening_loc: ∅
|
||||
│ │ │ │ ├── value_loc: (189,2)-(189,5) = "bar"
|
||||
│ │ │ │ ├── closing_loc: (189,5)-(189,6) = ":"
|
||||
│ │ │ │ └── unescaped: "bar"
|
||||
│ │ │ ├── value:
|
||||
│ │ │ │ @ HashPatternNode (location: (189,7)-(191,3))
|
||||
│ │ │ │ ├── constant:
|
||||
│ │ │ │ │ @ ConstantReadNode (location: (189,7)-(189,8))
|
||||
│ │ │ │ │ └── name: :B
|
||||
│ │ │ │ ├── elements: (length: 1)
|
||||
│ │ │ │ │ └── @ AssocNode (location: (190,4)-(190,12))
|
||||
│ │ │ │ │ ├── key:
|
||||
│ │ │ │ │ │ @ SymbolNode (location: (190,4)-(190,10))
|
||||
│ │ │ │ │ │ ├── opening_loc: ∅
|
||||
│ │ │ │ │ │ ├── value_loc: (190,4)-(190,9) = "value"
|
||||
│ │ │ │ │ │ ├── closing_loc: (190,9)-(190,10) = ":"
|
||||
│ │ │ │ │ │ └── unescaped: "value"
|
||||
│ │ │ │ │ ├── value:
|
||||
│ │ │ │ │ │ @ LocalVariableTargetNode (location: (190,11)-(190,12))
|
||||
│ │ │ │ │ │ ├── name: :a
|
||||
│ │ │ │ │ │ └── depth: 0
|
||||
│ │ │ │ │ └── operator_loc: ∅
|
||||
│ │ │ │ ├── rest: ∅
|
||||
│ │ │ │ ├── opening_loc: (189,8)-(189,9) = "["
|
||||
│ │ │ │ └── closing_loc: (191,2)-(191,3) = "]"
|
||||
│ │ │ └── operator_loc: ∅
|
||||
│ │ ├── rest: ∅
|
||||
│ │ ├── opening_loc: (188,8)-(188,9) = "["
|
||||
│ │ └── closing_loc: (192,0)-(192,1) = "]"
|
||||
│ └── operator_loc: (188,4)-(188,6) = "in"
|
||||
├── @ MatchPredicateNode (location: (194,0)-(194,17))
|
||||
│ ├── value:
|
||||
│ │ @ CallNode (location: (194,0)-(194,3))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (194,0)-(194,3) = "foo"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: variable_call
|
||||
│ │ └── name: :foo
|
||||
│ ├── pattern:
|
||||
│ │ @ CapturePatternNode (location: (194,7)-(194,17))
|
||||
│ │ ├── value:
|
||||
│ │ │ @ LocalVariableTargetNode (location: (194,7)-(194,10))
|
||||
│ │ │ ├── name: :bar
|
||||
│ │ │ └── depth: 0
|
||||
│ │ ├── target:
|
||||
│ │ │ @ LocalVariableTargetNode (location: (194,14)-(194,17))
|
||||
│ │ │ ├── name: :baz
|
||||
│ │ │ └── depth: 0
|
||||
│ │ └── operator_loc: (194,11)-(194,13) = "=>"
|
||||
│ └── operator_loc: (194,4)-(194,6) = "in"
|
||||
└── @ MatchRequiredNode (location: (195,0)-(195,17))
|
||||
├── value:
|
||||
│ @ CallNode (location: (188,0)-(188,3))
|
||||
│ @ CallNode (location: (195,0)-(195,3))
|
||||
│ ├── receiver: ∅
|
||||
│ ├── call_operator_loc: ∅
|
||||
│ ├── message_loc: (188,0)-(188,3) = "foo"
|
||||
│ ├── message_loc: (195,0)-(195,3) = "foo"
|
||||
│ ├── opening_loc: ∅
|
||||
│ ├── arguments: ∅
|
||||
│ ├── closing_loc: ∅
|
||||
@ -4462,41 +4537,14 @@
|
||||
│ ├── flags: variable_call
|
||||
│ └── name: :foo
|
||||
├── pattern:
|
||||
│ @ HashPatternNode (location: (188,7)-(192,1))
|
||||
│ ├── constant:
|
||||
│ │ @ ConstantReadNode (location: (188,7)-(188,8))
|
||||
│ │ └── name: :A
|
||||
│ ├── elements: (length: 1)
|
||||
│ │ └── @ AssocNode (location: (189,2)-(191,3))
|
||||
│ │ ├── key:
|
||||
│ │ │ @ SymbolNode (location: (189,2)-(189,6))
|
||||
│ │ │ ├── opening_loc: ∅
|
||||
│ │ │ ├── value_loc: (189,2)-(189,5) = "bar"
|
||||
│ │ │ ├── closing_loc: (189,5)-(189,6) = ":"
|
||||
│ │ │ └── unescaped: "bar"
|
||||
│ │ ├── value:
|
||||
│ │ │ @ HashPatternNode (location: (189,7)-(191,3))
|
||||
│ │ │ ├── constant:
|
||||
│ │ │ │ @ ConstantReadNode (location: (189,7)-(189,8))
|
||||
│ │ │ │ └── name: :B
|
||||
│ │ │ ├── elements: (length: 1)
|
||||
│ │ │ │ └── @ AssocNode (location: (190,4)-(190,12))
|
||||
│ │ │ │ ├── key:
|
||||
│ │ │ │ │ @ SymbolNode (location: (190,4)-(190,10))
|
||||
│ │ │ │ │ ├── opening_loc: ∅
|
||||
│ │ │ │ │ ├── value_loc: (190,4)-(190,9) = "value"
|
||||
│ │ │ │ │ ├── closing_loc: (190,9)-(190,10) = ":"
|
||||
│ │ │ │ │ └── unescaped: "value"
|
||||
│ │ │ │ ├── value:
|
||||
│ │ │ │ │ @ LocalVariableTargetNode (location: (190,11)-(190,12))
|
||||
│ │ │ │ │ ├── name: :a
|
||||
│ │ │ │ │ └── depth: 0
|
||||
│ │ │ │ └── operator_loc: ∅
|
||||
│ │ │ ├── rest: ∅
|
||||
│ │ │ ├── opening_loc: (189,8)-(189,9) = "["
|
||||
│ │ │ └── closing_loc: (191,2)-(191,3) = "]"
|
||||
│ │ └── operator_loc: ∅
|
||||
│ ├── rest: ∅
|
||||
│ ├── opening_loc: (188,8)-(188,9) = "["
|
||||
│ └── closing_loc: (192,0)-(192,1) = "]"
|
||||
└── operator_loc: (188,4)-(188,6) = "in"
|
||||
│ @ CapturePatternNode (location: (195,7)-(195,17))
|
||||
│ ├── value:
|
||||
│ │ @ LocalVariableTargetNode (location: (195,7)-(195,10))
|
||||
│ │ ├── name: :bar
|
||||
│ │ └── depth: 0
|
||||
│ ├── target:
|
||||
│ │ @ LocalVariableTargetNode (location: (195,14)-(195,17))
|
||||
│ │ ├── name: :baz
|
||||
│ │ └── depth: 0
|
||||
│ └── operator_loc: (195,11)-(195,13) = "=>"
|
||||
└── operator_loc: (195,4)-(195,6) = "=>"
|
||||
|
@ -1,8 +1,8 @@
|
||||
@ ProgramNode (location: (1,0)-(11,21))
|
||||
├── locals: []
|
||||
@ ProgramNode (location: (1,0)-(13,20))
|
||||
├── locals: [:baz]
|
||||
└── statements:
|
||||
@ StatementsNode (location: (1,0)-(11,21))
|
||||
└── body: (length: 6)
|
||||
@ StatementsNode (location: (1,0)-(13,20))
|
||||
└── body: (length: 7)
|
||||
├── @ UntilNode (location: (1,0)-(1,18))
|
||||
│ ├── keyword_loc: (1,0)-(1,5) = "until"
|
||||
│ ├── closing_loc: (1,15)-(1,18) = "end"
|
||||
@ -61,44 +61,79 @@
|
||||
│ │ ├── keyword_loc: (9,0)-(9,6) = "return"
|
||||
│ │ └── arguments: ∅
|
||||
│ └── flags: ∅
|
||||
└── @ UntilNode (location: (11,0)-(11,21))
|
||||
├── keyword_loc: (11,11)-(11,16) = "until"
|
||||
├── @ UntilNode (location: (11,0)-(11,21))
|
||||
│ ├── keyword_loc: (11,11)-(11,16) = "until"
|
||||
│ ├── closing_loc: ∅
|
||||
│ ├── predicate:
|
||||
│ │ @ CallNode (location: (11,17)-(11,21))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (11,17)-(11,21) = "bar?"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: ∅
|
||||
│ │ └── name: :bar?
|
||||
│ ├── statements:
|
||||
│ │ @ StatementsNode (location: (11,0)-(11,10))
|
||||
│ │ └── body: (length: 1)
|
||||
│ │ └── @ CallNode (location: (11,0)-(11,10))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (11,0)-(11,3) = "foo"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments:
|
||||
│ │ │ @ ArgumentsNode (location: (11,4)-(11,10))
|
||||
│ │ │ ├── arguments: (length: 2)
|
||||
│ │ │ │ ├── @ SymbolNode (location: (11,4)-(11,6))
|
||||
│ │ │ │ │ ├── opening_loc: (11,4)-(11,5) = ":"
|
||||
│ │ │ │ │ ├── value_loc: (11,5)-(11,6) = "a"
|
||||
│ │ │ │ │ ├── closing_loc: ∅
|
||||
│ │ │ │ │ └── unescaped: "a"
|
||||
│ │ │ │ └── @ SymbolNode (location: (11,8)-(11,10))
|
||||
│ │ │ │ ├── opening_loc: (11,8)-(11,9) = ":"
|
||||
│ │ │ │ ├── value_loc: (11,9)-(11,10) = "b"
|
||||
│ │ │ │ ├── closing_loc: ∅
|
||||
│ │ │ │ └── unescaped: "b"
|
||||
│ │ │ └── flags: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: ∅
|
||||
│ │ └── name: :foo
|
||||
│ └── flags: ∅
|
||||
└── @ WhileNode (location: (13,0)-(13,20))
|
||||
├── keyword_loc: (13,4)-(13,9) = "while"
|
||||
├── closing_loc: ∅
|
||||
├── predicate:
|
||||
│ @ CallNode (location: (11,17)-(11,21))
|
||||
│ ├── receiver: ∅
|
||||
│ ├── call_operator_loc: ∅
|
||||
│ ├── message_loc: (11,17)-(11,21) = "bar?"
|
||||
│ ├── opening_loc: ∅
|
||||
│ ├── arguments: ∅
|
||||
│ ├── closing_loc: ∅
|
||||
│ ├── block: ∅
|
||||
│ ├── flags: ∅
|
||||
│ └── name: :bar?
|
||||
│ @ MatchPredicateNode (location: (13,10)-(13,20))
|
||||
│ ├── value:
|
||||
│ │ @ CallNode (location: (13,10)-(13,13))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (13,10)-(13,13) = "bar"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: variable_call
|
||||
│ │ └── name: :bar
|
||||
│ ├── pattern:
|
||||
│ │ @ LocalVariableTargetNode (location: (13,17)-(13,20))
|
||||
│ │ ├── name: :baz
|
||||
│ │ └── depth: 0
|
||||
│ └── operator_loc: (13,14)-(13,16) = "in"
|
||||
├── statements:
|
||||
│ @ StatementsNode (location: (11,0)-(11,10))
|
||||
│ @ StatementsNode (location: (13,0)-(13,3))
|
||||
│ └── body: (length: 1)
|
||||
│ └── @ CallNode (location: (11,0)-(11,10))
|
||||
│ └── @ CallNode (location: (13,0)-(13,3))
|
||||
│ ├── receiver: ∅
|
||||
│ ├── call_operator_loc: ∅
|
||||
│ ├── message_loc: (11,0)-(11,3) = "foo"
|
||||
│ ├── message_loc: (13,0)-(13,3) = "foo"
|
||||
│ ├── opening_loc: ∅
|
||||
│ ├── arguments:
|
||||
│ │ @ ArgumentsNode (location: (11,4)-(11,10))
|
||||
│ │ ├── arguments: (length: 2)
|
||||
│ │ │ ├── @ SymbolNode (location: (11,4)-(11,6))
|
||||
│ │ │ │ ├── opening_loc: (11,4)-(11,5) = ":"
|
||||
│ │ │ │ ├── value_loc: (11,5)-(11,6) = "a"
|
||||
│ │ │ │ ├── closing_loc: ∅
|
||||
│ │ │ │ └── unescaped: "a"
|
||||
│ │ │ └── @ SymbolNode (location: (11,8)-(11,10))
|
||||
│ │ │ ├── opening_loc: (11,8)-(11,9) = ":"
|
||||
│ │ │ ├── value_loc: (11,9)-(11,10) = "b"
|
||||
│ │ │ ├── closing_loc: ∅
|
||||
│ │ │ └── unescaped: "b"
|
||||
│ │ └── flags: ∅
|
||||
│ ├── arguments: ∅
|
||||
│ ├── closing_loc: ∅
|
||||
│ ├── block: ∅
|
||||
│ ├── flags: ∅
|
||||
│ ├── flags: variable_call
|
||||
│ └── name: :foo
|
||||
└── flags: ∅
|
||||
|
@ -1,8 +1,8 @@
|
||||
@ ProgramNode (location: (1,0)-(21,31))
|
||||
├── locals: []
|
||||
@ ProgramNode (location: (1,0)-(23,20))
|
||||
├── locals: [:baz]
|
||||
└── statements:
|
||||
@ StatementsNode (location: (1,0)-(21,31))
|
||||
└── body: (length: 11)
|
||||
@ StatementsNode (location: (1,0)-(23,20))
|
||||
└── body: (length: 12)
|
||||
├── @ WhileNode (location: (1,0)-(1,18))
|
||||
│ ├── keyword_loc: (1,0)-(1,5) = "while"
|
||||
│ ├── closing_loc: (1,15)-(1,18) = "end"
|
||||
@ -282,40 +282,75 @@
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ └── keyword_loc: (19,42)-(19,47) = "break"
|
||||
│ └── flags: ∅
|
||||
└── @ WhileNode (location: (21,0)-(21,31))
|
||||
├── keyword_loc: (21,0)-(21,5) = "while"
|
||||
├── closing_loc: (21,28)-(21,31) = "end"
|
||||
├── @ WhileNode (location: (21,0)-(21,31))
|
||||
│ ├── keyword_loc: (21,0)-(21,5) = "while"
|
||||
│ ├── closing_loc: (21,28)-(21,31) = "end"
|
||||
│ ├── predicate:
|
||||
│ │ @ DefNode (location: (21,6)-(21,26))
|
||||
│ │ ├── name: :foo
|
||||
│ │ ├── name_loc: (21,10)-(21,13) = "foo"
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── parameters: ∅
|
||||
│ │ ├── body:
|
||||
│ │ │ @ StatementsNode (location: (21,16)-(21,26))
|
||||
│ │ │ └── body: (length: 1)
|
||||
│ │ │ └── @ CallNode (location: (21,16)-(21,26))
|
||||
│ │ │ ├── receiver: ∅
|
||||
│ │ │ ├── call_operator_loc: ∅
|
||||
│ │ │ ├── message_loc: (21,16)-(21,19) = "bar"
|
||||
│ │ │ ├── opening_loc: ∅
|
||||
│ │ │ ├── arguments: ∅
|
||||
│ │ │ ├── closing_loc: ∅
|
||||
│ │ │ ├── block:
|
||||
│ │ │ │ @ BlockNode (location: (21,20)-(21,26))
|
||||
│ │ │ │ ├── locals: []
|
||||
│ │ │ │ ├── parameters: ∅
|
||||
│ │ │ │ ├── body: ∅
|
||||
│ │ │ │ ├── opening_loc: (21,20)-(21,22) = "do"
|
||||
│ │ │ │ └── closing_loc: (21,23)-(21,26) = "end"
|
||||
│ │ │ ├── flags: ∅
|
||||
│ │ │ └── name: :bar
|
||||
│ │ ├── locals: []
|
||||
│ │ ├── def_keyword_loc: (21,6)-(21,9) = "def"
|
||||
│ │ ├── operator_loc: ∅
|
||||
│ │ ├── lparen_loc: ∅
|
||||
│ │ ├── rparen_loc: ∅
|
||||
│ │ ├── equal_loc: (21,14)-(21,15) = "="
|
||||
│ │ └── end_keyword_loc: ∅
|
||||
│ ├── statements: ∅
|
||||
│ └── flags: ∅
|
||||
└── @ WhileNode (location: (23,0)-(23,20))
|
||||
├── keyword_loc: (23,4)-(23,9) = "while"
|
||||
├── closing_loc: ∅
|
||||
├── predicate:
|
||||
│ @ DefNode (location: (21,6)-(21,26))
|
||||
│ ├── name: :foo
|
||||
│ ├── name_loc: (21,10)-(21,13) = "foo"
|
||||
│ ├── receiver: ∅
|
||||
│ ├── parameters: ∅
|
||||
│ ├── body:
|
||||
│ │ @ StatementsNode (location: (21,16)-(21,26))
|
||||
│ │ └── body: (length: 1)
|
||||
│ │ └── @ CallNode (location: (21,16)-(21,26))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (21,16)-(21,19) = "bar"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block:
|
||||
│ │ │ @ BlockNode (location: (21,20)-(21,26))
|
||||
│ │ │ ├── locals: []
|
||||
│ │ │ ├── parameters: ∅
|
||||
│ │ │ ├── body: ∅
|
||||
│ │ │ ├── opening_loc: (21,20)-(21,22) = "do"
|
||||
│ │ │ └── closing_loc: (21,23)-(21,26) = "end"
|
||||
│ │ ├── flags: ∅
|
||||
│ │ └── name: :bar
|
||||
│ ├── locals: []
|
||||
│ ├── def_keyword_loc: (21,6)-(21,9) = "def"
|
||||
│ ├── operator_loc: ∅
|
||||
│ ├── lparen_loc: ∅
|
||||
│ ├── rparen_loc: ∅
|
||||
│ ├── equal_loc: (21,14)-(21,15) = "="
|
||||
│ └── end_keyword_loc: ∅
|
||||
├── statements: ∅
|
||||
│ @ MatchPredicateNode (location: (23,10)-(23,20))
|
||||
│ ├── value:
|
||||
│ │ @ CallNode (location: (23,10)-(23,13))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (23,10)-(23,13) = "bar"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: variable_call
|
||||
│ │ └── name: :bar
|
||||
│ ├── pattern:
|
||||
│ │ @ LocalVariableTargetNode (location: (23,17)-(23,20))
|
||||
│ │ ├── name: :baz
|
||||
│ │ └── depth: 0
|
||||
│ └── operator_loc: (23,14)-(23,16) = "in"
|
||||
├── statements:
|
||||
│ @ StatementsNode (location: (23,0)-(23,3))
|
||||
│ └── body: (length: 1)
|
||||
│ └── @ CallNode (location: (23,0)-(23,3))
|
||||
│ ├── receiver: ∅
|
||||
│ ├── call_operator_loc: ∅
|
||||
│ ├── message_loc: (23,0)-(23,3) = "foo"
|
||||
│ ├── opening_loc: ∅
|
||||
│ ├── arguments: ∅
|
||||
│ ├── closing_loc: ∅
|
||||
│ ├── block: ∅
|
||||
│ ├── flags: variable_call
|
||||
│ └── name: :foo
|
||||
└── flags: ∅
|
||||
|
Loading…
x
Reference in New Issue
Block a user