From 719d314879719eb98099459199d3493f09694841 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Mon, 5 Oct 2020 15:04:11 -0300 Subject: [PATCH] Make `**` be right associative (#9684) --- spec/compiler/parser/parser_spec.cr | 1 + src/compiler/crystal/syntax/parser.cr | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/compiler/parser/parser_spec.cr b/spec/compiler/parser/parser_spec.cr index c9a4b7d2c0d8..cafa5246704a 100644 --- a/spec/compiler/parser/parser_spec.cr +++ b/spec/compiler/parser/parser_spec.cr @@ -136,6 +136,7 @@ module Crystal it_parses "foo[] /2", Call.new(Call.new("foo".call, "[]"), "/", 2.int32) it_parses "foo[1] /2", Call.new(Call.new("foo".call, "[]", 1.int32), "/", 2.int32) it_parses "[1] /2", Call.new(([1.int32] of ASTNode).array, "/", 2.int32) + it_parses "2**3**4", Call.new(2.int32, "**", Call.new(3.int32, "**", 4.int32)) it_parses "!1", Not.new(1.int32) it_parses "- 1", Call.new(1.int32, "-") diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr index 448b6fefc61c..5ddd2d007be9 100644 --- a/src/compiler/crystal/syntax/parser.cr +++ b/src/compiler/crystal/syntax/parser.cr @@ -504,7 +504,7 @@ module Crystal RangeLiteral.new(exp, right, exclusive).at(location).at_end(right) end - macro parse_operator(name, next_operator, node, operators) + macro parse_operator(name, next_operator, node, operators, right_associative = false) def parse_{{name.id}} location = @token.location @@ -521,7 +521,7 @@ module Crystal slash_is_regex! next_token_skip_space_or_newline - right = parse_{{next_operator.id}} + right = parse_{{(right_associative ? name : next_operator).id}} left = ({{node.id}}).at(location).at_end(right) left.name_location = name_location if left.is_a?(Call) else @@ -579,7 +579,7 @@ module Crystal end parse_operator :mul_or_div, :pow, "Call.new left, method, right", %(:"*", :"/", :"//", :"%", :"&*") - parse_operator :pow, :prefix, "Call.new left, method, right", %(:"**", :"&**") + parse_operator :pow, :prefix, "Call.new left, method, right", %(:"**", :"&**"), right_associative: true def parse_prefix name_location = @token.location