class NumRu::Units

Constants

RE_DATE
RE_DAY
RE_EXP
RE_HOUR
RE_HandM
RE_INTEGER
RE_MINUTE
RE_MONTH
RE_NAME
RE_REAL
RE_SECOND
RE_SPACE
RE_TIME
RE_YEAR
Racc_arg
Racc_debug_parser
Racc_token_to_s_table

Attributes

string[R]

Public Class Methods

[](string) click to toggle source
# File lib/numru/units.rb, line 2971
def self::[](string)
    new(string)
end
new(string) click to toggle source
# File lib/numru/units.rb, line 2696
def initialize string
    case string
    when String
        @string, @ptree = string, nil
    when Node
        @string, @ptree = nil, string
    else
        @string, @ptree = String(string), nil
    end
    @copy = @lexstat = nil
end
parse(string) click to toggle source
# File lib/numru/units.rb, line 2889
def self::parse(string)
    new(string).parse!
end
pow_f(a, b) click to toggle source
# File lib/numru/units.rb, line 3123
def self::pow_f(a, b)
    if Integer === b and b < 0 then
        a ** b.to_f
    else
        a ** b
    end
end
reduce_level() click to toggle source
# File lib/numru/units.rb, line 3041
def self::reduce_level
    @@reduce.to_s[-1]
end
reduce_level=(n) click to toggle source
# File lib/numru/units.rb, line 3045
def self::reduce_level=(n)
    @@reduce = case n
    when 1 then :reduce1
    when 2 then :reduce2
    when 3 then :reduce3
    when 4 then :reduce4
    else :reduce5
    end
end

Public Instance Methods

*(other) click to toggle source
# File lib/numru/units.rb, line 3066
def *(other)
    binop(:mul, other)
end
**(other) click to toggle source
# File lib/numru/units.rb, line 3070
def **(other)
    binop(:pow, other)
end
/(other) click to toggle source
# File lib/numru/units.rb, line 3074
def /(other)
    binop(:divide, other)
end
==(other) click to toggle source
# File lib/numru/units.rb, line 3082
def ==(other)
    case other
    when self.class
        dup.reduce5.to_s == other.dup.reduce5.to_s
    else
        false
    end
end
Also aliased as: ===
===(other)

def === (other)

reduce5.ptree.deref.to_s == other.reduce5.ptree.deref.to_s

end

Alias for: ==
=~(other) click to toggle source

def === (other)

# returns true if other is within a factor and/or offset of difference.
case other
when self.class
  (self/other).reduce5.ptree.children.each do |child|
    return false if !( NumberNode === child )
  end
  true
else
  false
end

end

# File lib/numru/units.rb, line 3111
def =~(other)
  case other
  when self.class
    (self/other).reduce5.ptree.children.each{ |node|
      return false unless NumberNode === node
    }
    true
  else
    false
  end
end
^(other) click to toggle source
# File lib/numru/units.rb, line 3078
def ^(other)
    binop(:shift, other)
end
_reduce_10( val, _values) click to toggle source
# File lib/numru/units.rb, line 3311
 def _reduce_10( val, _values)
val[0].mul(val[2])
 end
_reduce_11( val, _values) click to toggle source
# File lib/numru/units.rb, line 3315
 def _reduce_11( val, _values)
val[0].divide(val[2])
 end
_reduce_12( val, _values) click to toggle source
# File lib/numru/units.rb, line 3319
 def _reduce_12( val, _values)
val[0].mul(val[2])
 end
_reduce_13( val, _values) click to toggle source
# File lib/numru/units.rb, line 3323
 def _reduce_13( val, _values)
val[0].divide(val[2])
 end
_reduce_14( val, _values) click to toggle source
# File lib/numru/units.rb, line 3327
 def _reduce_14( val, _values)
NameNode.new(val[0])
 end
_reduce_15( val, _values) click to toggle source
# File lib/numru/units.rb, line 3331
 def _reduce_15( val, _values)
