crisp 0.0.7 → 0.0.8

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.
@@ -1,7 +1,16 @@
1
- ## 0.0.8 (2010-xx-xx)
1
+ ## 0.0.9 (2011-xx-xx)
2
2
 
3
3
  * ...
4
4
 
5
+ ## 0.0.8 (2011-01-06)
6
+
7
+ * local bindings with let
8
+ * cond provides a kind of switch/case statemnts, including default path
9
+ * load lets you load crisp source files at runtime
10
+ * loops can be performed with loop/recur
11
+ * internal fixes and refactorings
12
+ * more examples
13
+
5
14
  ## 0.0.6/0.0.7 (2010-12-17)
6
15
 
7
16
  * if else statements
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ begin
15
15
  gem.homepage = "http://github.com/mgsnova/crisp"
16
16
  gem.authors = ['Markus Gerdes']
17
17
  gem.add_dependency 'treetop', '~> 1.4.9'
18
- gem.add_development_dependency 'rspec', '~> 2.3.0'
18
+ gem.add_development_dependency 'rspec', '~> 2.4.0'
19
19
  end
20
20
 
21
21
  Jeweler::GemcutterTasks.new
data/bin/crisp CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'lib/crisp'
3
+ require 'crisp'
4
4
 
5
5
  if ARGV.size == 0
6
6
  Crisp::Shell.new.run
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{crisp}
8
- s.version = "0.0.7"
8
+ s.version = "0.0.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Markus Gerdes"]
12
- s.date = %q{2010-12-17}
12
+ s.date = %q{2011-01-06}
13
13
  s.default_executable = %q{crisp}
14
14
  s.email = %q{github@mgsnova.de}
15
15
  s.executables = ["crisp"]
@@ -25,7 +25,9 @@ Gem::Specification.new do |s|
25
25
  "autotest/discover.rb",
26
26
  "bin/crisp",
27
27
  "crisp.gemspec",
28
+ "examples/factorial.crisp",
28
29
  "examples/fibonacci.crisp",
30
+ "examples/run.crisp",
29
31
  "lib/crisp.rb",
30
32
  "lib/crisp/chained_env.rb",
31
33
  "lib/crisp/crisp.treetop",
@@ -83,14 +85,14 @@ Gem::Specification.new do |s|
83
85
 
84
86
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
85
87
  s.add_runtime_dependency(%q<treetop>, ["~> 1.4.9"])
86
- s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
88
+ s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
87
89
  else
88
90
  s.add_dependency(%q<treetop>, ["~> 1.4.9"])
89
- s.add_dependency(%q<rspec>, ["~> 2.3.0"])
91
+ s.add_dependency(%q<rspec>, ["~> 2.4.0"])
90
92
  end
91
93
  else
92
94
  s.add_dependency(%q<treetop>, ["~> 1.4.9"])
93
- s.add_dependency(%q<rspec>, ["~> 2.3.0"])
95
+ s.add_dependency(%q<rspec>, ["~> 2.4.0"])
94
96
  end
95
97
  end
96
98
 
@@ -0,0 +1,6 @@
1
+ (def factorial
2
+ (fn [n]
3
+ (loop [cnt n acc 1]
4
+ (if (= 0 cnt)
5
+ acc
6
+ (recur (- cnt 1) (* acc cnt))))))
@@ -3,4 +3,3 @@
3
3
  (if (< n 2)
4
4
  n
5
5
  (+ (fib (- n 1)) (fib (- n 2))))))
6
- (println "fibonacci for 10 is" (fib 10))
@@ -0,0 +1,5 @@
1
+ (load "fibonacci")
2
+ (load "factorial")
3
+
4
+ (println "fibonacci for 10 is" (fib 10))
5
+ (println "factorial of 10 is" (factorial 10))
@@ -3,7 +3,7 @@ require "treetop"
3
3
  require "pp"
4
4
 
5
5
  module Crisp
6
- VERSION = '0.0.7'
6
+ VERSION = '0.0.8'
7
7
  end
8
8
 
9
9
  require 'crisp/errors'
@@ -29,5 +29,15 @@ module Crisp
29
29
  def []=(key, val)
30
30
  @second[key] = val
31
31
  end
32
+
33
+ # returns global loop data of global/second env
34
+ def global_loop_data
35
+ @second.global_loop_data
36
+ end
37
+
38
+ # set global loop data to global/second env
39
+ def global_loop_data=(data)
40
+ @second.global_loop_data = data
41
+ end
32
42
  end
33
43
  end
@@ -37,7 +37,7 @@ grammar Crisp
37
37
  end
38
38
 
39
39
  rule symbol
40
- [a-z] [a-z0-9]* <Nodes::SymbolLiteral>
40
+ [a-zA-Z] [a-zA-Z0-9]* <Nodes::SymbolLiteral>
41
41
  end
42
42
 
43
43
  rule integer
@@ -2,6 +2,8 @@ module Crisp
2
2
  # The Crisp environment is basically a key/value store.
3
3
  # The value for each key is immutable, so you can only store one time for each key
4
4
  class Env
5
+ attr_accessor :global_loop_data
6
+
5
7
  # create a new internal hash
6
8
  def initialize
7
9
  @map = {}
@@ -9,4 +9,7 @@ module Crisp
9
9
  class EnvironmentError < StandardError
10
10
  end
11
11
 
12
+ class LoopError < StandardError
13
+ end
14
+
12
15
  end
@@ -54,10 +54,6 @@ module Crisp
54
54
  raise ArgumentError, "no argument list defined"
55
55
  end
56
56
 
57
- if args[1].class.name != "Crisp::Nodes::Operation"
58
- raise ArgumentError, "no function body defined"
59
- end
60
-
61
57
  fn_arg_list = args[0].raw_elements
62
58
  fn_operation = args[1]
63
59
 
@@ -72,7 +68,7 @@ module Crisp
72
68
 
73
69
  chained_env = ChainedEnv.new(local_env, env)
74
70
 
75
- fn_operation.eval(chained_env)
71
+ fn_operation.resolve_and_eval(chained_env)
76
72
  end
77
73
  end.bind('fn', current_env)
78
74
 
@@ -96,6 +92,127 @@ module Crisp
96
92
  res ? res.resolve_and_eval(env) : res
97
93
  end.bind('if', current_env)
98
94
 
95
+ # cond
96
+ # cond works like a switch/case statement, evaluating the first expression where the condition matches
97
+ #
98
+ # (cond
99
+ # false (println "should not be printed")
100
+ # true (println "should be printed"))
101
+ Function.new do
102
+ if args.size.odd?
103
+ raise ArgumentError, "argument list has to contain even list of arguments"
104
+ end
105
+
106
+ result = nil
107
+
108
+ args.each_with_index do |arg, idx|
109
+ next if idx.odd?
110
+ if (arg.class.name == 'Crisp::Nodes::SymbolLiteral' and arg.text_value == 'else') or
111
+ (![nil, false].include?(arg.resolve_and_eval(env)))
112
+ result = args[idx + 1].resolve_and_eval(env)
113
+ break
114
+ end
115
+ end
116
+
117
+ result
118
+ end.bind("cond", current_env)
119
+
120
+ # let
121
+ # create local binding only valid within let and evaluate expressions
122
+ #
123
+ # (let [x 1 y 2] (+ x y))
124
+ # => 3
125
+ Function.new do
126
+ if args[0].class.name != "Crisp::Nodes::ArrayLiteral"
127
+ raise ArgumentError, "no argument list defined"
128
+ end
129
+
130
+ if args[0].raw_elements.size.odd?
131
+ raise ArgumentError, "argument list has to contain even list of arguments"
132
+ end
133
+
134
+ local_env = Env.new
135
+ chained_env = ChainedEnv.new(local_env, env)
136
+ binding_array = args[0].raw_elements
137
+
138
+ binding_array.each_with_index do |key, idx|
139
+ next if idx.odd?
140
+ local_env[key.text_value] = binding_array[idx+1].resolve_and_eval(chained_env)
141
+ end
142
+
143
+ args[1..-1].map do |op|
144
+ op.resolve_and_eval(chained_env)
145
+ end.last
146
+ end.bind('let', current_env)
147
+
148
+ # loop
149
+ # create loop with a local binding, perform a loopjump using recur
150
+ #
151
+ # (loop [cnt 5 acc 1]
152
+ # (if (= 0 cnt)
153
+ # acc
154
+ # (recur (- cnt 1) (* acc cnt))))
155
+ # => 120
156
+ Function.new do
157
+ if env.global_loop_data
158
+ raise LoopError, "nested loops are not allowed"
159
+ end
160
+
161
+ if args[0].class.name != "Crisp::Nodes::ArrayLiteral"
162
+ raise ArgumentError, "no argument list defined"
163
+ end
164
+
165
+ if args[0].raw_elements.size.odd?
166
+ raise ArgumentError, "argument list has to contain even list of arguments"
167
+ end
168
+
169
+ local_env = Env.new
170
+ chained_env = ChainedEnv.new(local_env, env)
171
+ binding_array = args[0].raw_elements
172
+ argument_name_array = []
173
+
174
+ binding_array.each_with_index do |key, idx|
175
+ next if idx.odd?
176
+ local_env[key.text_value] = binding_array[idx+1].resolve_and_eval(chained_env)
177
+ argument_name_array << key.text_value
178
+ end
179
+
180
+ env.global_loop_data = {
181
+ :operations => args[1..-1],
182
+ :argument_names => argument_name_array
183
+ }
184
+
185
+ result = args[1..-1].map do |op|
186
+ op.resolve_and_eval(chained_env)
187
+ end.last
188
+
189
+ env.global_loop_data = nil
190
+
191
+ result
192
+ end.bind('loop', current_env)
193
+
194
+ # recur
195
+ # only used inside a loop. recur will trigger a new run of the loop
196
+ # see 'loop' for an example
197
+ Function.new do
198
+ if !env.global_loop_data
199
+ raise LoopError, "recur called outside loop"
200
+ end
201
+
202
+ validate_args_count(env.global_loop_data[:argument_names].size, args.size)
203
+
204
+ local_env = Env.new
205
+ chained_env = ChainedEnv.new(local_env, env)
206
+
207
+ env.global_loop_data[:argument_names].each_with_index do |key, idx|
208
+ local_env[key] = args[idx].resolve_and_eval(env)
209
+ end
210
+
211
+ env.global_loop_data[:operations].map do |op|
212
+ op.resolve_and_eval(chained_env)
213
+ end.last
214
+ end.bind('recur', current_env)
215
+
99
216
  # .
100
217
  # perform a native call on an object with optional arguments
101
218
  #
@@ -103,12 +220,42 @@ module Crisp
103
220
  # => "ABC"
104
221
  Function.new do
105
222
  meth = args[0].text_value.to_sym
106
- target = args[1].resolve_and_eval(env)
223
+ target = if args[1].class.name == "Crisp::Nodes::SymbolLiteral" and !env.has_key?(args[1].text_value)
224
+ Object.const_get(args[1].text_value)
225
+ else
226
+ args[1].resolve_and_eval(env)
227
+ end
107
228
  values = args[2..-1].map { |arg| arg.resolve_and_eval(env) }
108
229
 
109
230
  NativeCallInvoker.new(target, meth, values).invoke!
110
231
  end.bind('.', current_env)
111
232
 
233
+ # load
234
+ # include content of another crisp source file
235
+ #
236
+ # (load "business_logic")
237
+ # => true
238
+ Function.new do
239
+ args_evaled.collect(&:to_s).each do |filename|
240
+ pwd = `pwd`.strip
241
+ file = if filename[0..1] == '/'
242
+ File.join(pwd, filename)
243
+ else
244
+ filename
245
+ end.sub(".crisp$", '') + '.crisp'
246
+
247
+ if !File.exists?(file)
248
+ raise Crisp::ArgumentError, "file #{file} not found"
249
+ end
250
+
251
+ filecontent = File.read(file)
252
+ ast = Crisp::Parser.new.parse(filecontent)
253
+ Crisp::Runtime.new(env).run(ast)
254
+ end
255
+
256
+ true
257
+ end.bind('load', current_env)
258
+
112
259
  end
113
260
  end
114
261
  end
@@ -4,13 +4,9 @@ module Crisp
4
4
  class Block < Base
5
5
  # eval each element of the block and return the last result
6
6
  def eval(env)
7
- last_result = nil
8
-
9
- elements.each do |op|
10
- last_result = op.resolve_and_eval(env)
11
- end
12
-
13
- last_result
7
+ elements.map do |op|
8
+ op.resolve_and_eval(env)
9
+ end.last
14
10
  end
15
11
 
16
12
  # a block resolves to itself
@@ -5,9 +5,9 @@ module Crisp
5
5
  # get the function binded to the given function name and eval it (including arguments)
6
6
  def eval(env)
7
7
  if self.func_identifier.class.name == "Crisp::Nodes::Operation"
8
- self.func_identifier.eval(env).eval(env, self.element_list.elements.collect(&:element))
8
+ self.func_identifier.eval(env).eval(env, raw_element_list)
9
9
  else
10
- env[self.func_identifier.text_value].eval(env, self.element_list.elements.collect(&:element))
10
+ env[self.func_identifier.text_value].eval(env, raw_element_list)
11
11
  end
12
12
  end
13
13
 
@@ -15,6 +15,12 @@ module Crisp
15
15
  def resolve(env)
16
16
  self
17
17
  end
18
+
19
+ private
20
+
21
+ def raw_element_list
22
+ self.element_list.elements.collect(&:element)
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -6,9 +6,9 @@ module Crisp
6
6
  # Run code by calling run with the output of the parser as argurment.
7
7
  class Runtime
8
8
  # create a new env and load all functions when creating a new runtime
9
- def initialize
10
- @env = Env.new
11
- Functions.load(@env)
9
+ def initialize(env = nil)
10
+ @env = env || Env.new
11
+ Functions.load(@env) if !env
12
12
  end
13
13
 
14
14
  # run the parsed code (abstract syntax tree)
@@ -82,7 +82,7 @@ describe "arithemtic functions" do
82
82
  evaluate("(< 1 2)").should == true
83
83
  end
84
84
 
85
- it "should calc fibonacci numbers" do
85
+ it "calculates fibonacci numbers" do
86
86
  evaluate("
87
87
  (def fib (
88
88
  fn [n]
@@ -3,17 +3,17 @@ require 'spec_helper'
3
3
  describe "the language" do
4
4
  include Crisp::SpecHelper
5
5
 
6
- it "does not bother whitspaces characters in expressions" do
6
+ it "does not bother whitspace characters in expressions" do
7
7
  evaluate(" \r\t\n (\r+\t 1\n2 \t(\n - 9\r\t \n 2)\r)\r\t ").should == 10
8
8
  end
9
9
 
10
- it "creates syntax error on invalid expressions" do
10
+ it "raises a syntax error on invalid expressions" do
11
11
  lambda do
12
12
  evaluate("(()")
13
13
  end.should raise_error(Crisp::SyntaxError, "syntax error at : 0")
14
14
  end
15
15
 
16
- it "bind arrays to symbols" do
16
+ it "binds arrays to symbols" do
17
17
  evaluate("(def bla [1 2 3])").size.should == 3
18
18
  evaluate("(def bla [1 2 3])")[1].should == 2
19
19
  evaluate("(def foo 5)(def bla [1 2 foo])")[2].should == 5
@@ -80,4 +80,140 @@ describe "the core language features" do
80
80
  it "resolves symbols in if statements" do
81
81
  evaluate("(def foo 2)(if true foo)").should == 2
82
82
  end
83
+
84
+ it "uses local binding with let" do
85
+ evaluate("(let [x 1] x)").should == 1
86
+ end
87
+
88
+ it "uses more complex local bindings with let" do
89
+ evaluate("(let [x 2 y x] (* x y))").should == 4
90
+ end
91
+
92
+ it "evaluates several expressions within local binding" do
93
+ evaluate("(let [x 2 y 3] (* x y) (+ x y))").should == 5
94
+ end
95
+
96
+ it "binds symbols to global binding within local binding" do
97
+ evaluate("(let [x 1 y 2] (def foo (+ x y))) foo").should == 3
98
+ end
99
+
100
+ it "overrides global binding within local binding" do
101
+ evaluate("(def x 1)(let [x 2] x)").should == 2
102
+ end
103
+
104
+ it "ensures that local binding is only valid within let" do
105
+ evaluate("(def x 1)(let [x 2] x) x").should == 1
106
+ end
107
+
108
+ it "can handle emtpy local binding" do
109
+ evaluate("(let [] 2)").should == 2
110
+ end
111
+
112
+ it "raises an error when calling let without correct argument" do
113
+ lambda do
114
+ evaluate("(let 2 2)")
115
+ end.should raise_error(Crisp::ArgumentError, "no argument list defined")
116
+ end
117
+
118
+ it "raises an error when calling let with odd binding list" do
119
+ lambda do
120
+ evaluate("(let [x 1 y] 2)")
121
+ end.should raise_error(Crisp::ArgumentError, "argument list has to contain even list of arguments")
122
+ end
123
+
124
+ it "raises an error if file to be load not there" do
125
+ lambda do
126
+ evaluate('(load "not_there")')
127
+ end.should raise_error(Crisp::ArgumentError, /file (.*) not found/)
128
+
129
+ lambda do
130
+ evaluate('(load "/not_there")')
131
+ end.should raise_error(Crisp::ArgumentError, "file /not_there.crisp not found")
132
+ end
133
+
134
+ it "loads other crisp files" do
135
+ File.open("/tmp/crisp_test_file.crisp", 'w') do |f|
136
+ f << "(def foo 123)"
137
+ end
138
+
139
+ evaluate('(load "/tmp/crisp_test_file")(+ 1 foo)').should == 124
140
+ end
141
+
142
+ it "uses the current environment when loading other crisp source files" do
143
+ File.open("/tmp/crisp_test_file.crisp", 'w') do |f|
144
+ f << "(def bla 123)"
145
+ end
146
+
147
+ lambda do
148
+ evaluate('(def bla 321)(load "/tmp/crisp_test_file")')
149
+ end.should raise_error(Crisp::EnvironmentError, "bla already binded")
150
+ end
151
+
152
+ it "raises an error if calling cond with wrong number of arguments" do
153
+ lambda do
154
+ evaluate("(cond false 1 true)")
155
+ end.should raise_error(Crisp::ArgumentError, "argument list has to contain even list of arguments")
156
+ end
157
+
158
+ it "has cond statement" do
159
+ evaluate("(cond)").should == nil
160
+ evaluate("(cond false 1 false 2)").should == nil
161
+ evaluate("(cond true 3)").should == 3
162
+ evaluate("(cond true 3 false 2)").should == 3
163
+ evaluate("(cond false 3 true 2)").should == 2
164
+ evaluate("(cond (= 1 1) (+ 1 1))").should == 2
165
+ evaluate("(cond true 3 true 2 true 1)").should == 3
166
+ end
167
+
168
+ it "does not eval expressions for unmatched condition" do
169
+ evaluate("(cond false (def foo 1) true 2)(def foo 2) foo").should == 2
170
+ end
171
+
172
+ it "has a default condition in cond" do
173
+ evaluate("(cond false 1 true 2 else 3)").should == 2
174
+ evaluate("(cond true 1 true 2 else 3)").should == 1
175
+ evaluate("(cond false 1 else 2 true 3)").should == 2
176
+ end
177
+
178
+ it "raises an error when calling loop without correct argument" do
179
+ lambda do
180
+ evaluate("(loop 2 2)")
181
+ end.should raise_error(Crisp::ArgumentError, "no argument list defined")
182
+ end
183
+
184
+ it "raises an error when calling loop with odd binding list" do
185
+ lambda do
186
+ evaluate("(loop [x 1 y] 2)")
187
+ end.should raise_error(Crisp::ArgumentError, "argument list has to contain even list of arguments")
188
+ end
189
+
190
+ it "raises an error when calling recur outside a loop" do
191
+ lambda do
192
+ evaluate("(recur 1)")
193
+ end.should raise_error(Crisp::LoopError, "recur called outside loop")
194
+ end
195
+
196
+ it "raises an error when calling recur with wrong number of arguments" do
197
+ lambda do
198
+ evaluate("(loop [x 1] (recur 1 2))")
199
+ end.should raise_error(Crisp::ArgumentError, "wrong number of arguments for 'recur' (2 for 1)")
200
+ end
201
+
202
+ it "calculates factorials using loop recur" do
203
+ evaluate("
204
+ (def factorial
205
+ (fn [n]
206
+ (loop [cnt n acc 1]
207
+ (if (= 0 cnt)
208
+ acc
209
+ (recur (- cnt 1) (* acc cnt))))))
210
+ (factorial 5)
211
+ ").should == 120
212
+ end
213
+
214
+ it "raises an error when nesting loops" do
215
+ lambda do
216
+ evaluate("(loop [x 1] (loop [a 1 b 2] (+ a b)))")
217
+ end.should raise_error(Crisp::LoopError, "nested loops are not allowed")
218
+ end
83
219
  end
@@ -15,10 +15,11 @@ describe "the languages functions" do
15
15
  end.should raise_error(Crisp::ArgumentError, "no argument list defined")
16
16
  end
17
17
 
18
- it "does not create a function when not providing a proper function body" do
19
- lambda do
20
- evaluate("(fn [] [])")
21
- end.should raise_error(Crisp::ArgumentError, "no function body defined")
18
+ it "does return primitive values as result" do
19
+ evaluate("((fn [] 1))").should == 1
20
+ evaluate('((fn [] "abc"))').should == 'abc'
21
+ evaluate('((fn [] [1 2 3]))').should == [1, 2, 3]
22
+ evaluate("((fn [x] x) 2)").should == 2
22
23
  end
23
24
 
24
25
  it "creates functions" do
@@ -3,21 +3,27 @@ require 'spec_helper'
3
3
  describe "NativeCallInvoker functionality" do
4
4
  include Crisp::SpecHelper
5
5
 
6
- it "should execute String#reverse probably" do
6
+ it "executes ruby native String#reverse" do
7
7
  evaluate('(. reverse "foobar")').should == 'raboof'
8
8
  end
9
9
 
10
- it "should execute Array#first probably" do
10
+ it "executes ruby native Array#first" do
11
11
  evaluate('(. first [1 2 3])').should == 1
12
12
  end
13
13
 
14
- it "should execute Array#first(n) probably" do
14
+ it "executes ruby native Array#first(n)" do
15
15
  evaluate('(. first [1 2 3] 2)').should == [1,2]
16
16
  end
17
17
 
18
- it "should raise a named exception on invalid method" do
18
+ it "raises a named exception on invalid method" do
19
19
  lambda do
20
20
  evaluate('(. foo "bar")')
21
21
  end.should raise_error(NoMethodError, %q{undefined method `foo' for "bar":String})
22
22
  end
23
+
24
+ it "executes calls on Ruby classes" do
25
+ evaluate("(. new String)").should == ''
26
+ evaluate('(. new String "123")').should == '123'
27
+ evaluate("(. new Array 5 2)").should == [2, 2, 2, 2, 2]
28
+ end
23
29
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe "string functionality" do
4
4
  include Crisp::SpecHelper
5
5
 
6
- it "should concat strings" do
6
+ it "concats strings" do
7
7
  evaluate('(+ "foo" "bar")').should == 'foobar'
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crisp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Markus Gerdes
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-17 00:00:00 +01:00
18
+ date: 2011-01-06 00:00:00 +01:00
19
19
  default_executable: crisp
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -42,12 +42,12 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- hash: 3
45
+ hash: 31
46
46
  segments:
47
47
  - 2
48
- - 3
48
+ - 4
49
49
  - 0
50
- version: 2.3.0
50
+ version: 2.4.0
51
51
  type: :development
52
52
  version_requirements: *id002
53
53
  description:
@@ -67,7 +67,9 @@ files:
67
67
  - autotest/discover.rb
68
68
  - bin/crisp
69
69
  - crisp.gemspec
70
+ - examples/factorial.crisp
70
71
  - examples/fibonacci.crisp
72
+ - examples/run.crisp
71
73
  - lib/crisp.rb
72
74
  - lib/crisp/chained_env.rb
73
75
  - lib/crisp/crisp.treetop