X-Git-Url: http://git.hcoop.net/jackhill/mal.git/blobdiff_plain/bed63064c55c6f4dd80e43783df2ad310b2ae074..56be4ef0ee1b601b126f2db9c83b2ab1238f362a:/crystal/env.cr diff --git a/crystal/env.cr b/crystal/env.cr index 98ecc7ea..9f38d687 100644 --- a/crystal/env.cr +++ b/crystal/env.cr @@ -1,4 +1,5 @@ require "./types" +require "./error" module Mal @@ -12,15 +13,34 @@ module Mal def initialize(@outer, binds, exprs : Array(Mal::Type)) @data = {} of String => Mal::Type - raise EvalException.new "binds must be list or vector" unless binds.is_a?(Array) + eval_error "binds must be list or vector" unless binds.is_a? Array # Note: # Array#zip() can't be used because overload resolution failed (0...binds.size).each do |idx| - sym, expr = binds[idx], exprs[idx] - raise EvalException.new "bind list must be symbol" unless sym.is_a?(Mal::Symbol) - @data[sym.val] = expr + sym = binds[idx].unwrap + eval_error "bind name must be symbol" unless sym.is_a? Mal::Symbol + + if sym.str == "&" + eval_error "missing variable parameter name" if binds.size == idx + next_param = binds[idx+1].unwrap + eval_error "bind name must be symbol" unless next_param.is_a? Mal::Symbol + var_args = Mal::List.new + exprs[idx..-1].each{|e| var_args << e} if idx < exprs.size + @data[next_param.str] = Mal::Type.new var_args + break + end + + @data[sym.str] = exprs[idx] + end + end + + def dump + puts "ENV BEGIN".colorize.red + @data.each do |k, v| + puts " #{k} -> #{print(v)}".colorize.red end + puts "ENV END".colorize.red end def set(key, value) @@ -39,8 +59,8 @@ module Mal end def get(key) - e = find(key) - raise EvalException.new "#{key} not found" unless e + e = find key + eval_error "'#{key}' not found" unless e e.data[key] end end