val[0].pow(val[1])
 end
_reduce_16( val, _values) click to toggle source
# File lib/numru/units.rb, line 3335
 def _reduce_16( val, _values)
val[0].pow(val[2])
 end
_reduce_17( val, _values) click to toggle source
# File lib/numru/units.rb, line 3339
 def _reduce_17( val, _values)
val[1]
 end
_reduce_19( val, _values) click to toggle source

reduce 18 omitted

# File lib/numru/units.rb, line 3345
 def _reduce_19( val, _values)
val[1]
 end
_reduce_2( val, _values) click to toggle source

reduce 1 omitted

# File lib/numru/units.rb, line 3285
 def _reduce_2( val, _values)
yyaccept;
 end
_reduce_20( val, _values) click to toggle source
# File lib/numru/units.rb, line 3349
 def _reduce_20( val, _values)
NumberNode.new(val[0])
 end
_reduce_21( val, _values) click to toggle source
# File lib/numru/units.rb, line 3353
 def _reduce_21( val, _values)
NumberNode.new(val[0])
 end
_reduce_23( val, _values) click to toggle source

reduce 22 omitted

# File lib/numru/units.rb, line 3359
 def _reduce_23( val, _values)
val[1]
 end
_reduce_24( val, _values) click to toggle source
# File lib/numru/units.rb, line 3363
 def _reduce_24( val, _values)
TimeNode.new(val[0], 0.0, 0)
 end
_reduce_25( val, _values) click to toggle source
# File lib/numru/units.rb, line 3367
 def _reduce_25( val, _values)
TimeNode.new(val[0], val[1], 0)
 end
_reduce_26( val, _values) click to toggle source
# File lib/numru/units.rb, line 3371
 def _reduce_26( val, _values)
TimeNode.new(val[0], val[1], val[2])
 end
_reduce_3( val, _values) click to toggle source
# File lib/numru/units.rb, line 3289
 def _reduce_3( val, _values)
yyerrok
 end
_reduce_5( val, _values) click to toggle source

reduce 4 omitted

# File lib/numru/units.rb, line 3295
 def _reduce_5( val, _values)
val[0].shift(val[2])
 end
_reduce_6( val, _values) click to toggle source
# File lib/numru/units.rb, line 3299
 def _reduce_6( val, _values)
val[0].shift(val[2])
 end
_reduce_9( val, _values) click to toggle source

reduce 8 omitted

# File lib/numru/units.rb, line 3307
 def _reduce_9( val, _values)
val[0].mul(val[1])
 end
_reduce_none( val, _values) click to toggle source
# File lib/numru/units.rb, line 3375
def _reduce_none( val, _values)
 val[0]
end
binop(op, other) click to toggle source
# File lib/numru/units.rb, line 3055
def binop(op, other)
    case other
    when Numeric
        other = NumberNode.new(other)
    when Units
        other = other.ptree
    end
    q = self.ptree.send(op, other).send(@@reduce)
    Units.new(q)
end
convert(numeric, to_units) click to toggle source
# File lib/numru/units.rb, line 2990
def convert(numeric, to_units)
    to_units = Units.new( to_units ) if to_units.is_a?(String)
    r5 = dup.ptree.reduce5
    case r = r5.ref
    when TimeNode
        r.add_time(r5.deref.mul(numeric)).div_time(to_units.ptree)
    else
        shift1 = r.value
        numeric = shift1 + numeric if shift1 != 0
        fact = r5.divide(tp = to_units.dup.ptree).reduce5.value
        numeric *= fact if fact != 1
        shift2 = tp.reduce5.ref.value
        numeric = numeric - shift2 if shift2 != 0
        numeric
    end
