class MathExpression
Public Class Methods
new()
click to toggle source
# File lib/Expression/parser.rb, line 9 def initialize() @input = nil @look = nil end
Public Instance Methods
eval(input)
click to toggle source
# File lib/Expression/parser.rb, line 14 def eval(input) @input = input init temp = calculate unless @look.nil? raise InvalidInput, "unexpected input: \"#{@look}\"" end temp end
Private Instance Methods
addop?(x)
click to toggle source
# File lib/Expression/identifiers.rb, line 4 def addop?(x) ['+', '-'].include? x end
alpha?(x)
click to toggle source
# File lib/Expression/identifiers.rb, line 12 def alpha?(x) [*('a'..'z')].include? x end
calculate()
click to toggle source
# File lib/Expression/parser.rb, line 49 def calculate if addop? @look value = 0 else value = term end while addop?(@look) case @look when '+' match('+') value += term when '-' match('-') value -= term end end value end
digit?(x)
click to toggle source
# File lib/Expression/identifiers.rb, line 8 def digit?(x) [*(0..9)].map(&:to_s).include?(x) end
expected(msg)
click to toggle source
# File lib/Expression/parser.rb, line 27 def expected(msg) raise InvalidInput, "\a\"#{msg}\" expected" end
factor()
click to toggle source
# File lib/Expression/parser.rb, line 31 def factor if @look == '(' match('(') value = calculate match(')') elsif @look == '[' match('[') value = calculate match(']') elsif alpha? @look value = trig else value = get_number end value end
get_char()
click to toggle source
# File lib/Expression/getters.rb, line 4 def get_char @look = @input.shift end
get_number()
click to toggle source
# File lib/Expression/getters.rb, line 8 def get_number value = 0 nb_decimals = false expected('integer') if (!digit?(@look) && @look != '.') while (digit?(@look) || @look == '.') if @look == '.' match '.' if nb_decimals expected "integer" end nb_decimals = 1 else if nb_decimals nb_decimals *= 10 value = value + @look.to_f / nb_decimals get_char skip_white else value = 10 * value + @look.to_i get_char skip_white end end end value end
ident()
click to toggle source
# File lib/Expression/parser.rb, line 68 def ident value = factor while %w{! % ^}.include? @look case @look when '^' match('^') value **= factor when '%' match '%' value = value % factor when '!' match('!') str = value.to_s.split(".") if str[1] == "0" || str.size == 1 temp = (1..value).reduce(1, :*) value = temp else raise InvalidInput, "Factorial is not defined for floats" end end end value end
init()
click to toggle source
# File lib/Expression/parser.rb, line 113 def init @input = @input.downcase.split('') get_char skip_white end
match(char)
click to toggle source
# File lib/Expression/identifiers.rb, line 16 def match(char) if @look == char get_char skip_white else expected(char) end end
match_all(string)
click to toggle source
# File lib/Expression/identifiers.rb, line 25 def match_all(string) string.each_char { |x| match(x) } end
skip_white()
click to toggle source
# File lib/Expression/identifiers.rb, line 29 def skip_white while @look =~ /\s/ get_char end end
term()
click to toggle source
# File lib/Expression/parser.rb, line 92 def term value = ident while ['*', '/'].include? @look case @look when '*' match('*') value *= ident when '/' match('/') numerator = value denomenator = ident if denomenator == 0 raise IndeterminedForm, "Division by zero is undefined" else value = numerator.to_f / denomenator end end end value end
trig()
click to toggle source
# File lib/Expression/identifiers.rb, line 34 def trig case @look when 'c' match_all('cos') case @look when 'h' match_all('h(') value = cosh(calculate) when '(' match('(') value = cos(calculate) else expected('cos() or cosh()') end when 's' match('s') if @look == 'q' match_all('qrt(') value = sqrt(calculate) else match_all('in') case @look when 'h' match_all('h(') value = sinh(calculate) when '(' match('(') value = sin(calculate) else expected('sin() or sinh()') end end when 'r' match_all('root') base = get_number match('(') value = calculate ** (1.0/base) when 't' match_all('tan') case @look when 'h' match_all('h(') value = tanh(calculate) when '(' match('(') value = tan(calculate) else expected('tan() or tanh()') end when 'l' match('l') case @look when 'n' match_all('n(') value = log(calculate) when 'o' match_all('og') if digit? @look base = get_number elsif @look == "(" base = 10 else expected("integer or ( ") end match('(') value = log(calculate, base) else expected('ln() or log()') end when 'e' match_all('exp(') value = exp(calculate) when 'a' match_all('arc') case @look when 'c' match_all('cos') case @look when 'h' match_all('h(') value = acosh(calculate) when '(' match('(') value = acos(calculate) else expected('arccos() or arccosh()') end when 's' match_all('sin') case @look when 'h' match_all('h(') value = asinh(calculate) when '(' match('(') value = asin(calculate) else expected('arcsin() or arcsinh()') end when 't' match_all('tan') case @look when 'h' match_all('h(') value = atanh(calculate) when '(' match('(') value = atan(calculate) else expected('arctan() or arctanh()') end end else raise InvalidInput, "unexpected input: \"#{@look}\"" end match(')') value end