Merge branch 'develop' into develop

This commit is contained in:
Jason Turner 2017-11-21 13:54:54 -07:00 committed by GitHub
commit e97d3723df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 93 additions and 26 deletions

View File

@ -521,6 +521,10 @@ namespace chaiscript
validate_boxed_number(bv); validate_boxed_number(bv);
} }
static Boxed_Value clone(const Boxed_Value &t_bv) {
return Boxed_Number(t_bv).get_as(t_bv.get_type_info()).bv;
}
static bool is_floating_point(const Boxed_Value &t_bv) static bool is_floating_point(const Boxed_Value &t_bv)
{ {
const Type_Info &inp_ = t_bv.get_type_info(); const Type_Info &inp_ = t_bv.get_type_info();

View File

@ -62,7 +62,7 @@ namespace chaiscript
/// Types of AST nodes available to the parser and eval /// Types of AST nodes available to the parser and eval
enum class AST_Node_Type { Id, Fun_Call, Unused_Return_Fun_Call, Arg_List, Equation, Var_Decl, enum class AST_Node_Type { Id, Fun_Call, Unused_Return_Fun_Call, Arg_List, Equation, Var_Decl, Assign_Decl,
Array_Call, Dot_Access, Array_Call, Dot_Access,
Lambda, Block, Scopeless_Block, Def, While, If, For, Ranged_For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Lambda, Block, Scopeless_Block, Def, While, If, For, Ranged_For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
Inline_Range, Try, Catch, Finally, Method, Attr_Decl, Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
@ -77,7 +77,7 @@ namespace chaiscript
{ {
/// Helper lookup to get the name of each node type /// Helper lookup to get the name of each node type
inline const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { inline const char *ast_node_type_to_string(AST_Node_Type ast_node_type) {
static const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", static const char * const ast_node_types[] = { "Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", "Assign_Decl",
"Array_Call", "Dot_Access", "Array_Call", "Dot_Access",
"Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",

View File

@ -88,6 +88,23 @@ namespace chaiscript
return std::move(rv.retval); return std::move(rv.retval);
} }
} }
inline Boxed_Value clone_if_necessary(Boxed_Value incoming, std::atomic_uint_fast32_t &t_loc, const chaiscript::detail::Dispatch_State &t_ss)
{
if (!incoming.is_return_value())
{
if (incoming.get_type_info().is_arithmetic()) {
return Boxed_Number::clone(incoming);
} else if (incoming.get_type_info().bare_equal_type_info(typeid(bool))) {
return Boxed_Value(*static_cast<const bool*>(incoming.get_const_ptr()));
} else {
return t_ss->call_function("clone", t_loc, {incoming}, t_ss.conversions());
}
} else {
incoming.reset_return_value();
return incoming;
}
}
} }
template<typename T> template<typename T>
@ -459,11 +476,7 @@ namespace chaiscript
lhs.reset_return_value(); lhs.reset_return_value();
return rhs; return rhs;
} else { } else {
if (!rhs.is_return_value()) rhs = detail::clone_if_necessary(std::move(rhs), m_clone_loc, t_ss);
{
rhs = t_ss->call_function("clone", m_clone_loc, {rhs}, t_ss.conversions());
}
rhs.reset_return_value();
} }
} }
@ -542,6 +555,27 @@ namespace chaiscript
} }
}; };
template<typename T>
struct Assign_Decl_AST_Node final : AST_Node_Impl<T> {
Assign_Decl_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector<AST_Node_Impl_Ptr<T>> t_children) :
AST_Node_Impl<T>(std::move(t_ast_node_text), AST_Node_Type::Assign_Decl, std::move(t_loc), std::move(t_children)) { }
Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override {
const std::string &idname = this->children[0]->text;
try {
Boxed_Value bv(detail::clone_if_necessary(this->children[1]->eval(t_ss), m_loc, t_ss));
bv.reset_return_value();
t_ss.add_object(idname, bv);
return bv;
} catch (const exception::name_conflict_error &e) {
throw exception::eval_error("Variable redefined '" + e.name() + "'");
}
}
private:
mutable std::atomic_uint_fast32_t m_loc = {0};
};
template<typename T> template<typename T>
struct Array_Call_AST_Node final : AST_Node_Impl<T> { struct Array_Call_AST_Node final : AST_Node_Impl<T> {
@ -1056,12 +1090,7 @@ namespace chaiscript
if (!this->children.empty()) { if (!this->children.empty()) {
vec.reserve(this->children[0]->children.size()); vec.reserve(this->children[0]->children.size());
for (const auto &child : this->children[0]->children) { for (const auto &child : this->children[0]->children) {
auto obj = child->eval(t_ss); vec.push_back(detail::clone_if_necessary(child->eval(t_ss), m_loc, t_ss));
if (!obj.is_return_value()) {
vec.push_back(t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions()));
} else {
vec.push_back(std::move(obj));
}
} }
} }
return const_var(std::move(vec)); return const_var(std::move(vec));
@ -1086,12 +1115,8 @@ namespace chaiscript
std::map<std::string, Boxed_Value> retval; std::map<std::string, Boxed_Value> retval;
for (const auto &child : this->children[0]->children) { for (const auto &child : this->children[0]->children) {
auto obj = child->children[1]->eval(t_ss); retval.insert(std::make_pair(t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss)),
if (!obj.is_return_value()) { detail::clone_if_necessary(child->children[1]->eval(t_ss), m_loc, t_ss)));
obj = t_ss->call_function("clone", m_loc, {obj}, t_ss.conversions());
}
retval[t_ss->boxed_cast<std::string>(child->children[0]->eval(t_ss))] = std::move(obj);
} }
return const_var(std::move(retval)); return const_var(std::move(retval));
@ -1450,7 +1475,6 @@ namespace chaiscript
function_name); function_name);
} }
} catch (const exception::name_conflict_error &e) { } catch (const exception::name_conflict_error &e) {
std::cout << "Method!!" << std::endl;
throw exception::eval_error("Method redefined '" + e.name() + "'"); throw exception::eval_error("Method redefined '" + e.name() + "'");
} }
return void_var(); return void_var();

