privmsg (MathPlugin)

    # File rbot/plugins/math.rb, line 28
      def privmsg(m)
        unless(m.params)
          m.reply "incorrect usage: " + help(m.plugin)
          return
        end

        expr = m.params.dup
        @@digits.each {|k,v|
          expr.gsub!(/\b#{k}\b/, v)
        }

        while expr =~ /(exp ([\w\d]+))/
          exp = $1
          val = Math.exp($2).to_s
          expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
        end

        while expr =~ /^\s*(dec2hex\s*(\d+))\s*\?*/
          exp = $1
          val = sprintf("%x", $2)
          expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
        end

        expr.gsub(/\be\b/, Math.exp(1).to_s)

        while expr =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/
          exp = $1
          res = $2

          if res == 0
            val = "Infinity"
          else
            val = Math.log(res).to_s
          end

          expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
        end

        while expr =~ /(bin2dec ([01]+))/
          exp = $1
          val = join('', unpack('B*', pack('N', $2)))
          val.gsub!(/^0+/, "")
          expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
        end

        expr.gsub!(/ to the power of /, " ** ")
        expr.gsub!(/ to the /, " ** ")
        expr.gsub!(/\btimes\b/, "*")
        expr.gsub!(/\bdiv(ided by)? /, "/ ")
        expr.gsub!(/\bover /, "/ ")
        expr.gsub!(/\bsquared/, "**2 ")
        expr.gsub!(/\bcubed/, "**3 ")
        expr.gsub!(/\bto\s+(\d+)(r?st|nd|rd|th)?( power)?/, "**#$1 ")
        expr.gsub!(/\bpercent of/, "*0.01*")
        expr.gsub!(/\bpercent/, "*0.01")
        expr.gsub!(/\% of\b/, "*0.01*")
        expr.gsub!(/\%/, "*0.01")
        expr.gsub!(/\bsquare root of (\d+)/, "#$1 ** 0.5 ")
        expr.gsub!(/\bcubed? root of (\d+)/, "#$1 **(1.0/3.0) ")
        expr.gsub!(/ of /, " * ")
        expr.gsub!(/(bit(-| )?)?xor(\'?e?d( with))?/, "^")
        expr.gsub!(/(bit(-| )?)?or(\'?e?d( with))?/, "|")
        expr.gsub!(/bit(-| )?and(\'?e?d( with))?/, "& ")
        expr.gsub!(/(plus|and)/, "+")

        if (expr =~ /^\s*[-\d*+\s()\/^\.\|\&\*\!]+\s*$/ &&
           expr !~ /^\s*\(?\d+\.?\d*\)?\s*$/ &&
           expr !~ /^\s*$/ &&
           expr !~ /^\s*[( )]+\s*$/)

           begin
             debug "evaluating expression \"#{expr}\""
             answer = eval(expr)
             if answer =~ /^[-+\de\.]+$/
               answer = sprintf("%1.12f", answer)
               answer.gsub!(/\.?0+$/, "")
               answer.gsub!(/(\.\d+)000\d+/, $1)
               if (answer.length > 30)
                 answer = "a number with >30 digits..."
               end
             end
             m.reply answer
           rescue Exception => e
             puts "couldn't evaluate expression \"#{m.params}\": #{e}"
             m.reply "illegal expression \"#{m.params}\""
             return
           end
        else
          m.reply "illegal expression \"#{m.params}\""
          return
        end
      end