- cur_st = &st;
- ActionMap::iterator j = actions.find(st.keyword);
- if(j==actions.end())
- throw_at(KeyError("Unknown keyword", st.keyword), st.get_location());
- if(j->second)
- {
- try
- {
- j->second->execute(*this, st);
- }
- catch(Exception &e)
- {
- if(!e.where()[0])
- e.at(st.get_location());
- throw;
- }
- }
- cur_st = 0;
+ ActionMap::const_iterator begin = actions.lower_bound(ActionKey(key.keyword, string()));
+ ActionMap::const_iterator end = actions.upper_bound(ActionKey(key.keyword, "~"));
+
+ if(begin==end)
+ throw unknown_keyword(key.keyword);
+
+ for(ActionMap::const_iterator i=begin; i!=end; ++i)
+ if(signature_match(key.signature, i->first.signature))
+ return i->second;
+
+ throw invalid_signature(key.keyword, key.signature);
+}
+
+const string &Loader::get_source() const
+{
+ if(!cur_st)
+ throw logic_error("no current statement");
+ return cur_st->source;
+}
+
+void Loader::error(const string &msg) const
+{
+ if(!cur_st)
+ throw logic_error("!cur_st");
+ throw data_error(cur_st->source, cur_st->line, msg);
+}
+
+
+Loader::ActionKey::ActionKey(const string &k, const string &s):
+ keyword(k),
+ signature(s)
+{ }
+
+bool Loader::ActionKey::operator<(const ActionKey &other) const
+{
+ if(keyword!=other.keyword)
+ return keyword<other.keyword;
+ return signature<other.signature;