Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6d867d993906
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8bc771bdc55a
Choose a head ref
  • 2 commits
  • 5 files changed
  • 1 contributor

Commits on Sep 10, 2016

  1. Compiler: fixed parsing of regex with backlash. Fixes #3286

    Ary Borenszweig committed Sep 10, 2016
    Copy the full SHA
    19fdf45 View commit details
  2. Regex: fix to_s and inspect when regex has backslash. Fixes #3286

    Ary Borenszweig committed Sep 10, 2016
    Copy the full SHA
    8bc771b View commit details
Showing with 28 additions and 4 deletions.
  1. +2 −0 spec/compiler/parser/parser_spec.cr
  2. +1 −1 spec/compiler/parser/to_s_spec.cr
  3. +8 −0 spec/std/regex_spec.cr
  4. +5 −1 src/compiler/crystal/syntax/lexer.cr
  5. +12 −2 src/regex.cr
2 changes: 2 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
@@ -824,6 +824,8 @@ describe "Parser" do
it_parses "{/ /, / /}", TupleLiteral.new([regex(" "), regex(" ")] of ASTNode)
it_parses "begin; / /; end", Expressions.new([regex(" ")] of ASTNode)
it_parses "begin\n/ /\nend", Expressions.new([regex(" ")] of ASTNode)
it_parses "/\\//", regex("/")
it_parses "%r(/)", regex("/")

it_parses "1 =~ 2", Call.new(1.int32, "=~", 2.int32)
it_parses "1.=~(2)", Call.new(1.int32, "=~", 2.int32)
2 changes: 1 addition & 1 deletion spec/compiler/parser/to_s_spec.cr
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ describe "ASTNode#to_s" do
expect_to_s %(/\\s/)
expect_to_s %(/\\?/)
expect_to_s %(/\\(group\\)/)
expect_to_s %(/\\//), "/\\\\//"
expect_to_s %(/\\//), "/\\//"
expect_to_s %(/\#{1 / 2}/)
expect_to_s %<%r(/)>, %(/\\//)
expect_to_s %(foo &.bar), %(foo(&.bar))
8 changes: 8 additions & 0 deletions spec/std/regex_spec.cr
Original file line number Diff line number Diff line change
@@ -31,6 +31,14 @@ describe "Regex" do
md["foo"].should eq("r")
end

it "does inspect with slash" do
%r(/).inspect.should eq("/\\//")
end

it "does to_s with slash" do
%r(/).to_s.should eq("(?-imsx:\\/)")
end

it "doesn't crash when PCRE tries to free some memory (#771)" do
expect_raises(ArgumentError) { Regex.new("foo)") }
end
6 changes: 5 additions & 1 deletion src/compiler/crystal/syntax/lexer.cr
Original file line number Diff line number Diff line change
@@ -1722,7 +1722,11 @@ module Crystal
char = next_char
next_char
@token.type = :STRING
@token.value = "\\#{char}"
if string_end == '/' && char == '/'
@token.value = "/"
else
@token.value = "\\#{char}"
end
else
case char = next_char
when 'b'
14 changes: 12 additions & 2 deletions src/regex.cr
Original file line number Diff line number Diff line change
@@ -392,7 +392,7 @@ class Regex
# ```
def inspect(io : IO)
io << "/"
io << source
append_source(io)
io << "/"
io << "i" if options.includes?(Options::IGNORE_CASE)
io << "m" if options.includes?(Options::MULTILINE)
@@ -499,10 +499,20 @@ class Regex
io << "x" unless options.includes?(Options::EXTENDED)

io << ":"
io << source
append_source(io)
io << ")"
end

private def append_source(io)
source.each_char do |char|
if char == '/'
io << "\\/"
else
io << char
end
end
end

def dup
self
end