rprb 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +5 -0
- data/README +53 -0
- data/bin/rprb +13 -0
- data/lib/expr.rb +64 -0
- data/lib/rprb.rb +189 -0
- data/test/tc_evaluator.rb +199 -0
- data/test/tc_misc.rb +8 -0
- data/test/tc_reader.rb +27 -0
- data/test/ts_all.rb +5 -0
- metadata +92 -0
data/LICENSE
ADDED
data/README
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
##
|
2
|
+
## Intro/sample script for rprb (aka Reverse Polish RuBy)
|
3
|
+
##
|
4
|
+
|
5
|
+
{ Kernel swap puts drop } :say sto
|
6
|
+
{ "Enter to continue..." say gets drop } :pause sto
|
7
|
+
|
8
|
+
# basic RPN stuff
|
9
|
+
1 1 + p
|
10
|
+
2 * p
|
11
|
+
pause
|
12
|
+
|
13
|
+
# basic Ruby stuff
|
14
|
+
zero? p
|
15
|
+
0 zero? p
|
16
|
+
Array.new 1 push p
|
17
|
+
clr
|
18
|
+
pause
|
19
|
+
|
20
|
+
# obviously, lines starting with # are ignored, but also..
|
21
|
+
<<proc { puts "hi!" }
|
22
|
+
call
|
23
|
+
pause
|
24
|
+
|
25
|
+
# like Lisp, we have a "read" function
|
26
|
+
"1 1 +" read p
|
27
|
+
# which is equivalent to
|
28
|
+
{ 1 1 + } p
|
29
|
+
pause
|
30
|
+
|
31
|
+
# and an "eval" function to evaluate the results
|
32
|
+
eval p clr
|
33
|
+
pause
|
34
|
+
|
35
|
+
# and an "evaln" function to evaluate n times
|
36
|
+
{ 1 1 + } 5 dupn 5 evaln p clr
|
37
|
+
|
38
|
+
# we have registers..
|
39
|
+
1 :a sto p
|
40
|
+
:a rcl p
|
41
|
+
|
42
|
+
# registers store our functions
|
43
|
+
:drop rcl p
|
44
|
+
{ dup2 + } :fib sto
|
45
|
+
0 1 fib p
|
46
|
+
|
47
|
+
# exen executes multiple times
|
48
|
+
:fib 5 exen
|
49
|
+
|
50
|
+
# which is equivalent to
|
51
|
+
:fib rcl 5 evaln
|
52
|
+
|
53
|
+
# and a bunch of other stuff
|
data/bin/rprb
ADDED
data/lib/expr.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# This code is release by the authors into the Public Domain
|
2
|
+
|
3
|
+
# stream: expr+
|
4
|
+
# expr: block | atom | comment
|
5
|
+
# string_literal: duh
|
6
|
+
# block: { stream }
|
7
|
+
# atom: \S+ | string_literal
|
8
|
+
# comment: # anything endl
|
9
|
+
# endl: \n
|
10
|
+
#
|
11
|
+
|
12
|
+
require 'rubygems'
|
13
|
+
require 'packrat/grammar'
|
14
|
+
|
15
|
+
module RpRb
|
16
|
+
Grammar = Packrat::Grammar.new do
|
17
|
+
start_symbol :Stream
|
18
|
+
|
19
|
+
S = hidden(/\s*/)
|
20
|
+
FS = hidden(/\s\s*/)
|
21
|
+
|
22
|
+
prod :Stream, [mult(:Expression), ast(:Stream)]
|
23
|
+
|
24
|
+
prod :StringLiteral, [/"(?:[^"]|\\")*"/, lift(0)]
|
25
|
+
|
26
|
+
prod :Block, [hidden('{'), S, :Stream, S, hidden('}'), ast(:Block)]
|
27
|
+
|
28
|
+
prod :Atom, [any(:StringLiteral, /[^{} \t]+/), lift(0)]
|
29
|
+
|
30
|
+
rule :Expression, [S, any(:Block, :Atom), S, ast(:Expression)]
|
31
|
+
end
|
32
|
+
|
33
|
+
Parser = Grammar.interpreting_parser
|
34
|
+
|
35
|
+
class Reader
|
36
|
+
def read(string)
|
37
|
+
to_stream(Parser.parse_string(string))
|
38
|
+
end
|
39
|
+
|
40
|
+
include RpRb::Grammar::ASTs
|
41
|
+
|
42
|
+
def to_stream(ast)
|
43
|
+
case ast
|
44
|
+
when Stream
|
45
|
+
ast.children[0].collect { |child| to_stream(child) }
|
46
|
+
when Expression, Block
|
47
|
+
to_stream ast.children[0]
|
48
|
+
else
|
49
|
+
ast
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if __FILE__ == $0
|
56
|
+
require 'pp'
|
57
|
+
|
58
|
+
while gets
|
59
|
+
puts "Parser output:"
|
60
|
+
pp RpRb::Parser.parse_string($_.chomp)
|
61
|
+
puts "Reader output:"
|
62
|
+
pp RpRb::Reader.new.read($_.chomp)
|
63
|
+
end
|
64
|
+
end
|
data/lib/rprb.rb
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
# This code is release by the authors into the Public Domain
|
2
|
+
|
3
|
+
module Enumerable
|
4
|
+
def collect_with_index
|
5
|
+
result = []
|
6
|
+
each_with_index { |elem, i|
|
7
|
+
result << yield(elem, i)
|
8
|
+
}
|
9
|
+
result
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
#class Rational
|
14
|
+
# def inspect
|
15
|
+
# to_s
|
16
|
+
# end
|
17
|
+
#end
|
18
|
+
|
19
|
+
def trythese(*procs)
|
20
|
+
if procs.length == 0
|
21
|
+
raise "Ahhg!"
|
22
|
+
else
|
23
|
+
begin
|
24
|
+
procs[0].call
|
25
|
+
rescue Exception => error
|
26
|
+
#puts "ERROR: " + error
|
27
|
+
trythese(*procs[1..-1])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'expr'
|
33
|
+
|
34
|
+
module RpRb
|
35
|
+
class DC
|
36
|
+
def initialize
|
37
|
+
@reader = Reader.new
|
38
|
+
|
39
|
+
@stack = []
|
40
|
+
|
41
|
+
@registers = {
|
42
|
+
:eval => proc { |x| eval x },
|
43
|
+
:read => proc { |x| read x },
|
44
|
+
|
45
|
+
:p => proc { ||
|
46
|
+
puts "___"
|
47
|
+
puts @stack.collect_with_index { |entry, i| "%3d: %s" % [i, entry.inspect] }.reverse.join("\n")
|
48
|
+
puts "---"
|
49
|
+
:noval
|
50
|
+
},
|
51
|
+
|
52
|
+
:pick => proc { |n| @stack[n] },
|
53
|
+
:del => proc { |n| @stack.slice!(n); :noval },
|
54
|
+
:sto => proc { |val, sym| @registers[sym] = val; :noval },
|
55
|
+
:rcl => proc { |sym| @registers[sym] },
|
56
|
+
:if => proc { |den, elz, test| if test; den; else; elz; end },
|
57
|
+
:len => proc { || @stack.length },
|
58
|
+
|
59
|
+
:push => proc { |array, elem| array.push elem; array },
|
60
|
+
|
61
|
+
:while => proc { |expr, cond| loop { eval(cond); break unless @stack.shift; eval(expr) }; :noval },
|
62
|
+
:evaln => proc { |expr, n| n.times { eval(expr) }; :noval },
|
63
|
+
:loop => proc { |expr, times| times.times { |i| @stack.unshift(i); eval(expr) }; :noval },
|
64
|
+
:each => proc { |enumerable, expr| enumerable.each { |elem| @stack.unshift(elem); eval(expr) }; :noval },
|
65
|
+
|
66
|
+
:array => proc { |length| @stack.slice!(0, length).reverse },
|
67
|
+
|
68
|
+
:regs => proc { || @registers.keys },
|
69
|
+
}
|
70
|
+
|
71
|
+
|
72
|
+
[
|
73
|
+
read('{ Array.new } :"[]" sto'),
|
74
|
+
read('0 array :control sto'),
|
75
|
+
read('{ false true 2 pick if 1 del } :not sto'),
|
76
|
+
read('{ :control rcl swap unshift :control sto } :save sto'),
|
77
|
+
read('{ :control rcl 0 slice! } :restore sto'),
|
78
|
+
read('{ 1 pick 2 del } :swap sto'),
|
79
|
+
read('{ 0 del } :drop sto'),
|
80
|
+
read('{ 0 pick } :dup sto'),
|
81
|
+
read('{ {drop} swap evaln } :dropn sto'),
|
82
|
+
read('{ 2 dropn } :drop2 sto'),
|
83
|
+
read('{ 2 dupn } :dup2 sto'),
|
84
|
+
read('{ len dropn } :clr sto'),
|
85
|
+
read('{ rcl eval } :exe sto'),
|
86
|
+
read('{ swap rcl swap evaln } :exen sto'),
|
87
|
+
read('{ 1 - } :dec sto'),
|
88
|
+
read('{ 1 + } :inc sto'),
|
89
|
+
read('{ -1 * } :neg sto'),
|
90
|
+
read('{ 1.0 swap / } :inv sto'),
|
91
|
+
read('{ restore dup save } :peek sto'),
|
92
|
+
read('{ restore drop save } :poke sto'),
|
93
|
+
read('{ save {peek 1 - pick} peek evaln restore drop } :dupn sto'),
|
94
|
+
read('0 array :nop sto'),
|
95
|
+
read('{ swap dup length save swap each restore array } :map sto'),
|
96
|
+
read('{ File swap open save peek readlines restore close drop } :slurp sto'),
|
97
|
+
read('{ slurp {chomp} map {read} map {eval} each } :load sto'),
|
98
|
+
read('{ inc dup pick swap del } :take sto'),
|
99
|
+
read('{ len {+} swap dec evaln } :sum sto'),
|
100
|
+
].each { |stream| eval(stream) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def stack
|
104
|
+
@stack.dup
|
105
|
+
end
|
106
|
+
|
107
|
+
def read(val)
|
108
|
+
@reader.read val
|
109
|
+
end
|
110
|
+
|
111
|
+
def eval(tokens)
|
112
|
+
#puts "Eval-ing #{tokens.inspect}"
|
113
|
+
tokens.each { |token|
|
114
|
+
#puts "processing token #{token.inspect}..."
|
115
|
+
result = trythese(
|
116
|
+
*[
|
117
|
+
proc { execute(token.intern) },
|
118
|
+
proc { parse_code(token) },
|
119
|
+
proc { Kernel.eval(token) },
|
120
|
+
proc { puts("Error, nothing left to do"); :noval },
|
121
|
+
]
|
122
|
+
)
|
123
|
+
|
124
|
+
unless result == :noval
|
125
|
+
@stack.unshift result
|
126
|
+
end
|
127
|
+
}
|
128
|
+
|
129
|
+
:noval
|
130
|
+
end
|
131
|
+
|
132
|
+
def parse_code(stream)
|
133
|
+
if stream.is_a? Array
|
134
|
+
stream
|
135
|
+
else
|
136
|
+
raise "#{stream.inspect} isn't code!"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def execute(fn)
|
141
|
+
# check if /fn/ names a register
|
142
|
+
if @registers.include? fn
|
143
|
+
case @registers[fn]
|
144
|
+
when Proc, Method
|
145
|
+
values = @stack.slice!(0, @registers[fn].arity).reverse
|
146
|
+
return @registers[fn].call(*values)
|
147
|
+
else
|
148
|
+
return eval(@registers[fn])
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# check if /fn/ is a valid function call for an item on the stack
|
153
|
+
@stack.each_with_index { |src, arity|
|
154
|
+
begin
|
155
|
+
if fn == :call and (src.is_a?(Proc) or src.is_a?(Method)) and (src.arity == arity or src.arity == -1)
|
156
|
+
values = @stack.slice!(0, arity + 1).reverse
|
157
|
+
return values[0].call(*values[1..-1])
|
158
|
+
elsif src.respond_to?(fn) and (src.method(fn).arity == arity or src.method(fn).arity == -1)
|
159
|
+
values = @stack.slice!(0, arity + 1).reverse
|
160
|
+
return values[0].send(fn, *values[1..-1])
|
161
|
+
end
|
162
|
+
rescue ArgumentsError
|
163
|
+
end
|
164
|
+
}
|
165
|
+
|
166
|
+
# check if /fn/ is a valid method of Kernel or Math
|
167
|
+
[Kernel, Math].each { |src|
|
168
|
+
begin
|
169
|
+
if src.respond_to? fn
|
170
|
+
values = @stack.slice!(0, src.method(fn).arity).reverse
|
171
|
+
return src.send(fn, *values)
|
172
|
+
end
|
173
|
+
rescue
|
174
|
+
end
|
175
|
+
}
|
176
|
+
|
177
|
+
raise "Couldn't execute function on stack item, DC, Kernel, or Math"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
if __FILE__ == $0
|
183
|
+
dc = RpRb::DC.new
|
184
|
+
while gets
|
185
|
+
dc.eval dc.read($_.chomp)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# vim:ts=4:sw=4
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rprb'
|
3
|
+
|
4
|
+
include RpRb
|
5
|
+
|
6
|
+
class DCTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@dc = DC.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def e(arg)
|
12
|
+
@dc.eval arg
|
13
|
+
end
|
14
|
+
|
15
|
+
def r(arg)
|
16
|
+
@dc.read arg
|
17
|
+
end
|
18
|
+
|
19
|
+
def re(arg)
|
20
|
+
e r(arg)
|
21
|
+
end
|
22
|
+
|
23
|
+
def s
|
24
|
+
@dc.stack
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_basic_eval
|
28
|
+
re('nil nil')
|
29
|
+
assert_equal [nil, nil], s
|
30
|
+
|
31
|
+
re('clr 1 2 3')
|
32
|
+
assert_equal [3, 2, 1], s
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_basic_method_calling
|
36
|
+
re('1 2 +')
|
37
|
+
assert_equal [3], s
|
38
|
+
|
39
|
+
re 'clr 1 2 3 4 4 array 5 push'
|
40
|
+
assert_equal [[1, 2, 3, 4, 5]], s
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_basic_Math_method_calling
|
44
|
+
re('0 sin 0 cos')
|
45
|
+
assert_equal [1.0, 0.0], s
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_proc_calling
|
49
|
+
re '"proc{|arg|1+arg}" eval 1 call'
|
50
|
+
assert_equal [2], s
|
51
|
+
|
52
|
+
re 'clr Math.method(:sin) 0 call'
|
53
|
+
assert_equal [0.0], s
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_basic_dc_methods
|
57
|
+
re('0 dup')
|
58
|
+
assert_equal [0, 0], s
|
59
|
+
|
60
|
+
re('nil dup')
|
61
|
+
assert_equal [nil, nil, 0, 0], s
|
62
|
+
|
63
|
+
re('drop2 drop')
|
64
|
+
assert_equal [0], s
|
65
|
+
|
66
|
+
re('1 2')
|
67
|
+
assert_equal [2, 1, 0], s
|
68
|
+
|
69
|
+
re('drop dup2')
|
70
|
+
assert_equal [1, 0, 1, 0], s
|
71
|
+
|
72
|
+
re('drop2')
|
73
|
+
assert_equal [1, 0], s
|
74
|
+
|
75
|
+
re 'swap'
|
76
|
+
assert_equal [0, 1], s
|
77
|
+
|
78
|
+
re '1 pick'
|
79
|
+
assert_equal [1, 0, 1], s
|
80
|
+
|
81
|
+
re 'neg'
|
82
|
+
assert_equal [-1, 0, 1], s
|
83
|
+
|
84
|
+
re 'inc'
|
85
|
+
assert_equal [0, 0, 1], s
|
86
|
+
|
87
|
+
re 'dec'
|
88
|
+
assert_equal [-1, 0, 1], s
|
89
|
+
|
90
|
+
re 'len'
|
91
|
+
assert_equal [3, -1, 0, 1], s
|
92
|
+
|
93
|
+
re '[]'
|
94
|
+
assert_equal [[], 3, -1, 0, 1], s
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_variables
|
98
|
+
re('0 1 :a sto')
|
99
|
+
assert_equal [0], s
|
100
|
+
|
101
|
+
re(':a rcl')
|
102
|
+
assert_equal [1, 0], s
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_if
|
106
|
+
re('1 2 true if')
|
107
|
+
assert_equal [1], s
|
108
|
+
|
109
|
+
re('clr 1 2 false if')
|
110
|
+
assert_equal [2], s
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_not
|
114
|
+
re 'false not'
|
115
|
+
assert_equal [true], s
|
116
|
+
|
117
|
+
re 'clr true not'
|
118
|
+
assert_equal [false], s
|
119
|
+
|
120
|
+
re 'clr nil not'
|
121
|
+
assert_equal [true], s
|
122
|
+
|
123
|
+
re 'clr 0 not'
|
124
|
+
assert_equal [false], s
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_while
|
128
|
+
re '{ 1 } { len 5 == not } while'
|
129
|
+
assert_equal [1, 1, 1, 1, 1], s
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_array
|
133
|
+
re '1 2 3 4 4 array'
|
134
|
+
assert_equal [[1, 2, 3, 4]], s
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_evaln
|
138
|
+
re '{ 1 } 5 evaln'
|
139
|
+
assert_equal [1, 1, 1, 1, 1], s
|
140
|
+
|
141
|
+
re '3 dropn { dup2 + } 3 evaln'
|
142
|
+
assert_equal [5, 3, 2, 1, 1], s
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_stored_procedures
|
146
|
+
re('{ dup2 + } :fib sto 1 1')
|
147
|
+
assert_equal [1, 1], s
|
148
|
+
re('fib fib')
|
149
|
+
assert_equal [3, 2, 1, 1], s
|
150
|
+
re(':fib rcl eval')
|
151
|
+
assert_equal [5, 3, 2, 1, 1], s
|
152
|
+
re(':fib rcl 2 evaln')
|
153
|
+
assert_equal [13, 8, 5, 3, 2, 1, 1], s
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_save_restore
|
157
|
+
re '1 save 2 save restore save :control rcl'
|
158
|
+
assert_equal [[2, 1]], s
|
159
|
+
|
160
|
+
re('clr Array.new :control sto 1 save :control rcl')
|
161
|
+
assert_equal [[1]], s
|
162
|
+
|
163
|
+
re 'clr restore'
|
164
|
+
assert_equal [1], s
|
165
|
+
|
166
|
+
re 'clr :control rcl'
|
167
|
+
assert_equal [[]], s
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_each
|
171
|
+
re '1 2 3 4 5 5 array { 2 * } each'
|
172
|
+
assert_equal [10, 8, 6, 4, 2], s
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_map
|
176
|
+
re('1 2 3 4 5 5 array { 2 * } map')
|
177
|
+
assert_equal [[2, 4, 6, 8, 10]], s
|
178
|
+
|
179
|
+
re 'clr 1 2 3 4 5 5 array { neg } map'
|
180
|
+
assert_equal [[-1, -2, -3, -4, -5]], s
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_load
|
184
|
+
require 'tempfile'
|
185
|
+
thefile = nil
|
186
|
+
Tempfile.open("tc_evaluator") { |file|
|
187
|
+
thefile = file
|
188
|
+
file.write <<-END
|
189
|
+
{ dup2 + } :fib sto
|
190
|
+
{ 1 1 } :blah sto
|
191
|
+
END
|
192
|
+
}
|
193
|
+
|
194
|
+
re %Q{"#{thefile.path}" load}
|
195
|
+
re 'blah :fib 3 exen'
|
196
|
+
assert_equal [5, 3, 2, 1, 1], s
|
197
|
+
thefile.delete
|
198
|
+
end
|
199
|
+
end
|
data/test/tc_misc.rb
ADDED
data/test/tc_reader.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rprb'
|
3
|
+
|
4
|
+
include RpRb
|
5
|
+
|
6
|
+
class ReaderTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@reader = Reader.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def r(arg)
|
12
|
+
@reader.read arg
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_read
|
16
|
+
assert_equal ['1'], @reader.read("1")
|
17
|
+
assert_equal [['1']], @reader.read("{ 1 }")
|
18
|
+
assert_equal [['1']], @reader.read("{1}")
|
19
|
+
|
20
|
+
assert_equal ['1', ['1']], @reader.read('1 {1}')
|
21
|
+
|
22
|
+
assert_equal [[]], @reader.read('{ }')
|
23
|
+
|
24
|
+
assert_equal ['"1 2 3"'], r('"1 2 3"')
|
25
|
+
assert_equal ['"proc {}"'], r('"proc {}"')
|
26
|
+
end
|
27
|
+
end
|
data/test/ts_all.rb
ADDED
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rprb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jimmy Thrasher and Justin Dubs
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2006-10-11 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rockit
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 7
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 7
|
32
|
+
- 2
|
33
|
+
version: 0.7.2
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description:
|
37
|
+
email:
|
38
|
+
executables:
|
39
|
+
- rprb
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- lib/rprb.rb
|
46
|
+
- lib/expr.rb
|
47
|
+
- bin/rprb
|
48
|
+
- test/ts_all.rb
|
49
|
+
- test/tc_evaluator.rb
|
50
|
+
- test/tc_reader.rb
|
51
|
+
- test/tc_misc.rb
|
52
|
+
- README
|
53
|
+
- LICENSE
|
54
|
+
has_rdoc: true
|
55
|
+
homepage:
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.3.7
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Provides Ruby in RPN style, ostensibly for a dc replacement
|
88
|
+
test_files:
|
89
|
+
- test/ts_all.rb
|
90
|
+
- test/tc_evaluator.rb
|
91
|
+
- test/tc_reader.rb
|
92
|
+
- test/tc_misc.rb
|