Merge branch 'develop' of github.com:ChaiScript/ChaiScript into multithreaded_performance

Conflicts:
	include/chaiscript/language/chaiscript_eval.hpp
This commit is contained in:
Jason Turner
2015-07-16 18:12:09 -06:00
12 changed files with 203 additions and 97 deletions

View File

@@ -304,13 +304,17 @@ namespace chaiscript
/// the remaining parameters are the args to bind into the result
static Boxed_Value bind_function(const std::vector<Boxed_Value> &params)
{
if (params.size() < 2)
{
throw exception::arity_error(static_cast<int>(params.size()), 2);
if (params.empty()) {
throw exception::arity_error(0, 1);
}
Const_Proxy_Function f = boxed_cast<Const_Proxy_Function>(params[0]);
if (f->get_arity() != -1 && size_t(f->get_arity()) != params.size() - 1)
{
throw exception::arity_error(static_cast<int>(params.size()), f->get_arity());
}
return Boxed_Value(Const_Proxy_Function(std::make_shared<dispatch::Bound_Function>(std::move(f),
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
}

View File

@@ -22,6 +22,7 @@
#include "../chaiscript_defines.hpp"
#include "../chaiscript_threading.hpp"
#include "bad_boxed_cast.hpp"
#include "boxed_cast.hpp"
#include "boxed_cast_helper.hpp"
#include "boxed_value.hpp"
@@ -906,7 +907,14 @@ namespace chaiscript
std::vector<Boxed_Value> remaining_params{l_params.begin() + l_num_params, l_params.end()};
Boxed_Value bv = dispatch::dispatch(l_funs, attr_params, l_conversions);
if (!remaining_params.empty() || bv.get_type_info().bare_equal(user_type<dispatch::Proxy_Function_Base>())) {
return (*boxed_cast<const dispatch::Proxy_Function_Base *>(bv))(remaining_params, l_conversions);
auto func = boxed_cast<std::shared_ptr<const dispatch::Proxy_Function_Base>>(bv);
try {
return (*func)(remaining_params, l_conversions);
} catch (const chaiscript::exception::bad_boxed_cast &) {
} catch (const chaiscript::exception::arity_error &) {
} catch (const chaiscript::exception::guard_error &) {
}
throw chaiscript::exception::dispatch_error(remaining_params, std::vector<Const_Proxy_Function>{func});
} else {
return bv;
}

View File

@@ -149,7 +149,11 @@ namespace chaiscript
Boxed_Value operator()(const std::vector<Boxed_Value> &params, const chaiscript::Type_Conversions &t_conversions) const
{
return do_call(params, t_conversions);
if (m_arity < 0 || size_t(m_arity) == params.size()) {
return do_call(params, t_conversions);
} else {
throw exception::arity_error(static_cast<int>(params.size()), m_arity);
}
}
/// Returns a vector containing all of the types of the parameters the function returns/takes
@@ -420,18 +424,12 @@ namespace chaiscript
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{
if (m_arity < 0 || params.size() == size_t(m_arity))
if (call_match(params, t_conversions) && test_guard(params, t_conversions))
{
if (call_match(params, t_conversions) && test_guard(params, t_conversions))
{
return m_f(params);
} else {
throw exception::guard_error();
}
return m_f(params);
} else {
throw exception::arity_error(static_cast<int>(params.size()), m_arity);
}
throw exception::guard_error();
}
}
private:
@@ -728,19 +726,14 @@ namespace chaiscript
protected:
virtual Boxed_Value do_call(const std::vector<Boxed_Value> &params, const Type_Conversions &t_conversions) const CHAISCRIPT_OVERRIDE
{
if (params.size() == 1)
const Boxed_Value &bv = params[0];
if (bv.is_const())
{
const Boxed_Value &bv = params[0];
if (bv.is_const())
{
const Class *o = boxed_cast<const Class *>(bv, &t_conversions);
return detail::Handle_Return<const typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
} else {
Class *o = boxed_cast<Class *>(bv, &t_conversions);
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
}
const Class *o = boxed_cast<const Class *>(bv, &t_conversions);
return detail::Handle_Return<const typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
} else {
throw exception::arity_error(static_cast<int>(params.size()), 1);
Class *o = boxed_cast<Class *>(bv, &t_conversions);
return detail::Handle_Return<typename std::add_lvalue_reference<T>::type>::handle(o->*m_attr);
}
}
@@ -787,6 +780,9 @@ namespace chaiscript
const Type_Conversions &t_conversions)
{
const std::vector<Type_Info> &types = t_func->get_param_types();
if (t_func->get_arity() == -1) return false;
assert(plist.size() == types.size() - 1);
return std::mismatch(plist.begin(), plist.end(),

View File

@@ -29,7 +29,7 @@ namespace chaiscript
class Type_Info
{
public:
CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
CHAISCRIPT_CONSTEXPR Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti)
: m_type_info(t_ti), m_bare_type_info(t_bare_ti),
m_is_const(t_is_const), m_is_reference(t_is_reference), m_is_pointer(t_is_pointer),
@@ -38,7 +38,7 @@ namespace chaiscript
{
}
CHAISCRIPT_CONSTEXPR Type_Info()
CHAISCRIPT_CONSTEXPR Type_Info()
: m_type_info(nullptr), m_bare_type_info(nullptr),
m_is_const(false), m_is_reference(false), m_is_pointer(false),
m_is_void(false), m_is_arithmetic(false),
@@ -134,14 +134,14 @@ namespace chaiscript
{
typedef T type;
static Type_Info get()
static Type_Info get()
{
return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value,
std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
(std::is_arithmetic<T>::value || std::is_arithmetic<typename std::remove_reference<T>::type>::value)
&& !std::is_same<typename std::remove_const<T>::type, bool>::value,
&typeid(T),
&& !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
&typeid(T),
&typeid(typename Bare_Type<T>::type));
}
};
@@ -151,11 +151,11 @@ namespace chaiscript
{
typedef T type;
static Type_Info get()
static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
&typeid(std::shared_ptr<T> ),
&typeid(typename Bare_Type<T>::type));
}
@@ -166,11 +166,11 @@ namespace chaiscript
{
typedef T type;
static Type_Info get()
static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
&typeid(const std::shared_ptr<T> &),
&typeid(typename Bare_Type<T>::type));
}
@@ -181,11 +181,11 @@ namespace chaiscript
{
typedef T type;
static Type_Info get()
static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
&typeid(std::reference_wrapper<T> ),
&typeid(typename Bare_Type<T>::type));
}
@@ -196,11 +196,11 @@ namespace chaiscript
{
typedef T type;
static Type_Info get()
static Type_Info get()
{
return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value,
std::is_void<T>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<T>::type, bool>::value,
std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
&typeid(const std::reference_wrapper<T> &),
&typeid(typename Bare_Type<T>::type));
}

