Missed env.h
[lispp.git] / env.h
blob802dc5013276dd06a28111457d2e6cce9fc77ee5
1 #ifndef ENV_H
2 #define ENV_H
5 /** This is where symbols live - essentially a hash table of name:value mapping a symbol name to a variable value */
6 namespace lisp {
9 /** Equality predicate for an atom */
10 struct iequal_to
11 : std::binary_function<boost::shared_ptr<const atom>, boost::shared_ptr<const atom>, bool> {
12 bool operator()(boost::shared_ptr<const atom> ax,
13 boost::shared_ptr<const atom> ay) const {
14 std::string const& x(ax->name);
15 std::string const& y(ay->name);
16 return boost::algorithm::iequals(x, y, std::locale());
20 /** Hash function for an atom **/
21 struct ihash
22 : std::unary_function<std::string, std::size_t> {
23 std::size_t operator()(boost::shared_ptr<const atom> ax) const {
24 std::string const& x(ax->name);
25 std::size_t seed = 0;
26 std::locale locale;
27 for (std::string::const_iterator it = x.begin();
28 it != x.end(); ++it) {
29 boost::hash_combine(seed, std::toupper(*it, locale));
31 return seed;
36 /** The environment proper */
37 class environment {
38 private:
39 typedef boost::unordered_map<boost::shared_ptr<const atom>, boost::shared_ptr<symbol>, ihash, iequal_to> environment_type;
41 environment_type env_map;
42 boost::shared_ptr<environment> parent;
44 public:
46 /** Default constructor for root environment */
47 environment() : parent() {
50 /**
51 * Main construtor for further outer environments
52 * @param inner inner environment that this encloses
54 environment(boost::shared_ptr<environment> inner) : parent(inner) {
57 /**
58 * Variable assignment
59 * @param a Atom representing name of symbol to assign to
60 * @param s Symbol we assign to the atom in this environment
62 void set(boost::shared_ptr<const atom> a, boost::shared_ptr<symbol> s) {
63 env_map[a] = s;
66 /**
67 * Variable access
68 * @param a Atom represnting name of symbol to access
69 * @return Symbol in environment or nil if none found
71 boost::shared_ptr<symbol> get(boost::shared_ptr<const atom> a) const {
72 environment_type::const_iterator lookup(env_map.find(a));
73 if (lookup == env_map.end()) {
74 if (parent != NULL) {
75 return parent->get(a);
76 } else {
77 return boost::shared_ptr<symbol>(new symbol(nil));
79 } else {
80 return lookup->second;
86 #endif