Compare commits
16 Commits
Release-2.
...
Release-2.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4457df9ff5 | ||
![]() |
e601de9d18 | ||
![]() |
37b2ac2056 | ||
![]() |
645cdddd70 | ||
![]() |
ac8462fb67 | ||
![]() |
636c55493c | ||
![]() |
e2a2c14c0d | ||
![]() |
c418644a5b | ||
![]() |
fbf8f53e04 | ||
![]() |
a0c6366479 | ||
![]() |
15ffbd200a | ||
![]() |
1c6b2725b3 | ||
![]() |
95c124ca35 | ||
![]() |
1bd73884b2 | ||
![]() |
d3e4af433e | ||
![]() |
9f65303370 |
@@ -528,8 +528,28 @@ namespace chaiscript
|
||||
m->add(fun(&Dynamic_Object::get_attr), "get_attr");
|
||||
m->eval("def Dynamic_Object::clone() { var new_o := Dynamic_Object(this.get_type_name()); for_each(this.get_attrs(), bind(fun(new_o, x) { new_o.get_attr(x.first) = x.second; }, new_o, _) ); return new_o; }");
|
||||
|
||||
m->add(fun(&Boxed_Value::is_undef), "is_undef");
|
||||
m->add(fun(&Boxed_Value::is_null), "is_null");
|
||||
m->add(fun(&Boxed_Value::is_undef), "is_var_undef");
|
||||
m->add(fun(&Boxed_Value::is_null), "is_var_null");
|
||||
m->add(fun(&Boxed_Value::is_const), "is_var_const");
|
||||
m->add(fun(&Boxed_Value::is_ref), "is_var_reference");
|
||||
m->add(fun(&Boxed_Value::is_pointer), "is_var_pointer");
|
||||
m->add(fun(&Boxed_Value::is_type), "is_type");
|
||||
|
||||
m->add(fun(&Boxed_Value::get_type_info), "get_type_info");
|
||||
m->add(user_type<Type_Info>(), "Type_Info");
|
||||
|
||||
|
||||
operators::equal<Type_Info>(m);
|
||||
|
||||
m->add(fun(&Type_Info::is_const), "is_type_const");
|
||||
m->add(fun(&Type_Info::is_reference), "is_type_reference");
|
||||
m->add(fun(&Type_Info::is_void), "is_type_void");
|
||||
m->add(fun(&Type_Info::is_undef), "is_type_undef");
|
||||
m->add(fun(&Type_Info::is_pointer), "is_type_pointer");
|
||||
m->add(fun(&Type_Info::name), "cpp_name");
|
||||
m->add(fun(&Type_Info::bare_name), "cpp_bare_name");
|
||||
m->add(fun(&Type_Info::bare_equal), "bare_equal");
|
||||
|
||||
|
||||
basic_constructors<bool>("bool", m);
|
||||
operators::assign<bool>(m);
|
||||
|
@@ -158,7 +158,7 @@ namespace chaiscript
|
||||
template<typename ContainerType>
|
||||
ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(fun<size_t (ContainerType::*)() const>(&ContainerType::size), "size");
|
||||
m->add(fun(boost::function<int (const ContainerType *)>(&ContainerType::size)), "size");
|
||||
m->add(fun<bool (ContainerType::*)() const>(&ContainerType::empty), "empty");
|
||||
m->add(fun<void (ContainerType::*)()>(&ContainerType::clear), "clear");
|
||||
|
||||
@@ -319,7 +319,8 @@ namespace chaiscript
|
||||
template<typename ContainerType>
|
||||
ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module()))
|
||||
{
|
||||
m->add(fun<size_t (ContainerType::*)(const typename ContainerType::key_type &) const>(&ContainerType::count), "count");
|
||||
// m->add(fun<size_t (ContainerType::*)(const typename ContainerType::key_type &) const>(&ContainerType::count), "count");
|
||||
m->add(fun(boost::function<int (const ContainerType *, const typename ContainerType::key_type &)>(&ContainerType::count)), "count");
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -412,13 +413,16 @@ namespace chaiscript
|
||||
}
|
||||
m->add(fun(&String::push_back), push_back_name);
|
||||
|
||||
typedef typename String::size_type (String::*find_func)(const String &, typename String::size_type) const;
|
||||
m->add(fun(static_cast<find_func>(&String::find)), "find");
|
||||
m->add(fun(static_cast<find_func>(&String::rfind)), "rfind");
|
||||
m->add(fun(static_cast<find_func>(&String::find_first_of)), "find_first_of");
|
||||
m->add(fun(static_cast<find_func>(&String::find_last_of)), "find_last_of");
|
||||
m->add(fun(static_cast<find_func>(&String::find_first_not_of)), "find_first_not_of");
|
||||
m->add(fun(static_cast<find_func>(&String::find_last_not_of)), "find_last_not_of");
|
||||
typedef typename String::size_type (String::*find_func_ptr)(const String &, typename String::size_type) const;
|
||||
|
||||
typedef boost::function<int (const String *, const String &, int)> find_func;
|
||||
|
||||
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find))), "find");
|
||||
m->add(fun(find_func(static_cast<find_func_ptr>(&String::rfind))), "rfind");
|
||||
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_first_of))), "find_first_of");
|
||||
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_last_of))), "find_last_of");
|
||||
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_first_not_of))), "find_first_not_of");
|
||||
m->add(fun(find_func(static_cast<find_func_ptr>(&String::find_last_not_of))), "find_last_not_of");
|
||||
|
||||
return m;
|
||||
}
|
||||
|
@@ -264,6 +264,11 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
void swap(Boxed_Value &rhs)
|
||||
{
|
||||
std::swap(m_data, rhs.m_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the static global Object_Cache
|
||||
*/
|
||||
@@ -293,7 +298,8 @@ namespace chaiscript
|
||||
*/
|
||||
Boxed_Value &operator=(const Boxed_Value &rhs)
|
||||
{
|
||||
m_data = rhs.m_data;
|
||||
Boxed_Value temp(rhs);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -315,6 +321,11 @@ namespace chaiscript
|
||||
return m_data->m_type_info.is_const();
|
||||
}
|
||||
|
||||
bool is_type(const Type_Info &ti) const
|
||||
{
|
||||
return m_data->m_type_info.bare_equal(ti);
|
||||
}
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (m_data->m_is_null)
|
||||
@@ -335,6 +346,12 @@ namespace chaiscript
|
||||
return m_data->m_is_ref;
|
||||
}
|
||||
|
||||
bool is_pointer() const
|
||||
{
|
||||
return !is_ref();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Data> m_data;
|
||||
};
|
||||
@@ -700,7 +717,7 @@ namespace chaiscript
|
||||
{
|
||||
if (!m_isfloat && !r.m_isfloat)
|
||||
{
|
||||
return Boxed_Value(i + r.i);
|
||||
return smart_size(i + r.i);
|
||||
}
|
||||
|
||||
return Boxed_Value(((m_isfloat)?d:i) + ((r.m_isfloat)?r.d:r.i));
|
||||
@@ -710,7 +727,7 @@ namespace chaiscript
|
||||
{
|
||||
if (!m_isfloat && !r.m_isfloat)
|
||||
{
|
||||
return Boxed_Value(i - r.i);
|
||||
return smart_size(i - r.i);
|
||||
}
|
||||
|
||||
return Boxed_Value(((m_isfloat)?d:i) - ((r.m_isfloat)?r.d:r.i));
|
||||
@@ -750,7 +767,7 @@ namespace chaiscript
|
||||
{
|
||||
if (!m_isfloat && !r.m_isfloat)
|
||||
{
|
||||
return Boxed_Value(i / r.i);
|
||||
return smart_size(i / r.i);
|
||||
}
|
||||
|
||||
return Boxed_Value(((m_isfloat)?d:i) / ((r.m_isfloat)?r.d:r.i));
|
||||
@@ -760,7 +777,7 @@ namespace chaiscript
|
||||
{
|
||||
if (!m_isfloat && !r.m_isfloat)
|
||||
{
|
||||
return Boxed_Value(i << r.i);
|
||||
return smart_size(i << r.i);
|
||||
}
|
||||
|
||||
throw bad_boxed_cast("<< only valid for integer types");
|
||||
@@ -771,7 +788,7 @@ namespace chaiscript
|
||||
{
|
||||
if (!m_isfloat && !r.m_isfloat)
|
||||
{
|
||||
return Boxed_Value(i * r.i);
|
||||
return smart_size(i * r.i);
|
||||
}
|
||||
|
||||
return Boxed_Value(((m_isfloat)?d:i) * ((r.m_isfloat)?r.d:r.i));
|
||||
@@ -782,7 +799,7 @@ namespace chaiscript
|
||||
{
|
||||
if (!m_isfloat && !r.m_isfloat)
|
||||
{
|
||||
return Boxed_Value(i % r.i);
|
||||
return smart_size(i % r.i);
|
||||
}
|
||||
|
||||
throw bad_boxed_cast("% only valid for integer types");
|
||||
@@ -792,12 +809,23 @@ namespace chaiscript
|
||||
{
|
||||
if (!m_isfloat && !r.m_isfloat)
|
||||
{
|
||||
return Boxed_Value(i >> r.i);
|
||||
return smart_size(i >> r.i);
|
||||
}
|
||||
|
||||
throw bad_boxed_cast(">> only valid for integer types");
|
||||
}
|
||||
|
||||
Boxed_Value smart_size(boost::int64_t i) const
|
||||
{
|
||||
if (i < std::numeric_limits<int>::min()
|
||||
|| i > std::numeric_limits<int>::max())
|
||||
{
|
||||
return Boxed_Value(i);
|
||||
} else {
|
||||
return Boxed_Value(static_cast<int>(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double d;
|
||||
@@ -874,7 +902,14 @@ namespace chaiscript
|
||||
{
|
||||
return l.get_type_info() == r.get_type_info();
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<> void swap(chaiscript::Boxed_Value &lhs, chaiscript::Boxed_Value &rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -43,6 +43,7 @@ namespace chaiscript
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//Add a bit of chaiscript to eval during module implementation
|
||||
Module &eval(const std::string &str)
|
||||
{
|
||||
@@ -50,6 +51,11 @@ namespace chaiscript
|
||||
return *this;
|
||||
}
|
||||
|
||||
Module &add(const boost::shared_ptr<Module> &m)
|
||||
{
|
||||
m->apply(*this, *this);
|
||||
return *m;
|
||||
}
|
||||
|
||||
template<typename Eval, typename Engine>
|
||||
void apply(Eval &t_eval, Engine &t_engine) const
|
||||
@@ -192,6 +198,14 @@ namespace chaiscript
|
||||
typedef boost::tuples::tuple<std::map<std::string, Boxed_Value>, std::deque<Scope>, bool> StackData;
|
||||
typedef boost::shared_ptr<StackData> Stack;
|
||||
|
||||
struct State
|
||||
{
|
||||
std::multimap<std::string, Proxy_Function> m_functions;
|
||||
std::map<std::string, Boxed_Value> m_global_objects;
|
||||
Type_Name_Map m_types;
|
||||
std::set<std::string> m_reserved_words;
|
||||
};
|
||||
|
||||
Dispatch_Engine()
|
||||
: m_place_holder(boost::shared_ptr<Placeholder_Object>(new Placeholder_Object()))
|
||||
{
|
||||
@@ -268,7 +282,7 @@ namespace chaiscript
|
||||
boost::unique_lock<boost::shared_mutex> l(m_global_object_mutex);
|
||||
#endif
|
||||
|
||||
m_global_objects[name] = obj;
|
||||
m_state.m_global_objects[name] = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,7 +348,7 @@ namespace chaiscript
|
||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||
#endif
|
||||
|
||||
get_function_cache() = m_functions;
|
||||
get_function_cache() = m_state.m_functions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,8 +391,8 @@ namespace chaiscript
|
||||
boost::shared_lock<boost::shared_mutex> l(m_global_object_mutex);
|
||||
#endif
|
||||
|
||||
itr = m_global_objects.find(name);
|
||||
if (itr != m_global_objects.end())
|
||||
itr = m_state.m_global_objects.find(name);
|
||||
if (itr != m_state.m_global_objects.end())
|
||||
{
|
||||
cache[name] = itr->second;
|
||||
return itr->second;
|
||||
@@ -403,11 +417,13 @@ namespace chaiscript
|
||||
*/
|
||||
void add(const Type_Info &ti, const std::string &name)
|
||||
{
|
||||
add_global_const(const_var(ti), name + "_type");
|
||||
|
||||
#ifndef CHAISCRIPT_NO_THREADS
|
||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||
#endif
|
||||
|
||||
m_types.insert(std::make_pair(name, ti));
|
||||
m_state.m_types.insert(std::make_pair(name, ti));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,9 +435,9 @@ namespace chaiscript
|
||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||
#endif
|
||||
|
||||
Type_Name_Map::const_iterator itr = m_types.find(name);
|
||||
Type_Name_Map::const_iterator itr = m_state.m_types.find(name);
|
||||
|
||||
if (itr != m_types.end())
|
||||
if (itr != m_state.m_types.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
@@ -440,8 +456,8 @@ namespace chaiscript
|
||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||
#endif
|
||||
|
||||
for (Type_Name_Map::const_iterator itr = m_types.begin();
|
||||
itr != m_types.end();
|
||||
for (Type_Name_Map::const_iterator itr = m_state.m_types.begin();
|
||||
itr != m_state.m_types.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->second.bare_equal(ti))
|
||||
@@ -462,7 +478,7 @@ namespace chaiscript
|
||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||
#endif
|
||||
|
||||
return std::vector<std::pair<std::string, Type_Info> >(m_types.begin(), m_types.end());
|
||||
return std::vector<std::pair<std::string, Type_Info> >(m_state.m_types.begin(), m_state.m_types.end());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,7 +517,7 @@ namespace chaiscript
|
||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||
#endif
|
||||
|
||||
m_reserved_words.insert(name);
|
||||
m_state.m_reserved_words.insert(name);
|
||||
}
|
||||
|
||||
Boxed_Value call_function(const std::string &t_name, const std::vector<Boxed_Value> ¶ms) const
|
||||
@@ -510,7 +526,27 @@ namespace chaiscript
|
||||
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
||||
= functions.equal_range(t_name);
|
||||
|
||||
return dispatch(range.first, range.second, params);
|
||||
return dispatch(range.first, range.second, params);
|
||||
}
|
||||
|
||||
Boxed_Value call_function(const std::string &t_name) const
|
||||
{
|
||||
return call_function(t_name, std::vector<Boxed_Value>());
|
||||
}
|
||||
|
||||
Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1) const
|
||||
{
|
||||
std::vector<Boxed_Value> params;
|
||||
params.push_back(p1);
|
||||
return call_function(t_name, params);
|
||||
}
|
||||
|
||||
Boxed_Value call_function(const std::string &t_name, const Boxed_Value &p1, const Boxed_Value &p2) const
|
||||
{
|
||||
std::vector<Boxed_Value> params;
|
||||
params.push_back(p1);
|
||||
params.push_back(p2);
|
||||
return call_function(t_name, params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -616,6 +652,26 @@ namespace chaiscript
|
||||
return get_type_name(obj.get_type_info());
|
||||
}
|
||||
|
||||
State get_state()
|
||||
{
|
||||
#ifndef CHAISCRIPT_NO_THREADS
|
||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||
boost::unique_lock<boost::shared_mutex> l2(m_global_object_mutex);
|
||||
#endif
|
||||
|
||||
return m_state;
|
||||
}
|
||||
|
||||
void set_state(const State &t_state)
|
||||
{
|
||||
#ifndef CHAISCRIPT_NO_THREADS
|
||||
boost::unique_lock<boost::shared_mutex> l(m_mutex);
|
||||
boost::unique_lock<boost::shared_mutex> l2(m_global_object_mutex);
|
||||
#endif
|
||||
|
||||
m_state = t_state;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -642,7 +698,7 @@ namespace chaiscript
|
||||
boost::shared_lock<boost::shared_mutex> l(m_mutex);
|
||||
#endif
|
||||
|
||||
if (m_reserved_words.find(name) != m_reserved_words.end())
|
||||
if (m_state.m_reserved_words.find(name) != m_state.m_reserved_words.end())
|
||||
{
|
||||
throw reserved_word_error(name);
|
||||
}
|
||||
@@ -660,7 +716,7 @@ namespace chaiscript
|
||||
#endif
|
||||
|
||||
std::pair<std::multimap<std::string, Proxy_Function >::const_iterator, std::multimap<std::string, Proxy_Function >::const_iterator> range
|
||||
= m_functions.equal_range(t_name);
|
||||
= m_state.m_functions.equal_range(t_name);
|
||||
|
||||
while (range.first != range.second)
|
||||
{
|
||||
@@ -671,7 +727,7 @@ namespace chaiscript
|
||||
++range.first;
|
||||
}
|
||||
|
||||
m_functions.insert(std::make_pair(t_name, f));
|
||||
m_state.m_functions.insert(std::make_pair(t_name, f));
|
||||
get_function_cache().insert(std::make_pair(t_name, f));
|
||||
|
||||
return true;
|
||||
@@ -698,13 +754,9 @@ namespace chaiscript
|
||||
chaiscript::threading::Thread_Storage<Stack_Holder> m_stack_holder;
|
||||
|
||||
|
||||
std::multimap<std::string, Proxy_Function> m_functions;
|
||||
std::map<std::string, Boxed_Value> m_global_objects;
|
||||
State m_state;
|
||||
|
||||
Type_Name_Map m_types;
|
||||
Boxed_Value m_place_holder;
|
||||
|
||||
std::set<std::string> m_reserved_words;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -46,6 +46,16 @@ namespace chaiscript
|
||||
return Boxed_Value(r);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Ret>
|
||||
struct Handle_Return<const Ret &>
|
||||
{
|
||||
static Boxed_Value handle(const Ret &r)
|
||||
{
|
||||
return Boxed_Value(boost::cref(r));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used internally for handling a return value from a Proxy_Function call
|
||||
@@ -57,6 +67,11 @@ namespace chaiscript
|
||||
{
|
||||
return Boxed_Value(boost::ref(r));
|
||||
}
|
||||
|
||||
static Boxed_Value handle(const Ret &r)
|
||||
{
|
||||
return Boxed_Value(boost::cref(r));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "type_info.hpp"
|
||||
#include <string>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include "proxy_functions_detail.hpp"
|
||||
@@ -442,11 +443,10 @@ namespace chaiscript
|
||||
if (bv.is_const())
|
||||
{
|
||||
const Class *o = boxed_cast<const Class *>(bv);
|
||||
return Handle_Return<typename boost::add_const<typename boost::add_reference<T>::type>::type>::handle(o->*m_attr);
|
||||
return Handle_Return<const typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||
} else {
|
||||
Class *o = boxed_cast<Class *>(bv);
|
||||
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||
// return Boxed_Value( boost::ref(o->*m_attr) );
|
||||
}
|
||||
} else {
|
||||
throw arity_error(params.size(), 1);
|
||||
@@ -497,6 +497,11 @@ namespace chaiscript
|
||||
{
|
||||
}
|
||||
|
||||
dispatch_error(bool is_const) throw()
|
||||
: std::runtime_error(std::string("No matching function to dispatch to") + (is_const?", parameter is const":""))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~dispatch_error() throw() {}
|
||||
};
|
||||
|
||||
@@ -527,7 +532,7 @@ namespace chaiscript
|
||||
++begin;
|
||||
}
|
||||
|
||||
throw dispatch_error();
|
||||
throw dispatch_error(plist.empty()?false:plist[0].is_const());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -87,6 +87,17 @@ namespace chaiscript
|
||||
bool is_reference() const { return m_is_reference; }
|
||||
bool is_void() const { return m_is_void; }
|
||||
bool is_undef() const { return m_is_undef || m_bare_type_info == 0; }
|
||||
bool is_pointer() const { return m_is_pointer; }
|
||||
|
||||
std::string name() const
|
||||
{
|
||||
if (m_type_info)
|
||||
{
|
||||
return m_type_info->name();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string bare_name() const
|
||||
{
|
||||
|
@@ -78,17 +78,14 @@ namespace chaiscript
|
||||
};
|
||||
|
||||
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name)
|
||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
||||
m_moduleptr(m_func.m_symbol())
|
||||
{
|
||||
}
|
||||
|
||||
ModulePtr get()
|
||||
{
|
||||
return m_func.m_symbol();
|
||||
}
|
||||
|
||||
DLModule m_dlmodule;
|
||||
DLSym<Create_Module_Func> m_func;
|
||||
ModulePtr m_moduleptr;
|
||||
};
|
||||
#else
|
||||
|
||||
@@ -188,17 +185,14 @@ namespace chaiscript
|
||||
};
|
||||
|
||||
Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
|
||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name)
|
||||
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name),
|
||||
m_moduleptr(m_func.m_symbol());
|
||||
{
|
||||
}
|
||||
|
||||
ModulePtr get()
|
||||
{
|
||||
return m_func.m_symbol();
|
||||
}
|
||||
|
||||
DLModule m_dlmodule;
|
||||
DLSym<Create_Module_Func> m_func;
|
||||
ModulePtr m_moduleptr;
|
||||
};
|
||||
|
||||
#else
|
||||
@@ -229,6 +223,7 @@ namespace chaiscript
|
||||
|
||||
std::set<std::string> loaded_files;
|
||||
std::map<std::string, Loadable_Module_Ptr> loaded_modules;
|
||||
std::set<std::string> active_loaded_modules;
|
||||
|
||||
Eval_Engine engine;
|
||||
|
||||
@@ -339,6 +334,47 @@ namespace chaiscript
|
||||
return *this;
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
std::set<std::string> loaded_files;
|
||||
typename Eval_Engine::State engine_state;
|
||||
std::set<std::string> active_loaded_modules;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a state object that represents the current
|
||||
* set of loaded files, the set of global variables and
|
||||
* the set of initialized functions
|
||||
*/
|
||||
State get_state()
|
||||
{
|
||||
#ifndef CHAISCRIPT_NO_THREADS
|
||||
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
|
||||
boost::shared_lock<boost::shared_mutex> l2(mutex);
|
||||
#endif
|
||||
|
||||
State s;
|
||||
s.loaded_files = loaded_files;
|
||||
s.engine_state = engine.get_state();
|
||||
s.active_loaded_modules = active_loaded_modules;
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state from a saved State object.
|
||||
*/
|
||||
void set_state(const State &t_state)
|
||||
{
|
||||
#ifndef CHAISCRIPT_NO_THREADS
|
||||
boost::lock_guard<boost::recursive_mutex> l(use_mutex);
|
||||
boost::shared_lock<boost::shared_mutex> l2(mutex);
|
||||
#endif
|
||||
|
||||
loaded_files = t_state.loaded_files;
|
||||
active_loaded_modules = t_state.active_loaded_modules;
|
||||
engine.set_state(t_state.engine_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the system: type, function, object
|
||||
*/
|
||||
@@ -402,7 +438,11 @@ namespace chaiscript
|
||||
{
|
||||
Loadable_Module_Ptr lm(new Loadable_Module(t_module_name, t_filename));
|
||||
loaded_modules[t_module_name] = lm;
|
||||
add(lm->get());
|
||||
active_loaded_modules.insert(t_module_name);
|
||||
add(lm->m_moduleptr);
|
||||
} else if (active_loaded_modules.count(t_module_name) == 0) {
|
||||
active_loaded_modules.insert(t_module_name);
|
||||
add(loaded_modules[t_module_name]->m_moduleptr);
|
||||
} else {
|
||||
engine.sync_cache();
|
||||
}
|
||||
@@ -499,6 +539,8 @@ namespace chaiscript
|
||||
engine.add(fun(&Eval_Engine::type_name, boost::ref(engine)), "type_name");
|
||||
engine.add(fun(&Eval_Engine::function_exists, boost::ref(engine)), "function_exists");
|
||||
|
||||
engine.add(fun(&Eval_Engine::get_type_name, boost::ref(engine)), "name");
|
||||
|
||||
|
||||
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_1)(const std::string&);
|
||||
typedef void (ChaiScript_System<Eval_Engine>::*load_mod_2)(const std::string&, const std::string&);
|
||||
|
@@ -42,12 +42,15 @@ namespace chaiscript
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_file(Eval_System &ss, const TokenPtr &node) {
|
||||
Boxed_Value retval;
|
||||
unsigned int i;
|
||||
for (i = 0; i < node->children.size(); ++i) {
|
||||
retval = eval_token(ss, node->children[i]);
|
||||
const unsigned int size = node->children.size();
|
||||
for (unsigned int i = 0; i < size; ++i) {
|
||||
const Boxed_Value &retval = eval_token(ss, node->children[i]);
|
||||
if (i + 1 == size)
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
return Boxed_Value();
|
||||
}
|
||||
|
||||
template <typename Eval_System>
|
||||
@@ -173,16 +176,14 @@ namespace chaiscript
|
||||
try {
|
||||
if (lhs.is_undef())
|
||||
{
|
||||
retval = ss.call_function("clone", Param_List_Builder() << retval);
|
||||
retval = ss.call_function("clone", retval);
|
||||
}
|
||||
Param_List_Builder plb;
|
||||
plb << lhs;
|
||||
plb << retval;
|
||||
|
||||
try {
|
||||
retval = ss.call_function(node->children[i+1]->text, plb);
|
||||
retval = ss.call_function(node->children[i+1]->text, lhs, retval);
|
||||
}
|
||||
catch(const dispatch_error &){
|
||||
throw Eval_Error("Mismatched types in equation", node->children[i+1]);
|
||||
throw Eval_Error(std::string("Mismatched types in equation") + (lhs.is_const()?", lhs is const.":"."), node->children[i+1]);
|
||||
}
|
||||
}
|
||||
catch(const dispatch_error &){
|
||||
@@ -199,11 +200,8 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
else {
|
||||
Param_List_Builder plb;
|
||||
plb << eval_token(ss, node->children[i]);
|
||||
plb << retval;
|
||||
try {
|
||||
retval = ss.call_function(node->children[i+1]->text, plb);
|
||||
retval = ss.call_function(node->children[i+1]->text, eval_token(ss, node->children[i]), retval);
|
||||
}
|
||||
catch(const dispatch_error &){
|
||||
throw Eval_Error("Can not find appropriate '" + node->children[i+1]->text + "'", node->children[i+1]);
|
||||
@@ -251,12 +249,12 @@ namespace chaiscript
|
||||
Boxed_Value eval_logical(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value retval(eval_token(ss, node->children[0]));
|
||||
if (node->children.size() > 1) {
|
||||
for (i = 1; i < node->children.size(); i += 2) {
|
||||
bool lhs;
|
||||
try {
|
||||
lhs = boxed_cast<bool >(retval);
|
||||
lhs = boxed_cast<bool>(retval);
|
||||
}
|
||||
catch (const bad_boxed_cast &) {
|
||||
throw Eval_Error("Condition not boolean", node);
|
||||
@@ -290,18 +288,12 @@ namespace chaiscript
|
||||
unsigned int i;
|
||||
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
if (node->children.size() > 1) {
|
||||
for (i = 1; i < node->children.size(); i += 2) {
|
||||
Param_List_Builder plb;
|
||||
plb << retval;
|
||||
plb << eval_token(ss, node->children[i + 1]);
|
||||
|
||||
try {
|
||||
retval = ss.call_function(node->children[i]->text, plb);
|
||||
}
|
||||
catch(const dispatch_error &){
|
||||
throw Eval_Error("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]);
|
||||
}
|
||||
for (i = 1; i < node->children.size(); i += 2) {
|
||||
try {
|
||||
retval = ss.call_function(node->children[i]->text, retval, eval_token(ss, node->children[i + 1]));
|
||||
}
|
||||
catch(const dispatch_error &){
|
||||
throw Eval_Error("Can not find appropriate '" + node->children[i]->text + "'", node->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,11 +309,8 @@ namespace chaiscript
|
||||
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
for (i = 1; i < node->children.size(); ++i) {
|
||||
Param_List_Builder plb;
|
||||
plb << retval;
|
||||
plb << eval_token(ss, node->children[i]);
|
||||
try {
|
||||
retval = ss.call_function("[]", plb);
|
||||
retval = ss.call_function("[]", retval, eval_token(ss, node->children[i]));
|
||||
}
|
||||
catch(std::out_of_range &) {
|
||||
throw Eval_Error("Out of bounds exception", node);
|
||||
@@ -339,11 +328,8 @@ namespace chaiscript
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_prefix(Eval_System &ss, const TokenPtr &node) {
|
||||
Param_List_Builder plb;
|
||||
plb << eval_token(ss, node->children[1]);
|
||||
|
||||
try {
|
||||
return ss.call_function(node->children[0]->text, plb);
|
||||
return ss.call_function(node->children[0]->text, eval_token(ss, node->children[1]));
|
||||
}
|
||||
catch(std::exception &){
|
||||
throw Eval_Error("Can not find appropriate unary '" + node->children[0]->text + "'", node->children[0]);
|
||||
@@ -358,16 +344,13 @@ namespace chaiscript
|
||||
unsigned int i;
|
||||
|
||||
try {
|
||||
Boxed_Value retval = ss.call_function("Vector", Param_List_Builder());
|
||||
if (node->children.size() > 0) {
|
||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||
try {
|
||||
Boxed_Value tmp = eval_token(ss, node->children[0]->children[i]);
|
||||
ss.call_function("push_back", Param_List_Builder() << retval << tmp);
|
||||
}
|
||||
catch (const dispatch_error &) {
|
||||
throw Eval_Error("Can not find appropriate 'push_back'", node->children[0]->children[i]);
|
||||
}
|
||||
Boxed_Value retval = ss.call_function("Vector");
|
||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||
try {
|
||||
ss.call_function("push_back", retval, eval_token(ss, node->children[0]->children[i]));
|
||||
}
|
||||
catch (const dispatch_error &) {
|
||||
throw Eval_Error("Can not find appropriate 'push_back'", node->children[0]->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,9 +368,9 @@ namespace chaiscript
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_inline_range(Eval_System &ss, const TokenPtr &node) {
|
||||
try {
|
||||
return ss.call_function("generate_range", Param_List_Builder()
|
||||
<< eval_token(ss, node->children[0]->children[0]->children[0])
|
||||
<< eval_token(ss, node->children[0]->children[0]->children[1]));
|
||||
return ss.call_function("generate_range",
|
||||
eval_token(ss, node->children[0]->children[0]->children[0]),
|
||||
eval_token(ss, node->children[0]->children[0]->children[1]));
|
||||
}
|
||||
catch (const dispatch_error &) {
|
||||
throw Eval_Error("Unable to generate range vector", node);
|
||||
@@ -402,12 +385,12 @@ namespace chaiscript
|
||||
unsigned int i;
|
||||
|
||||
try {
|
||||
Boxed_Value retval = ss.call_function("Map", Param_List_Builder());
|
||||
Boxed_Value retval = ss.call_function("Map");
|
||||
for (i = 0; i < node->children[0]->children.size(); ++i) {
|
||||
try {
|
||||
Boxed_Value key = eval_token(ss, node->children[0]->children[i]->children[0]);
|
||||
Boxed_Value slot = ss.call_function("[]", Param_List_Builder() << retval << key);
|
||||
ss.call_function("=", Param_List_Builder() << slot << eval_token(ss, node->children[0]->children[i]->children[1]));
|
||||
Boxed_Value slot
|
||||
= ss.call_function("[]", retval, eval_token(ss, node->children[0]->children[i]->children[0]));
|
||||
ss.call_function("=", slot, eval_token(ss, node->children[0]->children[i]->children[1]));
|
||||
}
|
||||
catch (const dispatch_error &) {
|
||||
throw Eval_Error("Can not find appropriate '=' for map init", node->children[0]->children[i]);
|
||||
@@ -441,7 +424,7 @@ namespace chaiscript
|
||||
|
||||
try {
|
||||
ss.set_stack(new_stack);
|
||||
Boxed_Value retval = (*boxed_cast<Const_Proxy_Function>(fn))(plb);
|
||||
const Boxed_Value &retval = (*boxed_cast<Const_Proxy_Function>(fn))(plb);
|
||||
ss.set_stack(prev_stack);
|
||||
return retval;
|
||||
}
|
||||
@@ -483,8 +466,7 @@ namespace chaiscript
|
||||
Boxed_Value fn = eval_token(ss, node->children[0]);
|
||||
|
||||
try {
|
||||
Boxed_Value retval = (*boxed_cast<Const_Proxy_Function >(fn))(plb);
|
||||
return retval;
|
||||
return (*boxed_cast<Const_Proxy_Function >(fn))(plb);
|
||||
}
|
||||
catch(const dispatch_error &e){
|
||||
throw Eval_Error(std::string(e.what()) + " with function '" + node->children[0]->text + "'", node->children[0]);
|
||||
@@ -513,7 +495,7 @@ namespace chaiscript
|
||||
|
||||
//todo: Please extract a single way of doing function calls between this and eval_fun_call
|
||||
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
Boxed_Value retval(eval_token(ss, node->children[0]));
|
||||
if (node->children.size() > 1) {
|
||||
for (i = 2; i < node->children.size(); i+=2) {
|
||||
Param_List_Builder plb;
|
||||
@@ -570,7 +552,6 @@ namespace chaiscript
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_try(Eval_System &ss, const TokenPtr &node) {
|
||||
Boxed_Value retval;
|
||||
retval = Boxed_Value();
|
||||
|
||||
ss.new_scope();
|
||||
try {
|
||||
@@ -683,6 +664,7 @@ namespace chaiscript
|
||||
ss.pop_scope();
|
||||
throw;
|
||||
}
|
||||
|
||||
if (node->children.back()->identifier == Token_Type::Finally) {
|
||||
retval = eval_token(ss, node->children.back()->children[0]);
|
||||
}
|
||||
@@ -699,35 +681,32 @@ namespace chaiscript
|
||||
Boxed_Value eval_if(Eval_System &ss, const TokenPtr &node) {
|
||||
unsigned int i;
|
||||
|
||||
Boxed_Value retval = eval_token(ss, node->children[0]);
|
||||
bool cond;
|
||||
try {
|
||||
cond = boxed_cast<bool>(retval);
|
||||
cond = boxed_cast<bool>(eval_token(ss, node->children[0]));
|
||||
}
|
||||
catch (const bad_boxed_cast &) {
|
||||
throw Eval_Error("If condition not boolean", node->children[0]);
|
||||
}
|
||||
if (cond) {
|
||||
retval = eval_token(ss, node->children[1]);
|
||||
return eval_token(ss, node->children[1]);
|
||||
}
|
||||
else {
|
||||
if (node->children.size() > 2) {
|
||||
i = 2;
|
||||
while ((!cond) && (i < node->children.size())) {
|
||||
if (node->children[i]->text == "else") {
|
||||
retval = eval_token(ss, node->children[i+1]);
|
||||
cond = true;
|
||||
return eval_token(ss, node->children[i+1]);
|
||||
}
|
||||
else if (node->children[i]->text == "else if") {
|
||||
retval = eval_token(ss, node->children[i+1]);
|
||||
try {
|
||||
cond = boxed_cast<bool>(retval);
|
||||
cond = boxed_cast<bool>(eval_token(ss, node->children[i+1]));
|
||||
}
|
||||
catch (const bad_boxed_cast &) {
|
||||
throw Eval_Error("'else if' condition not boolean", node->children[i+1]);
|
||||
}
|
||||
if (cond) {
|
||||
retval = eval_token(ss, node->children[i+2]);
|
||||
return eval_token(ss, node->children[i+2]);
|
||||
}
|
||||
}
|
||||
i = i + 3;
|
||||
@@ -735,7 +714,7 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
return Boxed_Value(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -980,17 +959,22 @@ namespace chaiscript
|
||||
*/
|
||||
template <typename Eval_System>
|
||||
Boxed_Value eval_block(Eval_System &ss, const TokenPtr &node) {
|
||||
Boxed_Value retval;
|
||||
unsigned int i;
|
||||
unsigned int num_children = node->children.size();
|
||||
|
||||
ss.new_scope();
|
||||
for (i = 0; i < node->children.size(); ++i) {
|
||||
for (i = 0; i < num_children; ++i) {
|
||||
try {
|
||||
retval = eval_token(ss, node->children[i]);
|
||||
const Boxed_Value &retval = eval_token(ss, node->children[i]);
|
||||
|
||||
if (i + 1 == num_children)
|
||||
{
|
||||
ss.pop_scope();
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
catch (const chaiscript::Return_Value &rv) {
|
||||
ss.pop_scope();
|
||||
retval = rv.retval;
|
||||
throw;
|
||||
}
|
||||
catch (...) {
|
||||
@@ -998,9 +982,9 @@ namespace chaiscript
|
||||
throw;
|
||||
}
|
||||
}
|
||||
ss.pop_scope();
|
||||
|
||||
return retval;
|
||||
ss.pop_scope();
|
||||
return Boxed_Value();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -171,7 +171,9 @@ namespace chaiscript
|
||||
}
|
||||
else if (Symbol_(singleline_comment.c_str())) {
|
||||
while (input_pos != input_end) {
|
||||
if (Eol_()) {
|
||||
if (Symbol_("\r\n") || Char_('\n')) {
|
||||
++line;
|
||||
col = 1;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -1584,7 +1586,6 @@ namespace chaiscript
|
||||
if (Operator_Helper(precedence)) {
|
||||
do {
|
||||
if (!Operator(precedence+1)) {
|
||||
std::cout << std::string(input_pos, input_end);
|
||||
throw Eval_Error("Incomplete " + std::string(token_type_to_string(operators[precedence])) + " expression",
|
||||
File_Position(line, col), filename);
|
||||
}
|
||||
|
@@ -282,27 +282,27 @@ def zip(x, y) { \n\
|
||||
}\n\
|
||||
# Returns the position of the second value string in the first value string\n\
|
||||
def string::find(substr) : is_type(substr, "string") { \n\
|
||||
int(find(this, substr, size_t(0))); \n\
|
||||
int(find(this, substr, 0)); \n\
|
||||
} \n\
|
||||
# Returns the position of last match of the second value string in the first value string\n\
|
||||
def string::rfind(substr) : is_type(substr, "string") { \n\
|
||||
int(rfind(this, substr, size_t(-1))); \n\
|
||||
int(rfind(this, substr, -1)); \n\
|
||||
} \n\
|
||||
# Returns the position of the first match of elements in the second value string in the first value string\n\
|
||||
def string::find_first_of(list) : is_type(list, "string") { \n\
|
||||
int(find_first_of(this, list, size_t(0))); \n\
|
||||
int(find_first_of(this, list, 0)); \n\
|
||||
} \n\
|
||||
# Returns the position of the last match of elements in the second value string in the first value string\n\
|
||||
def string::find_last_of(list) : is_type(list, "string") { \n\
|
||||
int(find_last_of(this, list, size_t(-1))); \n\
|
||||
int(find_last_of(this, list, -1)); \n\
|
||||
} \n\
|
||||
# Returns the position of the first non-matching element in the second value string in the first value string\n\
|
||||
def string::find_first_not_of(list) : is_type(list, "string") { \n\
|
||||
int(find_first_not_of(this, list, size_t(0))); \n\
|
||||
int(find_first_not_of(this, list, 0)); \n\
|
||||
} \n\
|
||||
# Returns the position of the last non-matching element in the second value string in the first value string\n\
|
||||
def string::find_last_not_of(list) : is_type(list, "string") { \n\
|
||||
int(find_last_not_of(this, list, size_t(-1))); \n\
|
||||
int(find_last_not_of(this, list, -1)); \n\
|
||||
} \n\
|
||||
def string::ltrim() { \n\
|
||||
drop_while(this, fun(x) { x == ' ' || x == '\t' }); \n\
|
||||
|
@@ -1,3 +1,2 @@
|
||||
var i = 1
|
||||
var j = eval("5 + 4")
|
||||
print(j)
|
||||
|
@@ -2,11 +2,11 @@ for (var i = 0; i < 10; ++i) {
|
||||
print(i)
|
||||
}
|
||||
|
||||
for (i = 10; i >= 0; i -= 2) {
|
||||
for (var i = 10; i >= 0; i -= 2) {
|
||||
print(i)
|
||||
}
|
||||
|
||||
i = 0
|
||||
var i = 0
|
||||
|
||||
for (; i < 5; ++i) {
|
||||
print(i)
|
||||
|
7
unittests/classification.chai
Normal file
7
unittests/classification.chai
Normal file
@@ -0,0 +1,7 @@
|
||||
print(1.is_var_const());
|
||||
print(1.is_var_reference());
|
||||
print(1.is_var_pointer());
|
||||
print(1.is_var_null());
|
||||
print(1.is_var_undef());
|
||||
var i;
|
||||
print(i.is_var_undef());
|
6
unittests/classification.txt
Normal file
6
unittests/classification.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
true
|
||||
false
|
||||
true
|
||||
false
|
||||
false
|
||||
true
|
@@ -1 +1 @@
|
||||
Error: "Mismatched types in equation" in 'unittests/invalid_function_assignment.chai' at (1, 7)
|
||||
Error: "Mismatched types in equation, lhs is const." in 'unittests/invalid_function_assignment.chai' at (1, 7)
|
||||
|
@@ -1 +1 @@
|
||||
Error: "Mismatched types in equation" in 'unittests/invalid_function_reassignment.chai' at (2, 3)
|
||||
Error: "Mismatched types in equation." in 'unittests/invalid_function_reassignment.chai' at (2, 3)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
var i;
|
||||
print(i.is_undef());
|
||||
print(i.is_var_undef());
|
||||
i = 5;
|
||||
print(i.is_undef());
|
||||
print(i.is_var_undef());
|
||||
|
10
unittests/type_info.chai
Normal file
10
unittests/type_info.chai
Normal file
@@ -0,0 +1,10 @@
|
||||
print(string_type.name());
|
||||
print(string_type.is_type_const());
|
||||
print(string_type.is_type_reference());
|
||||
print(string_type.is_type_void());
|
||||
print(string_type.is_type_undef());
|
||||
print(string_type.is_type_pointer());
|
||||
print("string".get_type_info().name());
|
||||
print(string_type.bare_equal("string".get_type_info()));
|
||||
|
||||
print("bob".is_type(string_type));
|
9
unittests/type_info.txt
Normal file
9
unittests/type_info.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
string
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
false
|
||||
string
|
||||
true
|
||||
true
|
Reference in New Issue
Block a user