obtuse 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - ruby-head
5
+ - jruby-19mode
6
+ - rbx-19mode
7
+ script: bundle exec rspec spec
data/README.md CHANGED
@@ -1,29 +1,40 @@
1
- # Obtuse
1
+ # Obtuse [![Build Status](https://travis-ci.org/utkarshkukreti/obtuse.png)](https://travis-ci.org/utkarshkukreti/obtuse)
2
2
 
3
- TODO: Write a gem description
3
+ Obtuse is a stack-oriented programming language, optimized for brevity.
4
4
 
5
5
  ## Installation
6
6
 
7
- Add this line to your application's Gemfile:
7
+ ### Using Git (recommended)
8
8
 
9
- gem 'obtuse'
9
+ ```
10
+ $ git clone https://github.com/utkarshkukreti/obtuse.git
11
+ $ cd obtuse
12
+ $ bundle install
13
+ $ rake install
14
+ ```
10
15
 
11
- And then execute:
16
+ ### Using RubyGems
12
17
 
13
- $ bundle
18
+ ```
19
+ $ gem install obtuse
20
+ ```
14
21
 
15
- Or install it yourself as:
22
+ ## Usage
16
23
 
17
- $ gem install obtuse
24
+ Run
18
25
 
19
- ## Usage
26
+ ```
27
+ $ obtuse
28
+ ```
29
+
30
+ to start the interactive REPL.
31
+
32
+ ## Documentation
33
+
34
+ Check out `spec/obtuse_spec.rb` for all functions and their outputs.
20
35
 
21
- TODO: Write usage instructions here
36
+ ## License
22
37
 
23
- ## Contributing
38
+ The MIT License.
24
39
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
40
+ Copyright (c) 2012, Utkarsh Kukreti.
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ task :pry do
4
+ system "pry -Ilib -robtuse -e 'include Obtuse'"
5
+ end
6
+
7
+ task default: :pry
@@ -1,5 +1,7 @@
1
1
  require "parslet"
2
2
 
3
+ require "obtuse/ast/lambda"
4
+
3
5
  require "obtuse/parser"
4
6
  require "obtuse/transform"
5
7
  require "obtuse/evaluator"
@@ -0,0 +1,11 @@
1
+ module Obtuse
2
+ module AST
3
+ class Lambda
4
+ attr_accessor :expression
5
+
6
+ def initialize(expression)
7
+ @expression = expression
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,26 +1,209 @@
1
1
  module Obtuse
2
2
  class Evaluator
3
- attr_reader :stack
3
+ attr_accessor :stdin
4
+ attr_reader :stack, :stash
4
5
 
5
6
  def initialize
6
7
  @stack = []
8
+ @stash = []
9
+ @stdin = $stdin
7
10
  @parser = Parser.new
8
11
  @transform = Transform.new
9
12
  end
10
13
 
11
- def eval(input)
12
- @transform.apply(@parser.parse(input)).each do |atom|
14
+ def eval(input, parsed = false)
15
+ if parsed == false
16
+ input = @transform.apply(@parser.parse(input))
17
+ end
18
+
19
+ input.each do |atom|
13
20
  case atom
14
- when Integer, String
21
+ when Integer, String, Array, AST::Lambda
15
22
  push atom
16
23
  when :+, :-, :*, :/, :%, :^
17
24
  atom = :** if atom == :^
18
- y, x = pop, pop
19
- if Integer === x && Integer === y ||
20
- String === x && String === y
25
+ x, y = pop 2
26
+ if Integer === x && Integer === y
21
27
  push x.send(atom, y)
