15 #ifndef OPENSCENARIO_INTERPRETER__SCOPE_HPP_
16 #define OPENSCENARIO_INTERPRETER__SCOPE_HPP_
18 #include <boost/filesystem.hpp>
19 #include <boost/lexical_cast.hpp>
20 #include <boost/range/algorithm.hpp>
27 #include <unordered_map>
37 std::multimap<std::string, Object> variables;
41 std::multimap<std::string, EnvironmentFrame *> inner_frames;
43 std::vector<EnvironmentFrame *> unnamed_inner_frames;
45 #define DEFINE_SYNTAX_ERROR(TYPENAME, ...) \
46 template <typename T> \
47 struct TYPENAME : public SyntaxError \
49 explicit TYPENAME(const std::string & variable) \
50 : SyntaxError(__VA_ARGS__, std::quoted(variable), " of type ", makeTypename(typeid(T)), ".") \
58 #undef DEFINE_SYNTAX_ERROR
60 EnvironmentFrame() =
default;
62 explicit EnvironmentFrame(EnvironmentFrame &,
const std::string &);
75 for (std::vector<const EnvironmentFrame *> frames{
this}; not frames.empty();) {
76 auto objects = [&]() {
77 std::vector<Object> result;
78 for (
auto && frame : frames) {
79 boost::range::for_each(frame->variables.equal_range(name), [&](
auto && name_and_value) {
80 return result.push_back(name_and_value.second);
86 switch (boost::range::count_if(objects,
is_also<T>())) {
89 std::vector<const EnvironmentFrame *> result;
90 for (
auto && current_frame : frames) {
91 boost::range::copy(current_frame->unnamed_inner_frames, std::back_inserter(result));
97 return *boost::range::find_if(objects,
is_also<T>());
99 throw AmbiguousReferenceTo<T>(name);
103 return isOutermost() ?
throw NoSuchVariableNamed<T>(name) : outer_frame->
find<T>(name);
106 template <
typename T>
109 if (not prefixed_name.prefixes.empty()) {
110 const auto found = resolvePrefix(prefixed_name);
111 switch (found.size()) {
113 throw NoSuchVariableNamed<T>(boost::lexical_cast<std::string>(prefixed_name));
115 return found.front()->find<T>(prefixed_name.strip<1>());
117 throw AmbiguousReferenceTo<T>(boost::lexical_cast<std::string>(prefixed_name));
120 return find<T>(prefixed_name.name);
124 template <
typename T>
127 if (prefixed_name.absolute) {
128 return outermostFrame().find<T>(prefixed_name);
129 }
else if (prefixed_name.prefixes.empty()) {
130 return find<T>(prefixed_name.name);
132 return lookupFrame(prefixed_name)->find<T>(prefixed_name.strip<1>());
146 inline namespace syntax
177 struct ScenarioDefinition
179 const Entities * entities =
nullptr;
186 const std::shared_ptr<EnvironmentFrame> frame;
188 const std::shared_ptr<ScenarioDefinition> scenario_definition;
207 auto dirname() const ->
std::
string;
209 template <typename... Ts>
210 auto
ref(Ts &&...
xs) const -> decltype(auto)
212 return frame->ref<
Object>(std::forward<decltype(xs)>(
xs)...);
215 template <
typename T,
typename... Ts>
216 auto ref(Ts &&...
xs)
const -> decltype(
auto)
218 return frame->ref<T>(std::forward<decltype(xs)>(
xs)...).template as<T>();
225 auto local() const noexcept -> const
Scope &;
227 auto local() noexcept ->
Scope &;
229 auto insert(const
Name &, const
Object &) ->
void;
EnvironmentFrame(const EnvironmentFrame &)=delete
auto define(const Name &, const Object &) -> void
Definition: scope.cpp:36
EnvironmentFrame(EnvironmentFrame &&)=delete
auto find(const Prefixed< Name > &prefixed_name) const -> Object
Definition: scope.hpp:107
auto find(const Name &name) const -> Object
Definition: scope.hpp:72
auto isOutermost() const noexcept -> bool
Definition: scope.cpp:41
friend struct Scope
Definition: scope.hpp:35
auto ref(const Prefixed< Name > &prefixed_name) const -> Object
Definition: scope.hpp:125
Definition: scope.hpp:154
auto ref(Ts &&... xs) const -> decltype(auto)
Definition: scope.hpp:216
std::list< Entity > actors
Definition: scope.hpp:193
double seed
Definition: scope.hpp:195
const std::string name
Definition: scope.hpp:191
Scope(const Scope &)=default
Definition: junit5.hpp:25
std::string string
Definition: junit5.hpp:26
#define DEFINE_SYNTAX_ERROR(TYPENAME,...)
Definition: scope.hpp:45
Definition: object.hpp:42
Definition: catalog_locations.hpp:44
Definition: entities.hpp:41
Definition: open_scenario.hpp:40
Definition: scenario_definition.hpp:44