A fork of Crisp for HARP
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.6 KiB

  1. require "./expr"
  2. require "./error"
  3. module Crisp
  4. class Env
  5. property data
  6. def initialize(@outer : Env? = nil)
  7. @data = {} of String => Crisp::Expr
  8. end
  9. def initialize(@outer, binds, exprs : Array(Crisp::Expr))
  10. @data = {} of String => Crisp::Expr
  11. Crisp.eval_error "binds must be list or vector" unless binds.is_a? Array
  12. # Note:
  13. # Array#zip() can't be used because overload resolution failed
  14. (0...binds.size).each do |idx|
  15. sym = binds[idx].unwrap
  16. Crisp.eval_error "bind name must be symbol" unless sym.is_a? Crisp::Symbol
  17. if sym.str == "&"
  18. Crisp.eval_error "missing variable parameter name" if binds.size == idx
  19. next_param = binds[idx+1].unwrap
  20. Crisp.eval_error "bind name must be symbol" unless next_param.is_a? Crisp::Symbol
  21. var_args = Crisp::List.new
  22. exprs[idx..-1].each{|e| var_args << e} if idx < exprs.size
  23. @data[next_param.str] = Crisp::Expr.new var_args
  24. break
  25. end
  26. @data[sym.str] = exprs[idx]
  27. end
  28. end
  29. def dump
  30. puts "ENV BEGIN".colorize.red
  31. @data.each do |k, v|
  32. puts " #{k} -> #{print(v)}".colorize.red
  33. end
  34. puts "ENV END".colorize.red
  35. end
  36. def set(key, value)
  37. @data[key] = value
  38. end
  39. def find(key)
  40. return self if @data.has_key? key
  41. if o = @outer
  42. o.find key
  43. else
  44. nil
  45. end
  46. end
  47. def get(key)
  48. e = find key
  49. Crisp.eval_error "'#{key}' not found" unless e
  50. e.data[key]
  51. end
  52. end
  53. end