end
convert2(val, to_units) click to toggle source
# File lib/numru/units.rb, line 3016
def convert2(val, to_units)
    # Like Units#convert, but applicable to any Numeric-like objects.
    # Returns the original value if the units are incompatible.
    to_units = Units.new( to_units ) if to_units.is_a?(String)
    if ( self == to_units )
        val
    elsif ( self =~ to_units )
        if Numeric===val
            convert( val, to_units )
        else
            factor, offset = factor_and_offset( to_units )
            val*factor + offset
        end
    else
      unless $VERBOSE.nil?
        $stderr.print( "*WARNING*: " +
                 "incompatible units: #{self.to_s} and #{to_units.to_s}\n")
        caller(0).each{|c| $stderr.print "\t* ",c,"\n"}
      end        
      val
    end
end
do_parse2() click to toggle source
# File lib/numru/units.rb, line 2864
def do_parse2
    rewind
    return NumberNode.new(1) if @string.nil? or @string.empty?
    pa = do_parse
    pa ? pa : ErrorNode.new(@string)
end
dup() click to toggle source
# File lib/numru/units.rb, line 2876
def dup
    @string ? self.class.new(@string) : self.class.new(@ptree)
end
eval(x = 0) click to toggle source
# File lib/numru/units.rb, line 2979
def eval(x = 0)
    r5 = ptree.reduce5
    case r = r5.ref
    when TimeNode
        r.add(x, r5.name)
    else
        fac = NumberNode.new(x + r.value)
        self.class.new(MulNode.new(fac, r5.deref))
    end
end
factor_and_offset(to_units) click to toggle source
# File lib/numru/units.rb, line 3007
def factor_and_offset(to_units)
    # To convert a numeric from self to to_units: 
    # scale_factor * numeric + add_offset
    to_units = Units.new( to_units ) if to_units.is_a?(String)
    add_offset = convert(0, to_units)
    scale_factor = convert(1, to_units) - add_offset
    [ scale_factor, add_offset ]