28
+ elsif String === x && Integer === y
29
+ case atom
30
+ when :+
31
+ push x + y.to_s
32
+ when :*
33
+ push x * y
34
+ when :%
35
+ push x % y
36
+ end
37
+ elsif String === x && String === y
38
+ case atom
39
+ when :+
40
+ push x + y
41
+ when :-
42
+ push (x.chars.to_a - y.chars.to_a).join
43
+ when :*
44
+ push x.chars.to_a.join(y)
45
+ end
46
+ elsif String === x && Array === y
47
+ case atom
48
+ when :%
49
+ push x % y
50
+ end
51
+ elsif Array === x
52
+ case atom
53
+ when :+
54
+ push x + Array(y)
55
+ when :-
56
+ push x - Array(y)
57
+ when :*
58
+ if Integer === y
59
+ push x * y
60
+ elsif String === y
61
+ push x.join(y)
62
+ elsif Array === y
63
+ first = x.shift
64
+ push x.reduce([first]) {|fold, el| fold + y + [el] }
65
+ elsif AST::Lambda === y
66
+ push x.shift
67
+ x.each do |el|
68
+ push el
69
+ eval y.expression, true
70
+ end
71
+ end
72
+ when :%
73
+ if AST::Lambda === y
74
+ stash
75
+ x.each do |el|
76
+ push el
77
+ eval y.expression, true
78
+ end
79
+ stack = @stack
80
+ unstash
81
+ push stack
82
+ end
83
+ end
84
+ else
85
+ end
86
+ when :"#"
87
+ x = pop
88
+ if Integer === x
89
+ push [*0...x]
90
+ elsif String === x || Array === x
91
+ push x.length
92
+ end
93
+ when :"$"
94
+ x = pop
95
+ if Integer === x
96
+ push @stack[-x - 1] if @stack[-x - 1]
97
+ elsif String === x
98
+ push x.chars.sort.join
99
+ elsif Array === x
100
+ push x.sort
101
+ elsif AST::Lambda === x
102
+ y = x
103
+ x = pop
104
+ case x
105
+ when String, Array
106
+ stash
107
+ array = String === x ? x.chars.to_a : x
108
+ array.sort_by! do |el|
109
+ @stack = []
110
+ push el
111
+ eval y.expression, true
112
+ @stack
113
+ end
114
+ unstash
115
+ push String === x ? array.join : array
116
+ end
117
+ end
118
+ when :~
119
+ x = pop
120
+ case x
121
+ when String
122
+ eval x
123
+ when Array
124
+ @stack += x
125
+ when AST::Lambda
126
+ eval x.expression, true
127
+ end
128
+ when :!
129
+ push truthy?(pop) ? 0 : 1
130
+ when :"@"
131
+ x, y, z = pop 3
132
+ push y; push z; push x
133
+ when :"."
134
+ x = peek
135
+ push x if x
136
+ when :";"
137
+ pop
138
+ when :"["
139
+ stash
140
+ when :"]"
141
+ stack = @stack
142
+ unstash
143
+ push stack
144
+ when :"=", :<, :>
145
+ atom = :== if atom == :"="
146
+ x, y = pop 2
147
+ if Integer === x && Integer === y ||
148
+ String === x && String === y ||
149
+ Array === x && Array === y
150
+ push x.send(atom, y) ? 1 : 0
151
+ end
152
+ when :"\\"
153
+ x, y = pop 2
154
+ push y; push x;
155
+ when :I
156
+ x, y, z = pop 3
157
+ if AST::Lambda === x
158
+ eval x.expression, true
159
+ if truthy?(pop)
160
+ AST::Lambda === y ? eval(y.expression, true) : push(y)
161
+ else
162
+ AST::Lambda === z ? eval(z.expression, true) : push(z)
163
+ end
22
164
  else
165
+ if truthy?(x)
166
+ AST::Lambda === y ? eval(y.expression, true) : push(y)
167
+ else
168
+ AST::Lambda === z ? eval(z.expression, true) : push(z)
169
+ end
170
+ end
171
+ when :W
172
+ x, y = pop 2
173
+ if AST::Lambda === x && AST::Lambda === y
174
+ loop do
175
+ eval x.expression, true
176
+ break unless truthy?(pop)
177
+ eval y.expression, true
178
+ end
179
+ end
180
+ when :Ic
181
+ push pop.to_i.chr
182
+ when :Sg
183
+ x, y, z = pop 3
184
+ if (Integer === x || String === x) &&
185
+ (Integer === y || String === y) &&
186
+ (Integer === z || String === z)
187
+ push x.to_s.gsub(y.to_s, z.to_s)
23
188
  end
