calculo 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|