Permalink
Browse files

Kernel.loop

  • Loading branch information...
1 parent b27097f commit a399fbf24de9ce7c69230b0b8330a6e0a79ed605 @jmettraux committed Feb 4, 2012
Showing with 85 additions and 5 deletions.
  1. +1 −1 TODO.txt
  2. +1 −0 lib/subaltern.rb
  3. +2 −0 lib/subaltern/context.rb
  4. +6 −3 lib/subaltern/evaluator.rb
  5. +64 −0 lib/subaltern/kernel.rb
  6. +11 −1 spec/loops_spec.rb
View
2 TODO.txt
@@ -16,7 +16,7 @@
[o] while / until
[o] for
-[ ] Kernel.loop
+[o] Kernel.loop
[ ] rescue (maybe rescue nil is useful)
View
1 lib/subaltern.rb
@@ -26,6 +26,7 @@
require 'subaltern/errors'
require 'subaltern/context'
require 'subaltern/evaluator'
+require 'subaltern/kernel'
module Subaltern
View
2 lib/subaltern/context.rb
@@ -38,6 +38,8 @@ class Context
#
def initialize(parent={}, vars=nil)
+ vars.merge!(Subaltern.kernel) if parent.nil?
+
@parent, @variables = [ parent, vars ]
@parent, @variables = [ nil, parent ] if vars.nil?
end
View
9 lib/subaltern/evaluator.rb
@@ -413,8 +413,6 @@ def self.eval_const(context, tree)
def self.eval_defn(context, tree)
- #p tree
-
name = tree[1].to_s
context[name] = Function.new(tree)
@@ -494,7 +492,7 @@ def self.eval_if(context, tree)
if eval_tree(context, tree[1])
eval_tree(context, tree[2])
- else
+ elsif tree[3]
eval_tree(context, tree[3])
end
end
@@ -584,5 +582,10 @@ def self.eval_for(context, tree)
values.each { |v| block.call(context, [ v ], false) }
end
+
+ def self.eval_loop(context, tree)
+
+ pp tree
+ end
end
View
64 lib/subaltern/kernel.rb
@@ -0,0 +1,64 @@
+#--
+# Copyright (c) 2011-2012, John Mettraux, jmettraux@gmail.com
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#++
+
+
+module Subaltern
+
+ def self.kernel
+
+ {
+ 'loop' => LoopFunction.new
+ }
+ end
+
+ class LoopFunction < Function
+
+ def initialize
+ end
+
+ def call(context, tree)
+
+ return nil unless context['__block']
+ # a real Ruby would return an Enumerator instance
+
+ con = Context.new(context, {})
+
+ loop do
+
+ begin
+
+ r = context['__block'].call(con, [], false)
+ # new_context is false
+
+ rescue Command => c
+
+ case c.name
+ when 'break' then break c
+ when 'next' then next c
+ else raise c
+ end
+ end
+ end
+ end
+ end
+end
+
View
12 spec/loops_spec.rb
@@ -92,7 +92,17 @@
describe 'loop' do
- it 'works'
+ it 'works' do
+
+ Subaltern.eval(%{
+ a = 0
+ loop do
+ a = a + 1
+ break if a > 7
+ end
+ a
+ }).should == 8
+ end
end
end

0 comments on commit a399fbf

Please sign in to comment.