189
+ when :Sl
190
+ push pop.to_s.downcase
191
+ when :Su
192
+ push pop.to_s.upcase
193
+ when :Sc
194
+ push pop.to_s.capitalize
195
+ when :So
196
+ push pop.to_s.ord
197
+ when :Si
198
+ x, y = pop 2
199
+ push x.to_s.include?(y.to_s) ? 1 : 0
200
+ when :St
201
+ x, y, z = pop 3
202
+ push x.to_s.tr(y.to_s, z.to_s)
203
+ when :Ra
204
+ push stdin.read.chomp
205
+ when :Rl
206
+ push stdin.gets.chomp
24
207
  end
25
208
  end
26
209
  end
@@ -29,12 +212,25 @@ module Obtuse
29
212
  @stack << object
30
213
  end
31
214
 
32
- def pop
33
- @stack.pop
215
+ def pop(n = nil)
216
+ n ? @stack.pop(n) : @stack.pop
34
217
  end
35
218
 
36
219
  def peek
37
220
  @stack.last
38
221
  end
222
+
223
+ def stash
224
+ @stash << @stack
225
+ @stack = []
226
+ end
227
+
228
+ def unstash
229
+ @stack = @stash.pop
230
+ end
231
+
232
+ def truthy?(x)
233
+ !(x.nil? || x == 0 || x == "" || x == [])
234
+ end
39
235
  end
40
236
  end
@@ -4,9 +4,10 @@ module Obtuse
4
4
  rule(:spaces?) { spaces.maybe }
5
5
  rule(:digit) { match["0-9"] }
6
6
  rule(:digits) { match["0-9"].repeat(1) }
7
+ rule(:minus) { str("-") }
7
8
 
8
9
  rule :integer do
9
- digits.as(:integer) >> spaces?
10
+ (minus.maybe >> digits).as(:integer) >> spaces?
10
11
  end
11
12
 
12
13
  rule :string do
@@ -15,12 +16,19 @@ module Obtuse
15
16
  end
16
17
 
17
18
  rule :function do
18
- %w{+ - * / % ^}.map { |name| str name }.reduce(:|).
19
+ %w{+ - * / % ^ # $ ~ ! @ . ; [ ] = < > \\
20
+ W Ic I Sg Sl Su Sc So Si St Ra Rl}.
21
+ map { |name| str name }.reduce(:|).
19
22
  as(:function) >> spaces?
20
23
  end
21
24
 
25
+ rule :lambda do
26
+ str("{") >> spaces? >> expression.as(:expression).as(:lambda) >>
27
+ str("}") >> spaces?
28
+ end
29
+
22
30
  rule :expression do
23
- spaces? >> (string | integer | function).repeat >> spaces?
31
+ spaces? >> (integer | string | function | lambda).repeat >> spaces?
24
32
  end
25
33
 
26
34
  root :expression
@@ -5,5 +5,10 @@ module Obtuse
5
5
  rule(string: simple(:x)) do
6
6
  x.to_s.gsub('\\t', "\t").gsub('\\n', "\n").gsub('\\"', '"')
7
7
  end
8
+ rule(array: sequence(:x)) { x }
9
+
10
+ rule lambda: { expression: subtree(:expression) } do
11
+ AST::Lambda.new expression
12
+ end
8
13
  end
9
14
  end
