calculo 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +5 -0
- data/Rakefile +17 -0
- data/bin/calculo +49 -0
- data/lib/calculo/lisp.rb +58 -0
- data/lib/calculo/math.rb +56 -0
- data/lib/calculo/parse.rb +20 -0
- data/lib/calculo/repl.rb +110 -0
- data/lib/calculo/shunting_yard.rb +32 -0
- data/lib/calculo.rb +3 -0
- data/test/test.rb +129 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 647451e4c1e42739a7571ef0deb0db5bd4af3555
|
4
|
+
data.tar.gz: e27e02406f3fa7446749996881a986f81694dc49
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ca50356dc05252792acf85230babbbd64fb34e11bd1d6e486133722d46f9a0c8d6c50554155164e2081464ceff7e0db62ed9984b4217b0d871245d10b067a76a
|
7
|
+
data.tar.gz: 4e45b33979518f68c2a67769999299e8741a67cfa1ba9294ee96761b2c75b6eb8c25b8563f018e2c1aa1c0370745385822564080691d0831445d9664e6809cde
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rake/dmg'
|
3
|
+
|
4
|
+
Rake::DmgTask.new 'calculo', '1.0.0' do |dmg|
|
5
|
+
dmg.source_files.include('bin/*')
|
6
|
+
dmg.source_files.include('calculo/*')
|
7
|
+
dmg.source_files.include('test/*')
|
8
|
+
dmg.source_files.include('README.md')
|
9
|
+
dmg.strip = 'build'
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::TestTask.new do |t|
|
13
|
+
t.libs << 'test'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Run tests"
|
17
|
+
task :default => :test
|
data/bin/calculo
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'calculo'
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = "Usage: calculo.rb [options]"
|
8
|
+
opts.on("-t","--type TYPE",String,"The type of expression to be computed") do |type|
|
9
|
+
options[:type] = type
|
10
|
+
end
|
11
|
+
|
12
|
+
opts.on("-e","--expr EXPR","The expression to be computed") do |expr|
|
13
|
+
options[:expr] = expr
|
14
|
+
end
|
15
|
+
opts.on("-f","--file FILE",String,"Reads expressions from a file") do |file|
|
16
|
+
options[:file] = file
|
17
|
+
end
|
18
|
+
opts.on("-h","--help","Prints this help") do
|
19
|
+
puts opts
|
20
|
+
end
|
21
|
+
end.parse!
|
22
|
+
|
23
|
+
def cli_eval(string,type)
|
24
|
+
if type == 'lisp' or type == 'reverse-lisp' or type == 'reverse'
|
25
|
+
cli = Lisp.new(string,type)
|
26
|
+
output = "#{cli.string} : #{cli.result}"
|
27
|
+
return output
|
28
|
+
elsif type == 'rpn' or type == 'postfix' or type == 'pn' or type == 'prefix' or type == 'infix'
|
29
|
+
cli = MathNotation.new(string,type)
|
30
|
+
output = "#{cli.string} : #{cli.result}"
|
31
|
+
return output
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if not options.empty?
|
36
|
+
if options.has_key?(:file)
|
37
|
+
File.open(options[:file]).each_line do |line|
|
38
|
+
puts(cli_eval(line,options[:type]))
|
39
|
+
end
|
40
|
+
|
41
|
+
elsif options.has_key?(:expr)
|
42
|
+
puts(cli_eval(options[:expr],options[:type]))
|
43
|
+
|
44
|
+
elsif options.has_key?(:type)
|
45
|
+
Repl.new("=>",options[:type])
|
46
|
+
end
|
47
|
+
else
|
48
|
+
Repl.new("=>","infix")
|
49
|
+
end
|
data/lib/calculo/lisp.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'parse'
|
2
|
+
class Lisp
|
3
|
+
attr_accessor :string
|
4
|
+
attr_accessor :type
|
5
|
+
attr_accessor :array
|
6
|
+
attr_accessor :result
|
7
|
+
|
8
|
+
def initialize(string, type)
|
9
|
+
@string = string
|
10
|
+
@type = type
|
11
|
+
@array = parse(@string)
|
12
|
+
@result = eval_lisp(@array)
|
13
|
+
end
|
14
|
+
|
15
|
+
@private
|
16
|
+
def execute(array,type)
|
17
|
+
case type
|
18
|
+
when 'lisp'
|
19
|
+
array[2..-2].reduce(array[1].to_sym)
|
20
|
+
when 'reverse-lisp' || 'reverse'
|
21
|
+
array[1..-3].reverse.reduce(array[-2].to_sym)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def innermost_pair(array)
|
26
|
+
l_parens = []
|
27
|
+
r_parens = []
|
28
|
+
|
29
|
+
array.each_with_index do |item, index|
|
30
|
+
|
31
|
+
if item == "("
|
32
|
+
l_parens.push(index)
|
33
|
+
|
34
|
+
elsif item == ")"
|
35
|
+
r_parens.push(index)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
total_length = l_parens.length + r_parens.length
|
40
|
+
return [total_length, l_parens[-1], r_parens[0]]
|
41
|
+
end
|
42
|
+
|
43
|
+
def eval_lisp(array)
|
44
|
+
length, l, r = innermost_pair(array)
|
45
|
+
result = execute(array[l..r],type)
|
46
|
+
|
47
|
+
if length > 2
|
48
|
+
# Inserts the result in between the portions
|
49
|
+
# of the array not including the portion just
|
50
|
+
# used to calculate the result
|
51
|
+
new_array = array[0..(l-1)] + [result] + array[(r+1)..-1]
|
52
|
+
eval_lisp(new_array)
|
53
|
+
|
54
|
+
elsif length == 2
|
55
|
+
return result
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/calculo/math.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'parse'
|
2
|
+
require 'shunting_yard'
|
3
|
+
class MathNotation
|
4
|
+
attr_accessor :type
|
5
|
+
attr_accessor :string
|
6
|
+
attr_accessor :array
|
7
|
+
attr_accessor :result
|
8
|
+
|
9
|
+
def initialize(string,type)
|
10
|
+
@string = string
|
11
|
+
if type == 'infix'
|
12
|
+
@type = 'rpn'
|
13
|
+
@array = shunting_yard(parse(@string))
|
14
|
+
@result = eval_rpn(@array)
|
15
|
+
else
|
16
|
+
@array = parse(@string)
|
17
|
+
@type = type
|
18
|
+
if @type == 'prefix' or @type == 'pn'
|
19
|
+
@result = eval_pn(@array)
|
20
|
+
elsif @type == 'postfix' or @type == 'rpn'
|
21
|
+
@result = eval_rpn(@array)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
@private
|
27
|
+
def eval_pn(array)
|
28
|
+
operators = ['+','-','^','%','/','**','*']
|
29
|
+
stack = []
|
30
|
+
array.reverse.each{|item|
|
31
|
+
if operators.include?(item)
|
32
|
+
num2,num1 = stack.pop(2)
|
33
|
+
result = num1.method(item).call(num2)
|
34
|
+
stack.push(result)
|
35
|
+
else
|
36
|
+
stack.push(item)
|
37
|
+
end
|
38
|
+
}
|
39
|
+
return stack.pop
|
40
|
+
end
|
41
|
+
|
42
|
+
def eval_rpn(array)
|
43
|
+
operators = ['+','-','^','%','/','**','*']
|
44
|
+
stack = []
|
45
|
+
array.each{|item|
|
46
|
+
if operators.include?(item)
|
47
|
+
num1,num2 = stack.pop(2)
|
48
|
+
result = num1.method(item).call(num2)
|
49
|
+
stack.push(result)
|
50
|
+
else
|
51
|
+
stack.push(item)
|
52
|
+
end
|
53
|
+
}
|
54
|
+
return stack.pop
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
def parse(string)
|
2
|
+
# First regex puts a space after a parenthesis/math operation,
|
3
|
+
# Second regex a space between a digit and a parenthesis/math
|
4
|
+
# operation(s)
|
5
|
+
# Third regex converts any double spaces into single space
|
6
|
+
# Fourth regex converts to the exponent operator used in ruby
|
7
|
+
# split seperates the characters based on a space
|
8
|
+
|
9
|
+
op_re = Regexp.new(/([^\d\w\s\-])/)
|
10
|
+
dig_op_re = Regexp.new(/\d[^\d\w\s]+/)
|
11
|
+
dbl_space_re = Regexp.new(/\s{2,}/)
|
12
|
+
exp_re = Regexp.new(/\^/)
|
13
|
+
dig_re = Regexp.new(/\d+/)
|
14
|
+
array = string.gsub(op_re,'\1 ').gsub(dig_op_re){ |s| s.chars.join(' ')}.gsub(dbl_space_re,' ').gsub(exp_re,'**').split(' ')
|
15
|
+
|
16
|
+
# Regex finds if array element matches a digit, and converts it
|
17
|
+
# to a float.
|
18
|
+
array = array.map{|x| dig_re.match(x) != nil ? x.to_f : x}
|
19
|
+
return array
|
20
|
+
end
|
data/lib/calculo/repl.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'IO/console'
|
2
|
+
require 'os'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
class Repl
|
6
|
+
attr_accessor :history
|
7
|
+
attr_accessor :prompt
|
8
|
+
attr_accessor :type
|
9
|
+
def initialize(prompt,type)
|
10
|
+
@history = []
|
11
|
+
@og_prompt = prompt
|
12
|
+
@prompt = "[#{@history.length}]" + @og_prompt + " "
|
13
|
+
@type = type
|
14
|
+
clear_screen()
|
15
|
+
calculo_loop()
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear_screen
|
19
|
+
if OS.linux? or OS.mac? or OS.bsd?
|
20
|
+
system('clear')
|
21
|
+
elsif OS.windows?
|
22
|
+
system('cls')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def calculo_print(history)
|
27
|
+
history.each_with_index.map{|x,i| puts("#{i} : #{x}\n")}
|
28
|
+
end
|
29
|
+
|
30
|
+
def repl_eval(input)
|
31
|
+
# syntax for changing prompt/type is:
|
32
|
+
# set prompt/type = 'foo'
|
33
|
+
# or set prompt/type 'foo'
|
34
|
+
if input.start_with?("set","change")
|
35
|
+
@history.push(input)
|
36
|
+
input_array = input.split(' ')
|
37
|
+
|
38
|
+
if input_array[1] == "prompt" and input_array.last != "prompt"
|
39
|
+
@og_prompt = input_array.last
|
40
|
+
@prompt = "[#{@history.length}]" + @og_prompt + " "
|
41
|
+
return "prompt is now #{@prompt}"
|
42
|
+
|
43
|
+
elsif input_array[1] == "type" and input_array.last != "type"
|
44
|
+
@type = input_array.last
|
45
|
+
return "type is now #{@type}"
|
46
|
+
else
|
47
|
+
return "Error: variable can not be changed"
|
48
|
+
end
|
49
|
+
|
50
|
+
# If input is simply history, print all of the history
|
51
|
+
# can also use ruby range syntax, STARTING AT 0
|
52
|
+
# for example: history 0..-2 will print all but the
|
53
|
+
# last entry of history
|
54
|
+
elsif input.start_with?("history")
|
55
|
+
@history.push(input)
|
56
|
+
if input == "history"
|
57
|
+
return calculo_print(@history)
|
58
|
+
else
|
59
|
+
input_array = input.split(' ')
|
60
|
+
input_range = input_array[-1]
|
61
|
+
if input_range.length == 1
|
62
|
+
return @history[input_range.to_i]
|
63
|
+
elsif input_range.length == 4
|
64
|
+
return calculo_print(@history[(input_range.chars.first.to_i)..(input_range.chars.last.to_i)])
|
65
|
+
elsif input_range.length == 5
|
66
|
+
return calculo_print(@history[(input_range.chars.first.to_i)..(input_range.chars.drop(2).to_i)])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
elsif input.start_with?("clear")
|
71
|
+
@history.push(input)
|
72
|
+
if input == "clear"
|
73
|
+
return clear_screen()
|
74
|
+
elsif input == "clear history"
|
75
|
+
@history = []
|
76
|
+
return "History is now blank"
|
77
|
+
end
|
78
|
+
|
79
|
+
elsif input == "exit" or input == "quit"
|
80
|
+
return "Exiting calculo!"
|
81
|
+
|
82
|
+
else
|
83
|
+
if @type == 'lisp' or @type == 'reverse-lisp' or @type == 'reverse'
|
84
|
+
repl_class = Lisp.new(input,@type)
|
85
|
+
calculo_output = "#{repl_class.string} : #{repl_class.result}"
|
86
|
+
@history.push(calculo_output)
|
87
|
+
return calculo_output
|
88
|
+
|
89
|
+
elsif @type == 'postfix' or @type == 'infix' or @type == 'prefix' or @type == 'pn' or @type == 'rpn'
|
90
|
+
repl_class = MathNotation.new(input,@type)
|
91
|
+
calculo_output = "#{repl_class.string} : #{repl_class.result}"
|
92
|
+
@history.push(calculo_output)
|
93
|
+
return calculo_output
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def calculo_loop(output="Welcome to calculo!")
|
99
|
+
input = nil
|
100
|
+
while output != "Exiting calculo!"
|
101
|
+
puts(output)
|
102
|
+
@prompt = "[#{@history.length}]" + @og_prompt + " "
|
103
|
+
print(@prompt)
|
104
|
+
input = gets.chomp
|
105
|
+
output = repl_eval(input)
|
106
|
+
end
|
107
|
+
puts(output)
|
108
|
+
exit(1)
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
def shunting_yard(infix_array)
|
2
|
+
operators = {'+' => 2, '-' => 2, '*' => 3, '/' => 3, '>' => 4, '<' => 4, '=' => 4, '%' => 4, '**' => 4}
|
3
|
+
rpn_expr = []
|
4
|
+
op_stack = []
|
5
|
+
|
6
|
+
infix_array.each do |item|
|
7
|
+
if operators.has_key?(item)
|
8
|
+
op2 = op_stack.last
|
9
|
+
if operators.has_key?(op2) and ((op2 == "**" and operators[item] < operators[op2]) or (op2 != "**" and operators[item] <= operators[op2]))
|
10
|
+
rpn_expr.push(op_stack.pop)
|
11
|
+
end
|
12
|
+
op_stack.push(item)
|
13
|
+
|
14
|
+
elsif item == "("
|
15
|
+
op_stack.push(item)
|
16
|
+
|
17
|
+
elsif item == ")"
|
18
|
+
until op_stack.last == "("
|
19
|
+
rpn_expr.push(op_stack.pop)
|
20
|
+
end
|
21
|
+
op_stack.pop
|
22
|
+
else
|
23
|
+
rpn_expr.push(item)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
until op_stack.empty?
|
28
|
+
rpn_expr.push(op_stack.pop)
|
29
|
+
end
|
30
|
+
|
31
|
+
return rpn_expr
|
32
|
+
end
|
data/lib/calculo.rb
ADDED
data/test/test.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
require_relative "../lib/calculo/lisp"
|
2
|
+
require_relative "../lib/calculo/math"
|
3
|
+
require "minitest/autorun"
|
4
|
+
|
5
|
+
class TestLisp < MiniTest::Test
|
6
|
+
def setup
|
7
|
+
@type = "lisp"
|
8
|
+
@string = "( - ( + ( / 18 ( ^ 3 2 ) ) 12 ) 13 )"
|
9
|
+
@array = ["(", "-", "(", "+", "(", "/", 18.0, "(", "**", 3.0, 2.0, ")", ")", 12.0, ")", 13.0, ")"]
|
10
|
+
@result = 1
|
11
|
+
@Lisp = Lisp.new(@string, @type)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_type_access
|
15
|
+
assert_equal(@type, @Lisp.type)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_string_access
|
19
|
+
assert_equal(@string, @Lisp.string)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_array_access
|
23
|
+
assert_equal(@array, @Lisp.array)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_results
|
27
|
+
assert_equal(@result, @Lisp.result)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TestReverseLisp < MiniTest::Test
|
32
|
+
def setup
|
33
|
+
@type = "reverse-lisp"
|
34
|
+
@string = "( 13 ( 12 ( ( 2 3 ^ ) 18 / ) + ) - )"
|
35
|
+
@array = ["(", 13.0, "(", 12.0, "(", "(", 2.0, 3.0, "**", ")", 18.0, "/", ")", "+", ")", "-", ")"]
|
36
|
+
@result = 1
|
37
|
+
@ReverseLisp = Lisp.new(@string, @type)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_type_access
|
41
|
+
assert_equal(@type, @ReverseLisp.type)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_string_access
|
45
|
+
assert_equal(@string, @ReverseLisp.string)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_array_access
|
49
|
+
assert_equal(@array, @ReverseLisp.array)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_results
|
53
|
+
assert_equal(@result, @ReverseLisp.result)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class TestPN < MiniTest::Test
|
58
|
+
def setup
|
59
|
+
@type = "pn"
|
60
|
+
@string = "- + / 18 ^ 3 2 12 13"
|
61
|
+
@array = ['-', '+', '/', 18.0, '**', 3.0, 2.0, 12.0, 13.0]
|
62
|
+
@result = 1
|
63
|
+
@PN = MathNotation.new(@string, @type)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_type_access
|
67
|
+
assert_equal(@type, @PN.type)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_string_access
|
71
|
+
assert_equal(@string, @PN.string)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_array_access
|
75
|
+
assert_equal(@array, @PN.array)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_result_access
|
79
|
+
assert_equal(@result, @PN.result)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class TestRPN < MiniTest::Test
|
84
|
+
def setup
|
85
|
+
@type = "rpn"
|
86
|
+
@string = "12 18 3 2 ^ / 13 - +"
|
87
|
+
@array = [12.0, 18.0, 3.0, 2.0, "**", "/", 13.0, "-", "+"]
|
88
|
+
@result = 1
|
89
|
+
@RPN = MathNotation.new(@string, @type)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_string_access
|
93
|
+
assert_equal(@string, @RPN.string)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_array_access
|
97
|
+
assert_equal(@array, @RPN.array)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_result_access
|
101
|
+
assert_equal(@result, @RPN.result)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class TestInfix < MiniTest::Test
|
106
|
+
def setup
|
107
|
+
@type = "rpn"
|
108
|
+
@string = "12 + 18 / ( 3 ^ 2 ) - 13"
|
109
|
+
@rpn_array = [12.0, 18.0, 3.0, 2.0, "**", "/", 13.0, "-", "+"]
|
110
|
+
@result = 1
|
111
|
+
@Infix = MathNotation.new(@string, "infix")
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_type
|
115
|
+
assert_equal(@type, @Infix.type)
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_string_access
|
119
|
+
assert_equal(@string, @Infix.string)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_shunting_yard
|
123
|
+
assert_equal(@rpn_array, @Infix.array)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_result_access
|
127
|
+
assert_equal(@result, @Infix.result)
|
128
|
+
end
|
129
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: calculo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Noah Holt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: os
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake_dmg
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ocra
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: A calculator for the command line supporting postfix, prefix, infix,
|
56
|
+
and lisp notation (plus a REPL)
|
57
|
+
email: noahryanholt@gmail.com
|
58
|
+
executables:
|
59
|
+
- calculo
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- Rakefile
|
64
|
+
- README.md
|
65
|
+
- test/test.rb
|
66
|
+
- lib/calculo.rb
|
67
|
+
- lib/calculo/lisp.rb
|
68
|
+
- lib/calculo/parse.rb
|
69
|
+
- lib/calculo/math.rb
|
70
|
+
- lib/calculo/shunting_yard.rb
|
71
|
+
- lib/calculo/repl.rb
|
72
|
+
- bin/calculo
|
73
|
+
homepage: https://github.com/noaoh/calculo
|
74
|
+
licenses:
|
75
|
+
- GPLv3
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
- bin
|
82
|
+
- test
|
83
|
+
- lib/calculo
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 2.0.0
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.0.14.1
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: A calculator for the command line
|
100
|
+
test_files: []
|