Posts Tagged ‘Ashlar/Cornerstone’
Open Source Journaling: Cornerstone February 11, 2009 | 08:48 am

I did another brief update to Cornerstone last night. When parsing floating point numbers, I was doing a parse of an integer, then the dot, then a series of digits, and gluing it all together afterwards. Fred Medlin at the Java Hack Night pointed out that was silly, and I should should parse the value directly as a regex. I went one step further, and jacked the BigDecimal String constructor’s BNF, but encoded as a regex.

So the number parsing now looks like this:

  def float_number : Parser[BigDecimal] = (rawFloat <~ ("F"|"f"))
 
  def integer_number : Parser[BigInteger] = (rawInteger <~ ("Z"|"z"))
 
  def rational_number : Parser[CSRational] = (
    (rawFloat ^^ { new CSRational(_) }) |
    fraction |
    (rawInteger ^^ { new CSRational(_) })
  )
 
  def fraction : Parser[CSRational] = (
    ((rawInteger <~ "/") ~ rawNonzeroNatural) ^^ {
      case x ~ y => new CSRational(x,y)
    }
  )
 
  def rawInteger: Parser[BigInteger] = (
    ((opt("+") ~> """[01-9]+""".r) |
      """[-]?[01-9]+""".r) ^^ { new BigInteger(_) }
  )
 
  def rawNonzeroNatural : Parser[BigInteger] = (
    (opt("+") ~> """[1-9][01-9]*""".r) ^^ { new BigInteger(_) }
  )
 
  def rawFloat : Parser[BigDecimal] = (
    """[-+]?\d*\.\d+([eE][+-]?\d+)?""".r ^^ { new BigDecimal(_) }
  )

As you can see, Cornerstone has only 3 kinds of numbers: integers, floats, and rationals. Rationals are the default, with integers and floats being signaled by suffixes on the numbers (“Z”/”z” and “F”/”f”, respectively). I’m still trying to decide, but I may go with 5 numeric types at the end of the day: long integers (“z”), BigIntegers (“Z”), double-precision floats (“f”), BigDecimals (“F”), and arbitrary-precision rationals (un-suffixed).