A fork of Crisp for HARP
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

67 lignes
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