View File

@ -97,7 +97,7 @@ namespace chaiscript {
template<typename T> template<typename T>
bool contains_var_decl_in_scope(const eval::AST_Node_Impl<T> &node) bool contains_var_decl_in_scope(const eval::AST_Node_Impl<T> &node)
{ {
if (node.identifier == AST_Node_Type::Var_Decl) { if (node.identifier == AST_Node_Type::Var_Decl || node.identifier == AST_Node_Type::Assign_Decl) {
return true; return true;
} }
@ -208,6 +208,27 @@ namespace chaiscript {
} }
}; };
struct Assign_Decl {
template<typename T>
auto optimize(eval::AST_Node_Impl_Ptr<T> node) {
if ((node->identifier == AST_Node_Type::Equation)
&& node->text == "="
&& node->children.size() == 2
&& node->children[0]->identifier == AST_Node_Type::Var_Decl
)
{
std::vector<eval::AST_Node_Impl_Ptr<T>> new_children;
new_children.push_back(std::move(node->children[0]->children[0]));
new_children.push_back(std::move(node->children[1]));
return chaiscript::make_unique<eval::AST_Node_Impl<T>, eval::Assign_Decl_AST_Node<T>>(node->text,
node->location, std::move(new_children) );
}
return node;
}
};
struct If { struct If {
template<typename T> template<typename T>
auto optimize(eval::AST_Node_Impl_Ptr<T> node) { auto optimize(eval::AST_Node_Impl_Ptr<T> node) {
@ -440,7 +461,7 @@ namespace chaiscript {
}; };
typedef Optimizer<optimizer::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold, typedef Optimizer<optimizer::Partial_Fold, optimizer::Unused_Return, optimizer::Constant_Fold,
optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop> Optimizer_Default; optimizer::If, optimizer::Return, optimizer::Dead_Code, optimizer::Block, optimizer::For_Loop, optimizer::Assign_Decl> Optimizer_Default;
} }
} }

View File

@ -569,6 +569,8 @@ struct JSONParser {
bool isDouble = false; bool isDouble = false;
bool isNegative = false; bool isNegative = false;
int64_t exp = 0; int64_t exp = 0;
bool isExpNegative = false;
long exp = 0;
if( offset < str.size() && str.at(offset) == '-' ) { if( offset < str.size() && str.at(offset) == '-' ) {
isNegative = true; isNegative = true;
++offset; ++offset;
@ -587,7 +589,7 @@ struct JSONParser {
if( offset < str.size() && (c == 'E' || c == 'e' )) { if( offset < str.size() && (c == 'E' || c == 'e' )) {
c = str.at(offset++); c = str.at(offset++);
if( c == '-' ) { if( c == '-' ) {
exp_str += '-'; isExpNegative = true;
} else if( c == '+' ) { } else if( c == '+' ) {
// do nothing // do nothing
} else { } else {
@ -603,9 +605,9 @@ struct JSONParser {
} }
else { else {
break; break;
} }
} }
exp = chaiscript::parse_num<int64_t>( exp_str ); exp = chaiscript::parse_num<int64_t>( exp_str ) * (isExpNegative?-1:1);
} }
else if( offset < str.size() && (!isspace( c ) && c != ',' && c != ']' && c != '}' )) { else if( offset < str.size() && (!isspace( c ) && c != ',' && c != ']' && c != '}' )) {
throw std::runtime_error(std::string("JSON ERROR: Number: unexpected character '") + c + "'"); throw std::runtime_error(std::string("JSON ERROR: Number: unexpected character '") + c + "'");

View File

@ -0,0 +1,11 @@
def var_test(int n)
{
for (var i = 0; i < n; ++i) {
var j = 0
}
}
var n = 500000
var_test(n) // takes 2.6 s

View File

@ -25,7 +25,7 @@ Release under the BSD license, see "license.txt" for details.
Introduction Introduction
============ ============
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/ChaiScript/ChaiScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Gitter](https://badges.gitter.im/JoinChat.svg)](https://gitter.im/ChaiScript/ChaiScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
ChaiScript is one of the only embedded scripting language designed from the ChaiScript is one of the only embedded scripting language designed from the
ground up to directly target C++ and take advantage of modern C++ development ground up to directly target C++ and take advantage of modern C++ development

5
unittests/json_14.chai Normal file
View File

@ -0,0 +1,5 @@
assert_equal(from_json("9.9e-02"), 9.9e-02)
assert_equal(from_json("-13.57e+3"), -13570.0)
assert_equal(from_json("1E-01"), 0.1)
assert_equal(from_json("-314159e-5"), -3.14159)
assert_equal(from_json("5e+04"), 50000)