Merge branch 'master' into ChaiScript_5_0_CPP_11

Conflicts:
	include/chaiscript/dispatchkit/bootstrap_stl.hpp
This commit is contained in:
Jason Turner
2012-11-07 13:47:09 -07:00
6 changed files with 298 additions and 21 deletions

View File

@@ -13,7 +13,7 @@ list(APPEND CPACK_SOURCE_IGNORE_FILES ".swp")
list(APPEND CPACK_SOURCE_IGNORE_FILES ".*~") list(APPEND CPACK_SOURCE_IGNORE_FILES ".*~")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.txt") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme.md")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description.txt")
set(CPACK_PACKAGE_VERSION_MAJOR 5) set(CPACK_PACKAGE_VERSION_MAJOR 5)

View File

@@ -443,6 +443,7 @@ namespace chaiscript
bootstrap_pod_type<long double>("long_double", m); bootstrap_pod_type<long double>("long_double", m);
bootstrap_pod_type<float>("float", m); bootstrap_pod_type<float>("float", m);
bootstrap_pod_type<int>("int", m); bootstrap_pod_type<int>("int", m);
bootstrap_pod_type<long>("long", m);
bootstrap_pod_type<unsigned int>("unsigned_int", m); bootstrap_pod_type<unsigned int>("unsigned_int", m);
bootstrap_pod_type<unsigned long>("unsigned_long", m); bootstrap_pod_type<unsigned long>("unsigned_long", m);
bootstrap_pod_type<size_t>("size_t", m); bootstrap_pod_type<size_t>("size_t", m);

View File