View File

@@ -276,10 +276,13 @@ namespace chaiscript
template<typename T>
static std::string format_location(const T &t)
{
std::ostringstream oss;
oss << "(" << t->filename() << " " << t->start().line << ", " << t->start().column << ")";
return oss.str();
if (t) {
std::ostringstream oss;
oss << "(" << t->filename() << " " << t->start().line << ", " << t->start().column << ")";
return oss.str();
} else {
return "(internal)";
}
}

View File

@@ -1120,11 +1120,22 @@ namespace chaiscript
AST_Node(std::move(t_ast_node_text), AST_Node_Type::File, std::move(t_loc), std::move(t_children)) { }
virtual ~File_AST_Node() {}
virtual Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const CHAISCRIPT_OVERRIDE {
const auto num_children = children.size();
for (size_t i = 0; i < num_children-1; ++i) {
children[i]->eval(t_ss);
try {
const auto num_children = children.size();
if (num_children > 0) {
for (size_t i = 0; i < num_children-1; ++i) {
children[i]->eval(t_ss);
}
return children.back()->eval(t_ss);
} else {
return Boxed_Value();
}
} catch (const detail::Continue_Loop &) {
throw exception::eval_error("Unexpected `continue` statement outside of a loop");
} catch (const detail::Break_Loop &) {
throw exception::eval_error("Unexpected `break` statement outside of a loop");
}
return children.back()->eval(t_ss);
}
};
@@ -1161,7 +1172,7 @@ namespace chaiscript
try {
// short circuit arithmetic operations
if (m_oper != Operators::invalid && bv.get_type_info().is_arithmetic())
if (m_oper != Operators::invalid && m_oper != Operators::bitwise_and && bv.get_type_info().is_arithmetic())
{
return Boxed_Number::do_oper(m_oper, bv);
} else {

View File

@@ -194,6 +194,7 @@ namespace chaiscript
/// Returns the front-most AST node
AST_NodePtr ast() const {
if (m_match_stack.empty()) throw exception::eval_error("Attempted to access AST of failed parse.");
return m_match_stack.front();
}
@@ -261,7 +262,7 @@ namespace chaiscript
}
AST_NodePtr optimized_ast(bool t_optimize_blocks = false, bool t_optimize_returns = true) {
AST_NodePtr p = m_match_stack.front();
AST_NodePtr p = ast();
//Note, optimize_blocks is currently broken; it breaks stack management
if (t_optimize_blocks) { optimize_blocks(p); }
if (t_optimize_returns) { optimize_returns(p); }
@@ -1208,37 +1209,32 @@ namespace chaiscript
}
/// Reads an end-of-line group from input, without skipping initial whitespace
bool Eol_() {
bool Eol_(const bool t_eos = false) {
bool retval = false;
if (has_more_input() && (Symbol_("\r\n") || Char_('\n'))) {
retval = true;
++m_line;
m_col = 1;
} else if (has_more_input() && Char_(';')) {
} else if (has_more_input() && !t_eos && Char_(';')) {
retval = true;
}
return retval;
}
/// Reads (and potentially captures) an end-of-line group from input
bool Eol(const bool t_capture = false) {
/// Reads until the end of the current statement
bool Eos() {
SkipWS();
if (!t_capture) {
return Eol_();
} else {
const auto start = m_input_pos;
const auto prev_col = m_col;
const auto prev_line = m_line;
if (Eol_()) {
m_match_stack.push_back(make_node<eval::Eol_AST_Node>(std::string(start, m_input_pos), prev_line, prev_col));
return true;
} else {
return false;
}
}
return Eol_(true);
}
/// Reads (and potentially captures) an end-of-line group from input
bool Eol() {
SkipWS();
return Eol_();
}
/// Reads a comma-separated list of values from input. Id's only, no types allowed
@@ -1441,7 +1437,7 @@ namespace chaiscript
}
}
while (Eol()) {}
while (Eos()) {}
if (Char(':')) {
if (!Operator()) {