Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

! Fixes interaction with mathn

Mathn modifies integer division - this breaks a lot of stuff. Turns out,
parslet is easily modified hold up.
  • Loading branch information...
commit c4b4d25b50bce0cf261fa03d115c05beab272dd3 1 parent 5fd28d9
@kschiess authored
View
44 example/mathn.rb
@@ -0,0 +1,44 @@
+# Demonstrates that we have a compatibility fix to mathn's weird idea of
+# integer mathematics.
+# This was contributed by Jonathan Hinkle (https://github.com/hynkle). Thanks!
+
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'parslet'
+require 'parslet/convenience'
+include Parslet
+
+def attempt_parse
+ possible_whitespace = match['\s'].repeat
+
+ cephalopod =
+ str('octopus') |
+ str('squid')
+
+ parenthesized_cephalopod =
+ str('(') >>
+ possible_whitespace >>
+ cephalopod >>
+ possible_whitespace >>
+ str(')')
+
+ parser =
+ possible_whitespace >>
+ parenthesized_cephalopod >>
+ possible_whitespace
+
+ # This parse fails, but that is not the point. When mathn is in the current
+ # ruby environment, it modifies integer division in a way that makes
+ # parslet loop indefinitely.
+ parser.parse %{(\nsqeed)\n}
+rescue Parslet::ParseFailed
+end
+
+attempt_parse
+puts 'it terminates before we require mathn'
+
+puts "requiring mathn now"
+require 'mathn'
+puts "and trying again (will hang without the fix)"
+attempt_parse # but it doesn't terminate after requiring mathn
+puts "okay!"
View
4 example/output/mathn.out
@@ -0,0 +1,4 @@
+it terminates before we require mathn
+requiring mathn now
+and trying again (will hang without the fix in ...)
+okay!
View
8 lib/parslet/source/line_cache.rb
@@ -60,6 +60,12 @@ def scan_for_line_endings(start_pos, buf)
# # would describe [0, 10], (10, 20], (20, 30]
#
module RangeSearch # :nodoc:
+ def find_mid(left, right)
+ # NOTE: Jonathan Hinkle reported that when mathn is required, just
+ # dividing and relying on the integer truncation is not enough.
+ left + ((right - left) / 2).floor
+ end
+
# Scans the array for the first number that is > than bound. Returns the
# index of that number.
#
@@ -71,7 +77,7 @@ def lbound(bound)
right = size - 1
loop do
- mid = left + (right - left) / 2
+ mid = find_mid(left, right)
if self[mid] > bound
right = mid
Please sign in to comment.
Something went wrong with that request. Please try again.