@@ -1,3 +1,3 @@
1
1
  module Obtuse
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+
3
+ describe Obtuse do
4
+ describe "GCD" do
5
+ # From http://www.golfscript.com/golfscript/examples.html
6
+ e '13483 74205 {.}{.@\%}W;', 13483.gcd(74205)
7
+ end
8
+
9
+ describe "LCM" do
10
+ e '13483 74205 .@.@{.}{.@\%}W;\@*\/', 13483.lcm(74205)
11
+ end
12
+
13
+ describe "Project Euler" do
14
+ describe "Problem #6: Find the difference between the sum of the squares" +
15
+ " of the first one hundred natural numbers and the square of the sum." do
16
+ e '101#{+}*2^101#{2^}%{+}*-', 25164150
17
+ end
18
+ end
19
+ end
@@ -5,31 +5,348 @@ describe Obtuse do
5
5
  Obtuse::VERSION.should be_a String
6
6
  end
7
7
 
8
- describe "Integer Integer (+|-|*|/|%|^)" do
9
- e "2 1+", 3
10
- e "10 20 +", 30
11
- e "2 3-", -1
12
- e "10 20 -", -10
13
- e "2 3*", 6
14
- e "10 20 *", 200
15
- e "2 3/", 0
16
- e "10 20 /", 0
17
- e "2 3%", 2
18
- e "10 20 %", 10
19
- e "2 3^", 8
20
- e "10 20 ^", 10 ** 20
8
+ describe "Primitives" do
9
+ describe "Integer" do
10
+ e "2", 2
11
+ e "100", 100
12
+ e "-10", -10
13
+ end
21
14
 
22
- e "1 2+3-", 0
23
- e "5 1 4 5 2 3 4 +-+-+-", 0
15
+ describe "String" do
16
+ e %q{"a \n b \n c \t\td\na"}, "a \n b \n c \t\td\na"
17
+ end
24
18
  end
25
19
 
26
- describe "String" do
27
- e %q{"a \n b \n c \t\td\na"}, "a \n b \n c \t\td\na"
20
+ describe "Functions" do
21
+ describe "+" do
22
+ describe "Integer Integer" do
23
+ e "2 1+", 3
24
+ e "10 20 +", 30
25
+ e "2 -3+", -1
26
+ end
27
+
28
+ describe "String Integer" do
29
+ e %q{"foo: "42+}, "foo: 42"
30
+ end
31
+
32
+ describe "String String" do
33
+ e '"foo""bar"+', "foobar"
34
+ e '"foo" "bar"+', "foobar"
35
+ e '"foo\\"" "bar"+', 'foo"bar'
36
+ end
37
+
38
+ describe "Array Object" do
39
+ e %q{[1 2] 1 +}, [1, 2, 1]
40
+ e %q{[1 2] "1" +}, [1, 2, "1"]
41
+ e %q{[1] [] +}, [1]
42
+ e %q{[1 2] [3 4] +}, [1, 2, 3, 4]
43
+ end
44
+ end
45
+
46
+ describe "-" do
47
+ describe "Integer Integer" do
48
+ e "2 3-", -1
49
+ e "10 20 -", -10
50
+ e "-10 -20-", 10
51
+ end
52
+
53
+ describe "String String" do
54
+ e %q{"aaa""a"-}, ""
55
+ e %q{"cabc""b"-}, "cac"
56
+ e %q{"cabc""cb"-}, "a"
57
+ e %q{"cabc""cab"-}, ""
58
+ end
59
+
60
+ describe "Array Object" do
61
+ e %q{[1 2] 1 -}, [2]
62
+ e %q{[1 2] "1" -}, [1, 2]
63
+ e %q{[1] [] -}, [1]
64
+ e %q{[1 2 3 3 1 4 4] [3 4] -}, [1, 2, 1]
65
+ end
66
+ end
67
+
68
+ describe "*" do
69
+ describe "Integer Integer" do
70
+ e "2 3*", 6
71
+ e "10 20 *", 200
72
+ e "-5 5*", -25
73
+ end
74
+
75
+ describe "(String | Array) Integer" do
76
+ e %q{"foobar "3*}, "foobar foobar foobar "
77
+ e %q{[1 2 3] 3*}, [1, 2, 3, 1, 2, 3, 1, 2, 3]
78
+ end
79
+
80
+ describe "String String" do
81
+ e %q{"foobar" " 3 "*}, "f 3 o 3 o 3 b 3 a 3 r"
82
+ end
83
+
84
+ describe "Array String" do
85
+ e %q{[1 2 3] ", "*}, "1, 2, 3"
86
+ e %q{[1 . 3] ", "*}, "1, 1, 3"
87
+ end
88
+
89
+ describe "Array Array" do
90
+ e %q{[1 2 3] [1] *}, [1, 1, 2, 1, 3]
91
+ e %q{[1 2 3] [0 1] *}, [1, 0, 1, 2, 0, 1, 3]
92
+ end
93
+
94
+ describe "Array Lambda (Fold)" do
95
+ e %q{[1 2 3] {+} *}, 6
96
+ e %q{[1 2 3] {-} *}, -4
97
+ end
98
+ end
99
+
100
+ describe "/" do
101
+ describe "Integer Integer" do
102
+ e "2 3/", 0
103
+ e "10 20 /", 0
104
+ e "10 -2/", -5
105
+ end
106
+ end
107
+
108
+ describe "%" do
109
+ describe "Integer Integer" do
110
+ e "2 3%", 2
111
+ e "10 20 %", 10
112
+ e "5 -3%", -1
113
+ end
114
+
115
+ describe "String Integer" do
116
+ e %q{"%05d" 123%}, "00123"
117
+ end
118
+
119
+ describe "String Array" do
120
+ e %q{"%02d %03d %04d"4#%}, "00 001 0002"
121
+ e %q{"%02d %03d %04d"[0 1 2 3 4 5]%}, "00 001 0002"
122
+ end
123
+
124
+ describe "Array Lambda (Map)" do
125
+ e %q{[1 2 3 4] {..} %}, [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
126
+ end
127
+ end
128
+
129
+ describe "^" do
130
+ describe "Integer Integer" do
131
+ e "2 3^", 8
132
+ e "10 20 ^", 10 ** 20
133
+ e "-3 3^", -27
134
+ end
135
+ end
136
+
137
+ describe "#" do
138
+ describe "Integer" do
139
+ e "3#", [0, 1, 2]
140
+ end
141
+
142
+ describe "String" do
143
+ e %q{"foo bar"#}, 7
144
+ end
145
+
146
+ describe "Array" do
147
+ e "10##", 10
148
+ e "[1 2]#", 2
149
+ end
150
+ end
151
+
152
+ describe "$" do
153
+ describe "Integer" do
154
+ e %q{5 $}, [], stack: true
155
+ e %q{1 0 $}, [1, 1], stack: true
156
+ e %q{5#~ 3 $}, [0, 1, 2, 3, 4, 1], stack: true
157
+ end
158
+
159
+ describe "String" do
160
+ e %q{"abcdcba"$}, "aabbccd"
161
+ end
162
+
163
+ describe "Array" do
164
+ e %q{[1 4 3] $}, [1, 3, 4]
165
+ end
166
+
167
+ describe "(String | Array) Lambda (Sort by)" do
168
+ e %q{"abca" {.} $}, "aabc"
169
+ e %q{[1 4 3] {-1 *} $}, [4, 3, 1]
170
+ end
171
+ end
172
+
173
+ describe "~" do
174
+ describe "String" do
175
+ e %q{"123"~}, 123
176
+ e %q{"1 2 3 + -"~}, -4
177
+ end
178
+
179
+ describe "Array" do
180
+ e %q{4#~+++}, 6
181
+ e %q{[1 2]~+}, 3
182
+ end
183
+
184
+ describe "Lambda" do
185
+ e '{1 1 +}~', 2
186
+ end
187
+ end
188
+
189
+ describe "!" do
190
+ describe "" do
191
+ e "!", 1
192
+ end
193
+
194
+ describe "Integer" do
195
+ e "1!", 0
196
+ e "0!", 1
197
+ end
198
+
199
+ describe "String" do
200
+ e %q{""!}, 1
201
+ e %q{"foo"!}, 0
202
+ end
203
+
204
+ describe "Array" do
205
+ e "1#!", 0
206
+ e "0#!", 1
207
+ e "[]!", 1
208
+ e "[1]!", 0
209
+ end
210
+ end
211
+
212
+ describe "@" do
213
+ describe "Object Object Object" do
214
+ e %q{"abc" 10 4# @}, [10, [0, 1, 2, 3], "abc"], stack: true
215
+ end
216
+ end
217
+
218
+ describe "." do
219
+ describe "" do
220
+ e %q{1 2 .}, [1, 2, 2], stack: true
221
+ e %q{.}, [], stack: true
222
+ end
223
+ end
224
+
225
+ describe ";" do
226
+ describe "" do
227
+ e %q{1 2;}, [1], stack: true
228
+ e %q{2;}, [], stack: true
229
+ e %q{;}, [], stack: true
230
+ end
231
+ end
232
+
233
+ describe "[]" do
234
+ e %q{[1 . 2 . + . [1 . .]]}, [1, 1, 4, 4, [1, 1, 1]]
235
+ end
236
+
237
+ describe "=" do
238
+ describe "Object Object" do
239
+ e %q{12 12 =}, 1
240
+ e %q{"foo" "foo " =}, 0
241
+ end
242
+ end
243
+
244
+ describe "<" do
245
+ describe "Object Object" do
246
+ e %q{5 3 <}, 0
247
+ e %q{"bar" "foo" <}, 1
248
+ end
249
+ end
250
+
251
+ describe ">" do
252
+ describe "Object Object" do
253
+ e %q{5 3 >}, 1
254
+ e %q{"bar" "foo" >}, 0
255
+ end
256
+ end
257
+
258
+ describe "\\" do
259
+ describe "Object Object" do
260
+ e %q{1 2 \\}, [2, 1], stack: true
261
+ e %q{[] [1] \\}, [[1], []], stack: true
262
+ end
263
+ end
264
+
265
+ describe "I" do
266
+ describe "Object Object Object" do
267
+ e '0 1 2 I', 2
268
+ e '1 1 2 I', 1
269
+ e '0 1 {...} {.}I', [0, 0, 0, 0], stack: true
270
+ end
271
+ end
272
+
273
+ describe "W" do
274
+ describe "Lambda Lambda" do
275
+ e '3{.}{1-}W', 0
276
+ e '5{.}{1-.}W', [4, 3, 2, 1, 0, 0], stack: true
277
+ end
278
+ end
279
+
280
+ describe "Ic" do
281
+ describe "Integer" do
282
+ e "97 Ic", "a"
283
+ end
284
+ end
285
+
286
+ describe "Sg" do
287
+ describe "(Integer | String) (Integer | String) (Integer | String)" do
288
+ e %q{123 1 2 Sg}, "223"
289
+ e %q{"123" 1 "s" Sg}, "s23"
290
+ e %q{123 1 "s" Sg}, "s23"
291
+ e %q{"foo bar" "f" "b" Sg}, "boo bar"
292
+ end
293
+ end
294
+
295
+ describe "Sl" do
296
+ describe "String" do
297
+ e %q{"Foo Bar!" Sl}, "foo bar!"
298
+ end
299
+ end
300
+
301
+ describe "Su" do
302
+ describe "String" do
303
+ e %q{"Foo Bar!" Su}, "FOO BAR!"
304
+ end
305
+ end
306
+
307
+ describe "Sc" do
308
+ describe "String" do
309
+ e %q{"foo bar!" Sc}, "Foo bar!"
310
+ end
311
+ end
312
+
313
+ describe "So" do
314
+ describe "String" do
315
+ e %q{"a" So}, 97
316
+ end
317
+ end
318
+
319
+ describe "Si" do
320
+ describe "(Integer | String) (Integer | String)" do
321
+ e %q{123 11 Si}, 0
322
+ e %q{123 "11" Si}, 0
323
+ e %q{"foo bar" "o b" Si}, 1
324
+ e %q{"444" 4 Si}, 1
325
+ end
326
+ end
327
+
328
+ describe "St" do
329
+ describe "(Integer | String) (Integer | String) (Integer | String)" do
330
+ e %q{123 13 98 St}, "928"
331
+ e %q{"123" "13" 98 St}, "928"
332
+ e %q{"hello" "a-y" "b-z" St}, "ifmmp"
333
+ e %q{"hello" "^aeiou" 0 St}, "0e00o"
334
+ end
335
+ end
336
+
337
+ describe "Ra" do
338
+ e "Ra", "abc\nbcd", stdin: "abc\nbcd"
339
+ end
340
+
341
+ describe "Rl" do
342
+ e "Rl", "abc", stdin: "abc\nbcd"
343
+ end
28
344
  end
29
345
 
30
- describe "String String +" do
31
- e '"foo""bar"+', "foobar"
32
- e '"foo" "bar"+', "foobar"
33
- e '"foo\\"" "bar"+', 'foo"bar'
346
+ describe "Mixture" do
347
+ e "1 2+3-", 0
348
+ e "5 1 4 5 2 3 4 +-+-+-", 0
349
+ e "1-2-3-+", 2
350
+ e "1-2- 3+", 6
34
351
  end
35
352
  end
@@ -1,16 +1,25 @@
1
1
  require "bundler/setup"
2
2
  require "simplecov"
3
3
  SimpleCov.start do
4
- add_group "Libraries", "/lib"
4
+ add_group "Libraries", "/lib"
5
+ add_filter "/lib/obtuse/cli.rb"
5
6
  end
6
7
  require "obtuse"
7
8
 
8
9
  RSpec.configure do |config|
9
- def e(input, output)
10
- it "should evaluate #{input.inspect} to #{output.inspect}" do
10
+ def e(input, output, options = {})
11
+ stdin = options[:stdin]
12
+ stdin = String === stdin ? StringIO.new(stdin) : $stdin
13
+
14
+ it "should evaluate `#{input}` to `#{output}`" do
11
15
  evaluator = Obtuse::Evaluator.new
16
+ evaluator.stdin = stdin
12
17
  evaluator.eval(input)
13
- evaluator.peek.should eq output
18
+ if options[:stack]
19
+ evaluator.stack.should eq output
20
+ else
21
+ evaluator.peek.should eq output
22
+ end
14
23
  end
15
24
  end
16
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: obtuse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-17 00:00:00.000000000 Z
12
+ date: 2012-12-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parslet
@@ -101,6 +101,7 @@ extra_rdoc_files: []
101
101
  files:
102
102
  - .gitignore
103
103
  - .rspec
104
+ - .travis.yml
104
105
  - Gemfile
105
106
  - Guardfile
106
107
  - LICENSE.txt
@@ -108,12 +109,14 @@ files:
108
109
  - Rakefile
109
110
  - bin/obtuse
110
111
  - lib/obtuse.rb
112
+ - lib/obtuse/ast/lambda.rb
111
113
  - lib/obtuse/cli.rb
112
114
  - lib/obtuse/evaluator.rb
113
115
  - lib/obtuse/parser.rb
114
116
  - lib/obtuse/transform.rb
115
117
  - lib/obtuse/version.rb
116
118
  - obtuse.gemspec
119
+ - spec/examples_spec.rb
117
120
  - spec/obtuse_spec.rb
118
121
  - spec/spec_helper.rb
119
122
  homepage: https://github.com/utkarshkukreti/obtuse
@@ -141,6 +144,7 @@ signing_key:
141
144
  specification_version: 3
142
145
  summary: A Stack-oriented programming language, optimized for brevity.
143
146
  test_files:
147
+ - spec/examples_spec.rb
144
148
  - spec/obtuse_spec.rb
145
149
  - spec/spec_helper.rb
146
150
  has_rdoc: