rprb 0.1
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.
- 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
|