Skip to content

Commit

Permalink
Merge pull request #6927 from bcardiff/fix/parse-int-div
Browse files Browse the repository at this point in the history
Improve support for parsing and formatting //
  • Loading branch information
bcardiff authored Oct 11, 2018
2 parents 47b3fea + 85676b6 commit 252a9a7
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 8 deletions.
16 changes: 16 additions & 0 deletions spec/compiler/formatter/formatter_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,22 @@ describe Crystal::Formatter do
assert_format "def foo : Int32 \n end", "def foo : Int32\nend"
assert_format "def foo ( x ) : Int32 \n end", "def foo(x) : Int32\nend"
assert_format "def %(x)\n 1\nend"
assert_format "def //(x)\n 1\nend"
assert_format "def `(x)\n 1\nend"
assert_format "def /(x)\n 1\nend"
assert_format "def foo(x : X) forall X , Y; end", "def foo(x : X) forall X, Y; end"
assert_format "def foo(x)\n self // x\nend"
assert_format "def foo(x)\n case self // x\n when 2\n 3\n end\nend"
assert_format "def foo(x)\n case 1\n when self // 2\n 3\n end\nend"
assert_format "def foo(x)\n case //\n when //\n 3\n end\nend"
assert_format "foo self // 1"
assert_format "foo(self // 1)"
assert_format "foo x, self // 1"
assert_format "{x => self // 1}"
assert_format "foo(//, //)"
assert_format "foo(a: 1 // 2)"
assert_format "foo(a: //)"
assert_format "foo(a: //, b: //)"

assert_format "def foo(a : T) forall T \n #\nend", "def foo(a : T) forall T\n #\nend"
assert_format "def foo(a : T, b : U) forall T, U\n #\nend", "def foo(a : T, b : U) forall T, U\n #\nend"
Expand Down Expand Up @@ -308,6 +321,9 @@ describe Crystal::Formatter do
assert_format "1 / 2", "1 / 2"
assert_format "10/a", "10/a"
assert_format "10 / a", "10 / a"
assert_format "1 // 2", "1 // 2"
assert_format "10//a", "10//a"
assert_format "10 // a", "10 // a"
assert_format "10**a", "10**a"
assert_format "10 ** a", "10 ** a"
assert_format %(" " * 2)
Expand Down
7 changes: 7 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,10 @@ module Crystal
["<<", "<", "<=", "==", ">>", ">", ">=", "+", "-", "*", "/", "//", "%", "|", "&", "^", "**", "===", "=~", "!~", "&+", "&-", "&*", "&**"].each do |op|
it_parses "1 #{op} 2", Call.new(1.int32, op, 2.int32)
it_parses "n #{op} 2", Call.new("n".call, op, 2.int32)
it_parses "foo(n #{op} 2)", Call.new(nil, "foo", Call.new("n".call, op, 2.int32))
it_parses "foo(0, n #{op} 2)", Call.new(nil, "foo", 0.int32, Call.new("n".call, op, 2.int32))
it_parses "foo(a: n #{op} 2)", Call.new(nil, "foo", [] of ASTNode, named_args: [NamedArgument.new("a", Call.new("n".call, op, 2.int32))])
it_parses "foo(z: 0, a: n #{op} 2)", Call.new(nil, "foo", [] of ASTNode, named_args: [NamedArgument.new("z", 0.int32), NamedArgument.new("a", Call.new("n".call, op, 2.int32))])
it_parses "def #{op}(); end", Def.new(op)
it_parses "macro #{op};end", Macro.new(op, [] of Arg, Expressions.new)
end
Expand Down Expand Up @@ -942,6 +946,9 @@ module Crystal

it_parses "foo /a/", Call.new(nil, "foo", regex("a"))
it_parses "foo(/a/)", Call.new(nil, "foo", regex("a"))
it_parses "foo(//)", Call.new(nil, "foo", regex(""))
it_parses "foo(regex: //)", Call.new(nil, "foo", [] of ASTNode, named_args: [NamedArgument.new("regex", regex(""))])

it_parses "foo(/ /)", Call.new(nil, "foo", regex(" "))
it_parses "foo(/ /, / /)", Call.new(nil, "foo", [regex(" "), regex(" ")] of ASTNode)
it_parses "foo a, / /", Call.new(nil, "foo", ["a".call, regex(" ")] of ASTNode)
Expand Down
1 change: 1 addition & 0 deletions src/compiler/crystal/syntax/lexer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Crystal
property? count_whitespace : Bool
property? wants_raw : Bool
property? slash_is_regex : Bool
property? wants_def_or_macro_name : Bool
getter reader : Char::Reader
getter token : Token
property line_number : Int32
Expand Down
1 change: 1 addition & 0 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4325,6 +4325,7 @@ module Crystal
end

check :":"
slash_is_regex!
next_token_skip_space_or_newline

if @token.keyword?(:out)
Expand Down
20 changes: 12 additions & 8 deletions src/compiler/crystal/tools/formatter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1388,13 +1388,9 @@ module Crystal
write_token :"."
end

if @lexer.current_char == '%'
@token.type = :"%"
@token.column_number += 1
@lexer.next_char
end

@lexer.wants_def_or_macro_name = true
skip_space_or_newline
@lexer.wants_def_or_macro_name = false

write node.name
next_token_skip_space
Expand Down Expand Up @@ -2185,9 +2181,10 @@ module Crystal
if @token.type == :SPACE
needs_space = true
else
needs_space = node.name != "*" && node.name != "/" && node.name != "**"
needs_space = node.name != "*" && node.name != "/" && node.name != "**" && node.name != "//"
end

slash_is_not_regex!
skip_space

@multiline_call_indent = nil unless obj.is_a?(Call)
Expand Down Expand Up @@ -2637,6 +2634,9 @@ module Crystal
format_named_argument_name(node.name)
skip_space_or_newline
write_token :":", " "

slash_is_regex!

skip_space_or_newline
accept node.value

Expand Down Expand Up @@ -4327,7 +4327,11 @@ module Crystal
end

def slash_is_regex!
@lexer.slash_is_regex = true
@lexer.slash_is_regex!
end

def slash_is_not_regex!
@lexer.slash_is_not_regex!
end

def skip_space_write_line
Expand Down

0 comments on commit 252a9a7

Please sign in to comment.