Top Level Namespace

Defined Under Namespace

Classes: Lisp, MathNotation, Repl

Instance Method Summary collapse

Instance Method Details

#parse(string) ⇒ Object



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/calculo/parse.rb', line 1

def parse(string)
        # First regex puts a space after a parenthesis/math operation,
        # Second regex a space between a digit and a parenthesis/math
        # operation(s)
        # Third regex converts any double spaces into single space
        # Fourth regex converts to the exponent operator used in ruby
        # split seperates the characters based on a space

        op_re = Regexp.new(/([^\d\w\s\.\-])/)
        dig_op_re = Regexp.new(/\d[^\d\w\s\.]+/)
        dbl_space_re = Regexp.new(/\s{2,}/)
        exp_re = Regexp.new(/\^/)
        dig_re = Regexp.new(/\d+/)
        array = string.gsub(op_re,'\1 ').gsub(dig_op_re){ |s| s.chars.join(' ')}.gsub(dbl_space_re,' ').gsub(exp_re,'**').split(' ')

        # Regex finds if array element matches a digit, and converts it
        # to a float.
        array = array.map{|x| dig_re.match(x) != nil ? x.to_f : x}
        return array
end

#shunting_yard(infix_array) ⇒ Object



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/calculo/shunting_yard.rb', line 1

def shunting_yard(infix_array)
        operators = {'+' => 2, '-' => 2, '*' => 3, '/' => 3, '>' => 4, '<' => 4, '=' => 4, '%' => 4, '**' => 4}
        rpn_expr = []
        op_stack = []

        infix_array.each do |item|
                if operators.has_key?(item)
                        op2 = op_stack.last
                        if operators.has_key?(op2) and ((op2 == "**" and operators[item] < operators[op2]) or (op2 != "**" and operators[item] <= operators[op2]))
                                rpn_expr.push(op_stack.pop)
                        end
                        op_stack.push(item)

                elsif item == "("
                        op_stack.push(item)

                elsif item == ")"
                        until op_stack.last == "("
                                rpn_expr.push(op_stack.pop)
                        end
                        op_stack.pop
                else
                        rpn_expr.push(item)
                end
        end

        until op_stack.empty?
                rpn_expr.push(op_stack.pop)
        end

        return rpn_expr
end