@@ -148,6 +148,96 @@ namespace chaiscript
}; };
namespace detail { namespace detail {
template<typename T>
int return_int_impl(const std::function<typename T::size_type (const T *)> &t_func, const T *t_obj)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4267)
#endif
return t_func(t_obj);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<typename T>
std::function<int (const T *)> return_int(size_t (T::*t_func)() const)
{
return std::bind(&return_int_impl<T>, std::function<size_t (const T *)>(std::mem_fn(t_func)), std::placeholders::_1);
}
template<typename T, typename P1>
int return_int_impl(const std::function<typename T::size_type (const T *, P1)> &t_func, const T *t_obj, P1 p1)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4267)
#endif
return t_func(t_obj, p1);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<typename T, typename P1>
int return_int_impl_non_const(const std::function<typename T::size_type (T *, P1)> &t_func, T *t_obj, P1 p1)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4267)
#endif
return t_func(t_obj, p1);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<typename T, typename P1>
std::function<int (const T *, P1)> return_int(size_t (T::*t_func)(P1) const)
{
return std::bind(&return_int_impl<T, P1>, std::function<size_t (const T *, P1)>(std::mem_fn(t_func)), std::placeholders::_1, std::placeholders::_2);
}
template<typename T, typename P1>
std::function<int (T *, P1)> return_int(size_t (T::*t_func)(P1) )
{
return std::bind(&return_int_impl_non_const<T, P1>, std::function<size_t (T*, P1)>(std::mem_fn(t_func)), std::placeholders::_1, std::placeholders::_2);
}
template<typename T, typename P1, typename P2>
int return_int_impl(const std::function<typename T::size_type (const T *, P1, P2)> &t_func, const T *t_obj, P1 p1, P2 p2)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4267)
#endif
return t_func(t_obj, p1, p2);
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template<typename T, typename P1, typename P2>
std::function<int (const T *, P1, P2)> return_int(size_t (T::*t_func)(P1, P2) const)
{
return std::bind(&return_int_impl<T, P1, P2>, std::function<size_t (const T *, P1, P2)>(std::mem_fn(t_func)), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
}
template<typename T>
void insert(T &t_target, const T &t_other)
{
t_target.insert(t_other.begin(), t_other.end());
}
template<typename T>
void insert_ref(T &t_target, const typename T::value_type &t_val)
{
t_target.insert(t_val);
}
/** /**
* Add Bidir_Range support for the given ContainerType * Add Bidir_Range support for the given ContainerType
@@ -393,6 +483,23 @@ namespace chaiscript
{ {
m->add(fun<int (const ContainerType *, const typename ContainerType::key_type &)>(&ContainerType::count), "count"); m->add(fun<int (const ContainerType *, const typename ContainerType::key_type &)>(&ContainerType::count), "count");
typedef size_t (ContainerType::*erase)(const typename ContainerType::key_type &);
erase eraseptr(&ContainerType::erase);
m->add(fun(std::function<int (ContainerType *, const typename ContainerType::key_type &)>(detail::return_int(eraseptr))), "erase");
m->add(fun(&detail::insert<ContainerType>), "insert");
std::string insert_name;
if (typeid(typename ContainerType::mapped_type) == typeid(Boxed_Value))
{
insert_name = "insert_ref";
} else {
insert_name = "insert";
}
m->add(fun(&detail::insert_ref<ContainerType>), insert_name);
return m; return m;
} }

View File

@@ -104,6 +104,9 @@ namespace chaiscript
Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(const_var(int(atoi(t_ast_node_text.c_str())))) { } m_value(const_var(int(atoi(t_ast_node_text.c_str())))) { }
Int_AST_Node(const std::string &t_ast_node_text = "", const Boxed_Value &t_bv = const_var(0), int t_id = AST_Node_Type::Int, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(t_bv) { }
virtual ~Int_AST_Node() {} virtual ~Int_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){ virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
return m_value; return m_value;
@@ -119,6 +122,9 @@ namespace chaiscript
Float_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Float, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : Float_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Float, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(const_var(double(atof(t_ast_node_text.c_str())))) { } m_value(const_var(double(atof(t_ast_node_text.c_str())))) { }
Float_AST_Node(const std::string &t_ast_node_text = "", const Boxed_Value &t_bv = const_var(0), int t_id = AST_Node_Type::Float, const std::shared_ptr<std::string> &t_fname=std::shared_ptr<std::string>(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) :
AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col),
m_value(t_bv) { }
virtual ~Float_AST_Node() {} virtual ~Float_AST_Node() {}
virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){ virtual Boxed_Value eval_internal(chaiscript::detail::Dispatch_Engine &){
return m_value; return m_value;

View File

@@ -33,6 +33,8 @@ namespace chaiscript
, bin_alphabet , bin_alphabet
, id_alphabet , id_alphabet
, white_alphabet , white_alphabet
, int_suffix_alphabet
, float_suffix_alphabet
, max_alphabet , max_alphabet
, lengthof_alphabet = 256 , lengthof_alphabet = 256
}; };
@@ -175,6 +177,17 @@ namespace chaiscript
m_alphabet[detail::white_alphabet][static_cast<int>(' ')]=true; m_alphabet[detail::white_alphabet][static_cast<int>(' ')]=true;
m_alphabet[detail::white_alphabet][static_cast<int>('\t')]=true; m_alphabet[detail::white_alphabet][static_cast<int>('\t')]=true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('l')] = true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('L')] = true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('u')] = true;
m_alphabet[detail::int_suffix_alphabet][static_cast<int>('U')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('l')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('L')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('f')] = true;
m_alphabet[detail::float_suffix_alphabet][static_cast<int>('F')] = true;
} }
/** /**
@@ -343,6 +356,12 @@ namespace chaiscript
++m_input_pos; ++m_input_pos;
++m_col; ++m_col;
} }
while (has_more_input() && char_in_alphabet(*m_input_pos, detail::float_suffix_alphabet))
{
++m_input_pos;
++m_col;
}
} }
else { else {
--m_input_pos; --m_input_pos;
@@ -371,6 +390,11 @@ namespace chaiscript
++m_input_pos; ++m_input_pos;
++m_col; ++m_col;
} }
while (has_more_input() && char_in_alphabet(*m_input_pos, detail::int_suffix_alphabet))
{
++m_input_pos;
++m_col;
}
} }
else { else {
--m_input_pos; --m_input_pos;
@@ -386,6 +410,14 @@ namespace chaiscript
return retval; return retval;
} }
void IntSuffix_() {
while (has_more_input() && char_in_alphabet(*m_input_pos, detail::int_suffix_alphabet))
{
++m_input_pos;
++m_col;
}
}
/** /**
* Reads a binary value from input, without skipping initial whitespace * Reads a binary value from input, without skipping initial whitespace
*/ */
@@ -419,6 +451,110 @@ namespace chaiscript
return retval; return retval;
} }
Boxed_Value buildFloat(const std::string &t_val)
{
bool float_ = false;
bool long_ = false;
size_t i = t_val.size();
for (; i > 0; --i)
{
char val = t_val[i-1];
if (val == 'f' || val == 'F')
{
float_ = true;
} else if (val == 'l' || val == 'L') {
long_ = true;
} else {
break;
}
}
std::stringstream ss(t_val.substr(0, i));
if (float_)
{
float f;
ss >> f;
return Boxed_Value(const_var(f));
} else if (long_) {
long double f;
ss >> f;
return Boxed_Value(const_var(f));
} else {
double f;
ss >> f;
return Boxed_Value(const_var(f));
}
}
template<typename IntType>
Boxed_Value buildInt(const IntType &t_type, const std::string &t_val)
{
bool unsigned_ = false;
bool long_ = false;
bool longlong_ = false;
size_t i = t_val.size();
for (; i > 0; --i)
{
char val = t_val[i-1];
if (val == 'u' || val == 'U')
{
unsigned_ = true;
} else if (val == 'l' || val == 'L') {
if (long_)
{
longlong_ = true;
}
long_ = true;
} else {
break;
}
}
std::stringstream ss(t_val.substr(0, i));
ss >> t_type;
if (unsigned_)
{
if (longlong_)
{
uint64_t val;
ss >> val;
return Boxed_Value(const_var(val));
} else if (long_) {
unsigned long val;
ss >> val;
return Boxed_Value(const_var(val));
} else {
unsigned int val;
ss >> val;
return Boxed_Value(const_var(val));
}
} else {
if (longlong_)
{
int64_t val;
ss >> val;
return Boxed_Value(const_var(val));
} else if (long_) {
long val;
ss >> val;
return Boxed_Value(const_var(val));
} else {
int val;
ss >> val;
return Boxed_Value(const_var(val));
}
}
}
/** /**
* Reads a number from the input, detecting if it's an integer or floating point * Reads a number from the input, detecting if it's an integer or floating point
*/ */
@@ -435,19 +571,14 @@ namespace chaiscript
if (has_more_input() && char_in_alphabet(*m_input_pos, detail::float_alphabet) ) { if (has_more_input() && char_in_alphabet(*m_input_pos, detail::float_alphabet) ) {
if (Hex_()) { if (Hex_()) {
std::string match(start, m_input_pos); std::string match(start, m_input_pos);
std::stringstream ss(match); Boxed_Value i = buildInt(std::hex, match);
unsigned int temp_int; AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
ss >> std::hex >> temp_int;
std::ostringstream out_int;
out_int << static_cast<int>(temp_int);
AST_NodePtr t(new eval::Int_AST_Node(out_int.str(), AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
m_match_stack.push_back(t); m_match_stack.push_back(t);
return true; return true;
} }
if (Binary_()) { if (Binary_()) {
std::string match(start, m_input_pos); std::string match(start, m_input_pos);
int temp_int = 0; int64_t temp_int = 0;
size_t pos = 0, end = match.length(); size_t pos = 0, end = match.length();
while ((pos < end) && (pos < (2 + sizeof(int) * 8))) { while ((pos < end) && (pos < (2 + sizeof(int) * 8))) {
@@ -458,32 +589,36 @@ namespace chaiscript
++pos; ++pos;
} }
std::ostringstream out_int; Boxed_Value i;
out_int << temp_int; if (match.length() <= sizeof(int) * 8)
AST_NodePtr t(new eval::Int_AST_Node(out_int.str(), AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col)); {
i = Boxed_Value(const_var(int(temp_int)));
} else {
i = Boxed_Value(const_var(temp_int));
}
AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
m_match_stack.push_back(t); m_match_stack.push_back(t);
return true; return true;
} }
if (Float_()) { if (Float_()) {
std::string match(start, m_input_pos); std::string match(start, m_input_pos);
AST_NodePtr t(new eval::Float_AST_Node(match, AST_Node_Type::Float, m_filename, prev_line, prev_col, m_line, m_col)); Boxed_Value f = buildFloat(match);
AST_NodePtr t(new eval::Float_AST_Node(match, f, AST_Node_Type::Float, m_filename, prev_line, prev_col, m_line, m_col));
m_match_stack.push_back(t); m_match_stack.push_back(t);
return true; return true;
} }
else { else {
IntSuffix_();
std::string match(start, m_input_pos); std::string match(start, m_input_pos);
if ((match.size() > 0) && (match[0] == '0')) { if ((match.size() > 0) && (match[0] == '0')) {
std::stringstream ss(match); Boxed_Value i = buildInt(std::oct, match);
unsigned int temp_int; AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
ss >> std::oct >> temp_int;
std::ostringstream out_int;
out_int << int(temp_int);
AST_NodePtr t(new eval::Int_AST_Node(out_int.str(), AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
m_match_stack.push_back(t); m_match_stack.push_back(t);
} }
else { else {
AST_NodePtr t(new eval::Int_AST_Node(match, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col)); Boxed_Value i = buildInt(std::dec, match);
AST_NodePtr t(new eval::Int_AST_Node(match, i, AST_Node_Type::Int, m_filename, prev_line, prev_col, m_line, m_col));
m_match_stack.push_back(t); m_match_stack.push_back(t);
} }
return true; return true;

View File

@@ -1 +1,29 @@
assert_equal([true, false, true], map([1,2,3], odd)) assert_equal([true, false, true], map([1,2,3], odd))
var m = ["a":1, "b":2];
assert_equal(1, m.count("a"))
assert_equal(0, m.count("c"))
assert_equal(1, m.erase("a"))
assert_equal(1, m.size())
assert_equal(0, m.erase("a"))
assert_equal(1, m.size());
var m2 = ["c":3, "b":4]
m.insert(m2);
assert_equal(3, m["c"])
// The inserted values do not overwrite the existing ones
assert_equal(2, m["b"])
assert_equal(2, m.size())
var v = "bob";
m.insert_ref(Map_Pair("d", v))
assert_equal("bob", m["d"])
v = "bob2"
assert_equal("bob2", m["d"])