Created
August 9, 2016 13:11
-
-
Save maekawatoshiki/e270b51c81115318ab216da2c33f0b80 to your computer and use it in GitHub Desktop.
calculator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "std" | |
module Calc | |
def prim(input:string):string | |
str = "" | |
if input[$pos].alpha? # function (sqrt..) | |
fname = "" | |
while input[$pos].alpha? | |
fname += input[$pos] | |
$pos += 1 | |
end | |
$pos += 1 # ( | |
str = addsub(input) | |
$pos += 1 # ) | |
str + fname + " " | |
elsif input[$pos] == '(' | |
$pos += 1 | |
str = addsub(input) | |
$pos += 1 | |
str | |
else | |
while input[$pos].digit? | input[$pos] == '.' | |
str += input[$pos] | |
$pos += 1 | |
end | |
str + " " | |
end | |
end | |
def muldiv(input:string):string | |
str = prim input | |
while input[$pos] == '*' | input[$pos] == '/' | input[$pos] == '^' | |
op = input[$pos] | |
$pos += 1 | |
str += prim(input) + op + " " | |
end | |
str | |
end | |
def addsub(input:string):string | |
str = muldiv input | |
while input[$pos] == '+' | input[$pos] == '-' | |
op = input[$pos] | |
$pos += 1 | |
str += muldiv(input) + op + " " | |
end | |
str | |
end | |
def run(expr:string):double | |
tok_str = addsub expr | |
puts "reverse polish: ", tok_str | |
tok_ary = tok_str.split(' ') | |
# VM ( calculate ) | |
cur_stack_sz = 256 | |
stack = new cur_stack_sz double | |
sp = 0 | |
for i in 0...length tok_ary | |
s = tok_ary[i] | |
if s == "+" | |
stack[sp-2] = stack[sp-2] + stack[sp-1] | |
sp -= 1 | |
elsif s == "-" | |
stack[sp-2] = stack[sp-2] - stack[sp-1] | |
sp -= 1 | |
elsif s == "*" | |
stack[sp-2] = stack[sp-2] * stack[sp-1] | |
sp -= 1 | |
elsif s == "/" | |
stack[sp-2] = stack[sp-2] / stack[sp-1] | |
sp -= 1 | |
elsif s == "^" | |
stack[sp-2] = Math::pow stack[sp-2], stack[sp-1] | |
sp -= 1 | |
elsif s == "sqrt" | |
stack[sp-1] = Math::sqrt stack[sp-1] | |
else | |
stack[sp] = s.to_float | |
sp += 1 | |
end | |
end | |
stack[0] | |
end | |
end | |
$pos = 0 | |
print "expression: " | |
puts Calc::run gets |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment