obtuse 0.0.1 → 0.0.2

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.
@@ -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: