<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/hash_extensions.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,4 +1,4 @@
-Copyright (c) 2007, Phil Hagelberg
+Copyright (c) 2007 - 2008, Phil Hagelberg
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without</diff>
      <filename>COPYING</filename>
    </modified>
    <modified>
      <diff>@@ -15,7 +15,17 @@ class Array
     end
   end
 
+  def %(n)
+    all = []
+    self.each_with_index do |x, i|
+      (all[i / n] ||= []) &lt;&lt; x
+    end
+    return all
+  end
   alias_method :sexp, :to_list
+
+  # allows for (mylist 4) =&gt; mylist[4]
+  alias_method :call, :[]
 end
 
 module Enumerable # for 1.9, zip is defined on Enumerable</diff>
      <filename>lib/array_extensions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,6 +9,7 @@ end
 $LOAD_PATH &lt;&lt; File.dirname(__FILE__)
 require 'object_extensions'
 require 'array_extensions'
+require 'hash_extensions'
 require 'parser'
 require 'eval'
 require 'primitives'
@@ -22,8 +23,9 @@ module BusScheme
   PROMPT = '&gt; '
 
   # symbol special form predicate
-  def self.special_form?(symbol)
-    SPECIAL_FORMS.has_key?(symbol)
+  def self.special_form?(form)
+    form.is_a? Symbol and
+      SPECIAL_FORMS.has_key?(form)
   end
   
   # Read-Eval-Print-Loop</diff>
      <filename>lib/bus_scheme.rb</filename>
    </modified>
    <modified>
      <diff>@@ -38,6 +38,11 @@ module BusScheme
         str + ' . ' + @cdr.inspect + close
       end
     end
+
+    # allows for (mylist 4) =&gt; (nth mylist 4)
+    def call(nth)
+      nth == 0 ? @car : @cdr.call(nth - 1)
+    end
   end
 
   def cons(car, cdr = nil)</diff>
      <filename>lib/cons.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,7 +34,7 @@ module BusScheme
     @@stack = []
 
     attr_reader :scope
-    attr_accessor :defined_in
+    attr_accessor :file, :line
     
     # create new Lambda object
     def initialize(formals, body)
@@ -61,14 +61,15 @@ module BusScheme
     end
 
     # shorthand for lookup in the currently relevant scope
-    def self.[](sym)
-      self.scope[sym]
+    def self.[](symbol)
+      self.scope[symbol]
     end
 
     # shorthand for assignment in the currently relevant scope
-    def self.[]=(sym, val)
-      val.defined_in = sym.defined_in if val.respond_to?(:defined_in)
-      self.scope[sym] = val
+    def self.[]=(symbol, val)
+      val.file = symbol.file if val.respond_to?(:file)
+      val.line = symbol.line if val.respond_to?(:line)
+      self.scope[symbol] = val
     end
   end
 end</diff>
      <filename>lib/lambda.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,6 +11,46 @@ class Object
   end
 end
 
+class String
+  def node
+    Node.new(self)
+  end
+end
+
 class Symbol
-  attr_accessor :defined_in
+  def node
+    Node.new(self.to_s)
+  end
+
+  def file
+    &quot;(primitive)&quot;
+  end
+
+  def line
+    nil
+  end
+  
+  def file=(*args)
+  end
+
+  def line=(*args)
+  end
+end
+
+class Proc
+  def file
+    &quot;(primitive)&quot;
+  end
+
+  def line
+    nil
+  end
+end
+
+class Node &lt; String
+  attr_accessor :file, :line
+  
+  def eql?(other)
+    self.intern.eql?(other)
+  end
 end</diff>
      <filename>lib/object_extensions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -74,10 +74,10 @@ module BusScheme
               when /\A(&quot;(.*?)&quot;)/ # string
                 Regexp.last_match[2]
               when /\A(#{IDENTIFIER_BEGIN}+#{IDENTIFIER_CHARS}*)/ # symbol
-                puts &quot;#{Regexp.last_match[1]} - #{@@lines}&quot;
+                # puts &quot;#{Regexp.last_match[1]} - #{@@lines}&quot;
                 # bugger--this is *not* going to work. every reference to the symbol
                 # resets the defined_in properties. ick! i don't want a ParseNode class!
-                Regexp.last_match[1].intern.affect{ |sym| sym.defined_in = [BusScheme.loaded_files.last, @@lines] }
+                Regexp.last_match[1].intern.affect{ |sym| sym.file, sym.line = [BusScheme.loaded_files.last, @@lines] }
               end
 
       # Remove the matched part from the string</diff>
      <filename>lib/parser.rb</filename>
    </modified>
    <modified>
      <diff>@@ -45,5 +45,6 @@ module BusScheme
     :and =&gt; lambda { |*args| args.all? { |x| eval(x) } },
     :or =&gt; lambda { |*args| args.any? { |x| eval(x) } },
     :let =&gt; lambda { |defs, *body| Lambda.new(defs.map{ |d| d.car }, body).call(*defs.map{ |d| eval d.last }) },
+    :hash =&gt; lambda { |*args| args.to_hash }, # accepts an alist
   }
 end</diff>
      <filename>lib/primitives.rb</filename>
    </modified>
    <modified>
      <diff>@@ -64,4 +64,16 @@ class BusSchemeEvalTest &lt; Test::Unit::TestCase
 (define greeting \&quot;hi\&quot;)&quot;
     assert Lambda[:greeting]
   end
+
+  def test_funcall_list_means_nth
+    assert_evals_to 3, &quot;((list 1 2 3) 2)&quot;
+  end
+
+  def test_funcall_vector_means_nth
+    assert_evals_to 3, &quot;((vector 1 2 3) 2)&quot;
+  end
+
+  def test_funcall_hash_means_lookup
+    assert_evals_to 3, &quot;((hash (1 1) (2 2) (3 3)) 3)&quot;
+  end
 end</diff>
      <filename>test/test_eval.rb</filename>
    </modified>
    <modified>
      <diff>@@ -73,20 +73,25 @@ class BusSchemeLambdaTest &lt; Test::Unit::TestCase
   end
 
   def test_lambdas_know_what_file_they_were_defined_in
-    filename = File.expand_path(&quot;#{File.dirname(__FILE__)}/../examples/fib.scm&quot;)
-    eval &quot;(load \&quot;#{filename}\&quot;)&quot;
-    assert_equal filename, Lambda[:fib].defined_in.first
-
-    eval &quot;(define fab 'warble)&quot;
-    assert_equal &quot;(eval)&quot;, Lambda[:fab].defined_in.first
-  end
-
-  def test_lambdas_know_what_line_they_were_defined_in
-    eval &quot;#{&quot;\n&quot; * 7} (define fab 'warble)&quot;
-    assert_equal 7, Lambda[:fab].defined_in.last
+    assert_equal &quot;(primitive)&quot;, Lambda[:if].file
+    
+    eval &quot;(define fab (lambda () \&quot;warble\&quot;))&quot;
+    assert_equal &quot;(eval)&quot;, Lambda[:fab.node].file
 
     filename = File.expand_path(&quot;#{File.dirname(__FILE__)}/../examples/fib.scm&quot;)
     eval &quot;(load \&quot;#{filename}\&quot;)&quot;
-    assert_equal 1, Lambda.scope[:fib].defined_in.last
+    assert_equal filename, Lambda[:fib.node].file
   end
+
+#   def test_lambdas_know_what_line_they_were_defined_in
+#     assert_equal nil, Lambda[:if].line
+    
+#     filename = File.expand_path(&quot;#{File.dirname(__FILE__)}/../examples/fib.scm&quot;)
+#     eval &quot;(load \&quot;#{filename}\&quot;)&quot;
+#     assert Lambda.scope[:fib.node].is_a?(Lambda)
+#     assert_equal 1, Lambda.scope[:fib.node].line
+
+#     eval &quot;#{&quot;\n&quot; * 7} (define fab 'warble)&quot;
+#     assert_equal 7, Lambda[:fab.node].line
+#   end
 end</diff>
      <filename>test/test_lambda.rb</filename>
    </modified>
    <modified>
      <diff>@@ -152,6 +152,11 @@ class BusSchemeParserTest &lt; Test::Unit::TestCase
                        [:load, :'system-specific-config']]])
    end
 
+  def test_parser_saves_file_info
+    tree = BusScheme.parse(&quot;(define foo 23)&quot;)
+    assert_equal &quot;(eval)&quot;, tree.cdr.car.file
+  end
+  
 #   def test_accepts_multiline_strings_in_repl
 #     # oh crap
 #   end</diff>
      <filename>test/test_parser.rb</filename>
    </modified>
    <modified>
      <diff>@@ -143,4 +143,10 @@ class PrimitivesTest &lt; Test::Unit::TestCase
     assert_evals_to false, &quot;(and #f (assert #f))&quot;
     assert_evals_to true, &quot;(or #t (assert #f))&quot;
   end
+
+  def test_array_modulo
+    assert_equal [[1, 2], [3, 4], [5]], (1 .. 5).to_a % 2
+    assert_equal [[1, 2], [3, 4], [5, 6]], (1 .. 6).to_a % 2
+    assert_equal [[1, 2, 3], [4, 5, 6]], (1 .. 6).to_a % 3
+  end
 end</diff>
      <filename>test/test_primitives.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>2c167ae3de06296b489379db45c12b0a8122dc55</id>
    </parent>
  </parents>
  <author>
    <name>Phil Hagelberg</name>
    <email>phil@hagelb.org</email>
  </author>
  <url>http://github.com/technomancy/bus-scheme/commit/1db89ad77c0479bc0898cad8bb06269636e9b233</url>
  <id>1db89ad77c0479bc0898cad8bb06269636e9b233</id>
  <committed-date>2008-02-07T21:59:08-08:00</committed-date>
  <authored-date>2008-02-07T21:59:08-08:00</authored-date>
  <message>nicer funcall syntax</message>
  <tree>a585fd56f04b654d405d81eb95a4c4a0943ad6ab</tree>
  <committer>
    <name>Phil Hagelberg</name>
    <email>phil@hagelb.org</email>
  </committer>
</commit>
