00001 #include <map> 00002 00003 #include "calc_error.hpp" 00004 #include "node.hpp" 00005 #include "variables.hpp" 00006 00007 namespace { 00008 symbol_table variables; 00009 std::vector<symbol_table const*> symbol_tables; 00010 00011 class initializer { 00012 public: 00013 initializer() { 00014 variables["pi"] = node(3.141592653589792); 00015 variables["e"] = node(2.718281828459); 00016 symbol_tables.push_back(&variables); 00017 } 00018 }; 00019 initializer init; 00020 } 00021 00022 set_symbol_table::set_symbol_table(symbol_table const& locals) 00023 { 00024 symbol_tables.push_back(&locals); 00025 } 00026 00027 set_symbol_table::~set_symbol_table() 00028 { 00029 symbol_tables.pop_back(); 00030 } 00031 00032 bool find_symbol(std::string const& name, node& value) 00033 { 00034 for (std::vector<symbol_table const*>::reverse_iterator iter(symbol_tables.rbegin()); iter != symbol_tables.rend(); ++iter) { 00035 symbol_table const& table( **iter ); 00036 symbol_table::const_iterator entry = table.find(name); 00037 if (entry != table.end()) { 00038 value = entry->second; 00039 return true; 00040 } 00041 } 00042 return false; 00043 } 00044 00045 node get_variable(std::string const& name) 00046 { 00047 node result; 00048 if (not find_symbol(name, result)) 00049 return node(); 00050 else if (result.get_parameters().empty()) 00051 return result; 00052 else 00053 throw function_error(name, result.get_parameters().size(), 0); 00054 } 00055 00056 void set_variable(std::string const& name, node value) 00057 { 00058 variables[name] = value; 00059 } 00060 00061 node get_function(std::string const& name) 00062 { 00063 node result; 00064 if (not find_symbol(name, result)) 00065 throw no_such_function(name); 00066 else 00067 return result; 00068 } 00069 00070 void set_function(std::string const& name, node value) 00071 { 00072 set_variable(name, value); 00073 }