end
inspect() click to toggle source
# File lib/numru/units.rb, line 2963
def inspect
    if @ptree.nil? then
        "Units{#{@string}}"
    else
        "Units[#{@ptree.inspect}]".gsub(/Units::/, '').gsub(/Node\[/, '[')
    end
end
next_token() click to toggle source
# File lib/numru/units.rb, line 2733
def next_token

    # decomment
    @copy.sub!(/^#.*/, '');

    if @copy.sub!(%r{^\s*(\))}, '') then
        @lexstat = nil
        return [$1, $1]
    end

    if @copy.sub!(%r{^\s*(\()\s*}, '') then
        return [$1, $1]
    end

    if @copy.sub!(%r{^[ \t]*(@)[ \t]*}, '')      or @copy.sub!(%r{^[ \t]+(after|from|since|ref)[ \t]+}i, '') then
        @lexstat = :SHIFT_SEEN
        return [:SHIFT, $1]
    end

    if @copy.sub!(%r{^[ \t]*(/)[ \t]*}, '')      or @copy.sub!(%r{^[ \t]+(per)[ \t]+}i, '') then
        @lexstat = nil
        return [:DIVIDE, $1]
    end

    if @copy.sub!(%r{^(\^|\*\*)}, '') then
        @lexstat = nil
        return [:EXPONENT, $1]
    end

    if @copy.sub!(%r{^(\.|\*|[ \t]+)}, '') then
        @lexstat = nil
        return [:MULTIPLY, $1]
    end

    if :SHIFT_SEEN === @lexstat      and @copy.sub!(%r{^#{RE_DATE}T?[ \t]*}, '') then
        y, m, d = $1, $2, $3
        @lexstat = :DATE_SEEN
        return [:DATE, XDate.new(y.to_i, m.to_i, d.to_i)]
    end

    if :SHIFT_SEEN === @lexstat      and @copy.sub!(%r{^now[ \t]*}, '') then
        @lexstat = nil
        return [:DATE, :now]
    end

    if :DATE_SEEN === @lexstat      and @copy.sub!(%r{^#{RE_TIME}[ \t]*}, '') then
        h, m, s = $1, $3, $5
        m = m.sub(/:/,'') if m
        s = 0 if s.nil?
        @lexstat = :TIME_SEEN
        return [:TIME, ((h.to_i * 60 + m.to_i) * 60 + Float(s))]
    end

    if :DATE_SEEN === @lexstat      and @copy.sub!(%r{^([0-2][0-9])([0-5][0-9])[ \t]*}, '') then
        h, m = $1, $2
        @lexstat = :TIME_SEEN
        return [:TIME, ((h.to_i * 60 + m.to_i) * 60.0)]
    end

    if :DATE_SEEN === @lexstat      and @copy.sub!(%r{^([0-9])([0-5][0-9])[ \t]*}, '') then
        h, m = $1, $2
        @lexstat = :TIME_SEEN
        return [:TIME, ((h.to_i * 60 + m.to_i) * 60.0)]
    end

    if :TIME_SEEN === @lexstat      and @copy.sub!(%r{^UTC[ \t]*}, '') then
        @lexstat = nil
        return [:ZONE, 0]
    end

    if :TIME_SEEN === @lexstat      and @copy.sub!(%r{^([-+]?)#{RE_HandM}[ \t]*}, '') then
        sgn, h, m = $1, $2, $4
        m = m.sub(/:/,'') if m
        @lexstat = nil
        h = h.to_i
        h = -h if sgn == "-"
        m = m.to_i
        m = -m if sgn == "-"
        return [:ZONE, ((h * 60) + m)]
    end

    if @copy.sub!(%r{^#{RE_NAME}}, '') then
        @lexstat = nil
        return [:NAME, $1]
    end

    if @copy.sub!(%r{^#{RE_REAL}}, '') then
        @lexstat = nil
        return [:REAL, $1.to_f]
    end

    if @copy.sub!(%r{^#{RE_INTEGER}}, '') then
        @lexstat = nil
        return [:INT, $1.to_i]
    end

    if @copy.sub!(%r{^(-)}, '') then
        @lexstat = nil
        return [:MULTIPLY, $1]
    end

    if @copy.sub!(%r{^(.)}, '') then
        return [$1, $1]
    end

    return [false, false]

end
parse() click to toggle source
# File lib/numru/units.rb, line 2880
def parse
    dup.parse!
end
parse!() click to toggle source
# File lib/numru/units.rb, line 2884
def parse!
    @ptree = do_parse2 if not @ptree
    self
end
ptree() click to toggle source
# File lib/numru/units.rb, line 2871
def ptree
    @ptree = do_parse2 if not @ptree
    @ptree
end
reduce0() click to toggle source
# File lib/numru/units.rb, line 2898
def reduce0
    self
end
reduce1() click to toggle source
# File lib/numru/units.rb, line 2907
def reduce1
    @string = ptree.to_s
    self
end
reduce2() click to toggle source
# File lib/numru/units.rb, line 2917
def reduce2
    @ptree = ptree.reduce2
    @string = nil
    self
end
reduce3() click to toggle source
# File lib/numru/units.rb, line 2928
def reduce3
    @ptree = ptree.reduce3
    @string = nil
    self
end
reduce4() click to toggle source
# File lib/numru/units.rb, line 2939
def reduce4
    @ptree = ptree.reduce4
    @string = nil
    self
end
reduce5() click to toggle source
# File lib/numru/units.rb, line 2950
def reduce5
    @ptree = ptree.reduce5
    @string = nil
    self
end
rewind() click to toggle source

LEXICAL ANALYZER ===

# File lib/numru/units.rb, line 2712
def rewind
    @copy = @string.dup.strip
    @lexstat = nil
end
to_s() click to toggle source
# File lib/numru/units.rb, line 2958
def to_s
    @string = @ptree.to_s if @string.nil?
    @string
end
tokens() click to toggle source

USER LEVEL METHODS ===

# File lib/numru/units.rb, line 2855
def tokens
    rewind
    x = []
    while (t = next_token).first
        x.push t
    end
    x
end