From 1e584048ceb777fabf9aa7207dee939e36bcdf51 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 9 Apr 2016 21:00:07 -0600 Subject: [PATCH 01/37] Remove std::function from bind_first --- include/chaiscript/dispatchkit/bind_first.hpp | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index fcba534..98da1de 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -27,45 +27,52 @@ namespace chaiscript } template - std::function bind_first(Ret (*f)(P1, Param...), O&& o) + auto bind_first(Ret (*f)(P1, Param...), O&& o) { - return std::function( - [f, o](Param...param) -> Ret { - return f(std::forward(o), std::forward(param)...); - } - ); + return [f, o](Param...param) -> Ret { + return f(std::forward(o), std::forward(param)...); + }; } template - std::function bind_first(Ret (Class::*f)(Param...), O&& o) + auto bind_first(Ret (Class::*f)(Param...), O&& o) { - return std::function( - [f, o](Param...param) -> Ret { - return (get_pointer(o)->*f)(std::forward(param)...); - } - ); + return [f, o](Param...param) -> Ret { + return (get_pointer(o)->*f)(std::forward(param)...); + }; } template - std::function bind_first(Ret (Class::*f)(Param...) const, O&& o) + auto bind_first(Ret (Class::*f)(Param...) const, O&& o) { - return std::function( - [f, o](Param...param) -> Ret { - return (get_pointer(o)->*f)(std::forward(param)...); - } - ); + return [f, o](Param...param) -> Ret { + return (get_pointer(o)->*f)(std::forward(param)...); + }; } template - std::function bind_first(const std::function &f, O&& o) + auto bind_first(const std::function &f, O&& o) { - return std::function( - [f, o](Param...param) -> Ret { - return f(o, std::forward(param)...); - }); + return [f, o](Param...param) -> Ret { + return f(o, std::forward(param)...); + }; } + template + auto bind_first(const F &fo, O&& o, Ret (Class::*f)(P1, Param...) const) + { + return [fo, o, f](Param ...param) -> Ret { + return (fo.*f)(o, std::forward(param)...); + }; + + } + + template + auto bind_first(const F &f, O&& o) + { + return bind_first(f, std::forward(o), &F::operator()); + } } } From 2400c64c82cfbaaed4f14f202fa8f78963ff605d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 9 Apr 2016 21:15:07 -0600 Subject: [PATCH 02/37] Move to strongly typed enums for node types --- .../language/chaiscript_algebraic.hpp | 2 +- .../chaiscript/language/chaiscript_common.hpp | 25 ++++++++----------- .../chaiscript/language/chaiscript_parser.hpp | 6 ++--- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index 52441e8..b196db4 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -31,7 +31,7 @@ namespace chaiscript }; static const char *to_string(Opers t_oper) { - const char *opers[] = { + static const char *opers[] = { "", "==", "<", ">", "<=", ">=", "!=", "", diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 27ac85f..f20ed09 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -32,28 +32,25 @@ namespace chaiscript /// Types of AST nodes available to the parser and eval - class AST_Node_Type { - public: - enum Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, - Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, - Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, - Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, - Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl - }; + enum class AST_Node_Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, + Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, + Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, + Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, + Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl }; namespace { /// Helper lookup to get the name of each node type - const char *ast_node_type_to_string(int ast_node_type) { - const char *ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", + const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { + static const char * const ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg"}; - return ast_node_types[ast_node_type]; + return ast_node_types[static_cast(ast_node_type)]; } } @@ -166,7 +163,7 @@ namespace chaiscript private: template - static int id(const T& t) + static AST_Node_Type id(const T& t) { return t->identifier; } @@ -434,7 +431,7 @@ namespace chaiscript /// \brief Struct that doubles as both a parser ast_node and an AST node. struct AST_Node : std::enable_shared_from_this { public: - const int identifier; //< \todo shouldn't this be a strongly typed enum value? + const AST_Node_Type identifier; const std::string text; Parse_Location location; std::vector children; @@ -507,7 +504,7 @@ namespace chaiscript virtual ~AST_Node() {} protected: - AST_Node(std::string t_ast_node_text, int t_id, Parse_Location t_loc, + AST_Node(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc, std::vector t_children = std::vector()) : identifier(t_id), text(std::move(t_ast_node_text)), location(std::move(t_loc)), diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 715d90c..2c61d83 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -146,8 +146,8 @@ namespace chaiscript } - static const std::array &create_operators() { - static const std::array operators = { { + static const std::array &create_operators() { + static const std::array operators = { { AST_Node_Type::Ternary_Cond, AST_Node_Type::Logical_Or, AST_Node_Type::Logical_And, @@ -169,7 +169,7 @@ namespace chaiscript const std::array, detail::max_alphabet> &m_alphabet = create_alphabet(); const std::vector> &m_operator_matches = create_operator_matches(); - const std::array &m_operators = create_operators(); + const std::array &m_operators = create_operators(); std::shared_ptr m_filename; std::vector m_match_stack; From 641ac1a1aecb9f02d9df8717ce68b9ccf8f42b6d Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 9 Apr 2016 21:49:12 -0600 Subject: [PATCH 03/37] Split up ifdef'd module code --- .../chaiscript/language/chaiscript_engine.hpp | 213 +----------------- .../chaiscript/language/chaiscript_posix.hpp | 79 +++++++ .../language/chaiscript_unknown.hpp | 27 +++ .../language/chaiscript_windows.hpp | 128 +++++++++++ 4 files changed, 242 insertions(+), 205 deletions(-) create mode 100644 include/chaiscript/language/chaiscript_posix.hpp create mode 100644 include/chaiscript/language/chaiscript_unknown.hpp create mode 100644 include/chaiscript/language/chaiscript_windows.hpp diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 78d86ee..4aaf0f4 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -33,14 +33,15 @@ #if defined(_POSIX_VERSION) && !defined(__CYGWIN__) #include -#else +#endif + + #ifdef CHAISCRIPT_WINDOWS -#define VC_EXTRA_LEAN -#if !defined(WIN32_LEAN_AND_MEAN) -#define WIN32_LEAN_AND_MEAN -#endif -#include -#endif +#include "chaiscript_windows.hpp" +#elif _POSIX_VERSION +#include "chaiscript_posix.hpp" +#else +#include "chaiscript_unknown.hpp" #endif @@ -49,205 +50,9 @@ namespace chaiscript { - namespace exception - { - /// \brief Thrown if an error occurs while attempting to load a binary module - struct load_module_error : std::runtime_error - { - load_module_error(const std::string &t_reason) noexcept - : std::runtime_error(t_reason) - { - } - - load_module_error(const load_module_error &) = default; - virtual ~load_module_error() noexcept {} - }; - } namespace detail { -#if defined(_POSIX_VERSION) && !defined(__CYGWIN__) - struct Loadable_Module - { - struct DLModule - { - DLModule(const std::string &t_filename) - : m_data(dlopen(t_filename.c_str(), RTLD_NOW)) - { - if (!m_data) - { - throw chaiscript::exception::load_module_error(dlerror()); - } - } - - DLModule(const DLModule &); // Explicitly unimplemented copy constructor - DLModule &operator=(const DLModule &); // Explicitly unimplemented assignment operator - - ~DLModule() - { - dlclose(m_data); - } - - void *m_data; - }; - - template - struct DLSym - { - DLSym(DLModule &t_mod, const std::string &t_symbol) - : m_symbol(cast_symbol(dlsym(t_mod.m_data, t_symbol.c_str()))) - { - if (!m_symbol) - { - throw chaiscript::exception::load_module_error(dlerror()); - } - } - - static T cast_symbol(void *p) - { - union cast_union - { - T func_ptr; - void *in_ptr; - }; - - cast_union c; - c.in_ptr = p; - return c.func_ptr; - } - - T m_symbol; - }; - - 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_moduleptr(m_func.m_symbol()) - { - } - - DLModule m_dlmodule; - DLSym m_func; - ModulePtr m_moduleptr; - }; -#else - -#ifdef WIN32 - - - struct Loadable_Module - { - template - static std::wstring to_wstring(const T &t_str) - { - return std::wstring(t_str.begin(), t_str.end()); - } - - template - static std::string to_string(const T &t_str) - { - return std::string(t_str.begin(), t_str.end()); - } - -#if defined(_UNICODE) || defined(UNICODE) - template - static std::wstring to_proper_string(const T &t_str) - { - return to_wstring(t_str); - } -#else - template - static std::string to_proper_string(const T &t_str) - { - return to_string(t_str); - } -#endif - - static std::string get_error_message(DWORD t_err) - { - typedef LPTSTR StringType; - -#if defined(_UNICODE) || defined(UNICODE) - std::wstring retval = L"Unknown Error"; -#else - std::string retval = "Unknown Error"; -#endif - StringType lpMsgBuf = nullptr; - - if (FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, - t_err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast(&lpMsgBuf), - 0, nullptr ) != 0 && lpMsgBuf) - { - retval = lpMsgBuf; - LocalFree(lpMsgBuf); - } - - return to_string(retval); - } - - struct DLModule - { - DLModule(const std::string &t_filename) - : m_data(LoadLibrary(to_proper_string(t_filename).c_str())) - { - if (!m_data) - { - throw chaiscript::exception::load_module_error(get_error_message(GetLastError())); - } - } - - ~DLModule() - { - FreeLibrary(m_data); - } - - HMODULE m_data; - }; - - template - struct DLSym - { - DLSym(DLModule &t_mod, const std::string &t_symbol) - : m_symbol(reinterpret_cast(GetProcAddress(t_mod.m_data, t_symbol.c_str()))) - { - if (!m_symbol) - { - throw chaiscript::exception::load_module_error(get_error_message(GetLastError())); - } - } - - T m_symbol; - }; - - 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_moduleptr(m_func.m_symbol()) - { - } - - DLModule m_dlmodule; - DLSym m_func; - ModulePtr m_moduleptr; - }; - -#else - struct Loadable_Module - { - Loadable_Module(const std::string &, const std::string &) - { - throw chaiscript::exception::load_module_error("Loadable module support not available for your platform"); - } - - ModulePtr m_moduleptr; - }; -#endif -#endif - typedef std::shared_ptr Loadable_Module_Ptr; } @@ -286,8 +91,6 @@ namespace chaiscript - - /// Evaluates the given file and looks in the 'use' paths const Boxed_Value internal_eval_file(const std::string &t_filename) { for (const auto &path : m_use_paths) diff --git a/include/chaiscript/language/chaiscript_posix.hpp b/include/chaiscript/language/chaiscript_posix.hpp new file mode 100644 index 0000000..08cb53d --- /dev/null +++ b/include/chaiscript/language/chaiscript_posix.hpp @@ -0,0 +1,79 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2016, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_POSIX_HPP_ +#define CHAISCRIPT_POSIX_HPP_ + +namespace chaiscript +{ + namespace detail + { + struct Loadable_Module + { + struct DLModule + { + DLModule(const std::string &t_filename) + : m_data(dlopen(t_filename.c_str(), RTLD_NOW)) + { + if (!m_data) + { + throw chaiscript::exception::load_module_error(dlerror()); + } + } + + DLModule(const DLModule &); // Explicitly unimplemented copy constructor + DLModule &operator=(const DLModule &); // Explicitly unimplemented assignment operator + + ~DLModule() + { + dlclose(m_data); + } + + void *m_data; + }; + + template + struct DLSym + { + DLSym(DLModule &t_mod, const std::string &t_symbol) + : m_symbol(cast_symbol(dlsym(t_mod.m_data, t_symbol.c_str()))) + { + if (!m_symbol) + { + throw chaiscript::exception::load_module_error(dlerror()); + } + } + + static T cast_symbol(void *p) + { + union cast_union + { + T func_ptr; + void *in_ptr; + }; + + cast_union c; + c.in_ptr = p; + return c.func_ptr; + } + + T m_symbol; + }; + + 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_moduleptr(m_func.m_symbol()) + { + } + + DLModule m_dlmodule; + DLSym m_func; + ModulePtr m_moduleptr; + }; + } +} +#endif + diff --git a/include/chaiscript/language/chaiscript_unknown.hpp b/include/chaiscript/language/chaiscript_unknown.hpp new file mode 100644 index 0000000..2e5c228 --- /dev/null +++ b/include/chaiscript/language/chaiscript_unknown.hpp @@ -0,0 +1,27 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2016, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_UNKNOWN_HPP_ +#define CHAISCRIPT_UNKNOWN_HPP_ + + +namespace chaiscript +{ + namespace detail + { + struct Loadable_Module + { + Loadable_Module(const std::string &, const std::string &) + { + throw chaiscript::exception::load_module_error("Loadable module support not available for your platform"); + } + + ModulePtr m_moduleptr; + }; + } +} +#endif + diff --git a/include/chaiscript/language/chaiscript_windows.hpp b/include/chaiscript/language/chaiscript_windows.hpp new file mode 100644 index 0000000..f36db1e --- /dev/null +++ b/include/chaiscript/language/chaiscript_windows.hpp @@ -0,0 +1,128 @@ +// This file is distributed under the BSD License. +// See "license.txt" for details. +// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) +// Copyright 2009-2016, Jason Turner (jason@emptycrate.com) +// http://www.chaiscript.com + +#ifndef CHAISCRIPT_WINDOWS_HPP_ +#define CHAISCRIPT_WINDOWS_HPP_ + +#include + +#ifdef CHAISCRIPT_WINDOWS +#define VC_EXTRA_LEAN +#if !defined(WIN32_LEAN_AND_MEAN) +#define WIN32_LEAN_AND_MEAN +#endif +#include +#endif + + +namespace chaiscript +{ + namespace detail + { + struct Loadable_Module + { + template + static std::wstring to_wstring(const T &t_str) + { + return std::wstring(t_str.begin(), t_str.end()); + } + + template + static std::string to_string(const T &t_str) + { + return std::string(t_str.begin(), t_str.end()); + } + +#if defined(_UNICODE) || defined(UNICODE) + template + static std::wstring to_proper_string(const T &t_str) + { + return to_wstring(t_str); + } +#else + template + static std::string to_proper_string(const T &t_str) + { + return to_string(t_str); + } +#endif + + static std::string get_error_message(DWORD t_err) + { + typedef LPTSTR StringType; + +#if defined(_UNICODE) || defined(UNICODE) + std::wstring retval = L"Unknown Error"; +#else + std::string retval = "Unknown Error"; +#endif + StringType lpMsgBuf = nullptr; + + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + t_err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast(&lpMsgBuf), + 0, nullptr ) != 0 && lpMsgBuf) + { + retval = lpMsgBuf; + LocalFree(lpMsgBuf); + } + + return to_string(retval); + } + + struct DLModule + { + DLModule(const std::string &t_filename) + : m_data(LoadLibrary(to_proper_string(t_filename).c_str())) + { + if (!m_data) + { + throw chaiscript::exception::load_module_error(get_error_message(GetLastError())); + } + } + + ~DLModule() + { + FreeLibrary(m_data); + } + + HMODULE m_data; + }; + + template + struct DLSym + { + DLSym(DLModule &t_mod, const std::string &t_symbol) + : m_symbol(reinterpret_cast(GetProcAddress(t_mod.m_data, t_symbol.c_str()))) + { + if (!m_symbol) + { + throw chaiscript::exception::load_module_error(get_error_message(GetLastError())); + } + } + + T m_symbol; + }; + + 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_moduleptr(m_func.m_symbol()) + { + } + + DLModule m_dlmodule; + DLSym m_func; + ModulePtr m_moduleptr; + }; + } +} +#endif + From 08a68f310a76138f17e6cb734a38a67ad23ba9d2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 9 Apr 2016 21:50:23 -0600 Subject: [PATCH 04/37] Move to strongly typed algebraic enum --- .../chaiscript/dispatchkit/boxed_number.hpp | 218 +++++++++--------- .../language/chaiscript_algebraic.hpp | 68 +++--- .../chaiscript/language/chaiscript_common.hpp | 12 + .../chaiscript/language/chaiscript_eval.hpp | 8 +- 4 files changed, 159 insertions(+), 147 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 7eefe99..6bbf088 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -162,17 +162,17 @@ namespace chaiscript { switch (t_oper) { - case Operators::equals: + case Operators::Opers::equals: return const_var(t == u); - case Operators::less_than: + case Operators::Opers::less_than: return const_var(t < u); - case Operators::greater_than: + case Operators::Opers::greater_than: return const_var(t > u); - case Operators::less_than_equal: + case Operators::Opers::less_than_equal: return const_var(t <= u); - case Operators::greater_than_equal: + case Operators::Opers::greater_than_equal: return const_var(t >= u); - case Operators::not_equal: + case Operators::Opers::not_equal: return const_var(t != u); default: throw chaiscript::detail::exception::bad_any_cast(); @@ -184,10 +184,10 @@ namespace chaiscript { switch (t_oper) { - case Operators::pre_increment: + case Operators::Opers::pre_increment: ++t; break; - case Operators::pre_decrement: + case Operators::Opers::pre_decrement: --t; break; default: @@ -202,20 +202,20 @@ namespace chaiscript { switch (t_oper) { - case Operators::assign: + case Operators::Opers::assign: t = u; break; - case Operators::assign_product: + case Operators::Opers::assign_product: t *= u; break; - case Operators::assign_sum: + case Operators::Opers::assign_sum: t += u; break; - case Operators::assign_quotient: + case Operators::Opers::assign_quotient: check_divide_by_zero(u); t /= u; break; - case Operators::assign_difference: + case Operators::Opers::assign_difference: t -= u; break; default: @@ -230,23 +230,23 @@ namespace chaiscript { switch (t_oper) { - case Operators::assign_bitwise_and: + case Operators::Opers::assign_bitwise_and: t &= u; break; - case Operators::assign_bitwise_or: + case Operators::Opers::assign_bitwise_or: t |= u; break; - case Operators::assign_shift_left: + case Operators::Opers::assign_shift_left: t <<= u; break; - case Operators::assign_shift_right: + case Operators::Opers::assign_shift_right: t >>= u; break; - case Operators::assign_remainder: + case Operators::Opers::assign_remainder: check_divide_by_zero(u); t %= u; break; - case Operators::assign_bitwise_xor: + case Operators::Opers::assign_bitwise_xor: t ^= u; break; default: @@ -260,7 +260,7 @@ namespace chaiscript { switch (t_oper) { - case Operators::bitwise_complement: + case Operators::Opers::bitwise_complement: return const_var(~t); default: throw chaiscript::detail::exception::bad_any_cast(); @@ -272,18 +272,18 @@ namespace chaiscript { switch (t_oper) { - case Operators::shift_left: + case Operators::Opers::shift_left: return const_var(t << u); - case Operators::shift_right: + case Operators::Opers::shift_right: return const_var(t >> u); - case Operators::remainder: + case Operators::Opers::remainder: check_divide_by_zero(u); return const_var(t % u); - case Operators::bitwise_and: + case Operators::Opers::bitwise_and: return const_var(t & u); - case Operators::bitwise_or: + case Operators::Opers::bitwise_or: return const_var(t | u); - case Operators::bitwise_xor: + case Operators::Opers::bitwise_xor: return const_var(t ^ u); default: throw chaiscript::detail::exception::bad_any_cast(); @@ -295,9 +295,9 @@ namespace chaiscript { switch (t_oper) { - case Operators::unary_minus: + case Operators::Opers::unary_minus: return const_var(-t); - case Operators::unary_plus: + case Operators::Opers::unary_plus: return const_var(+t); default: throw chaiscript::detail::exception::bad_any_cast(); @@ -309,14 +309,14 @@ namespace chaiscript { switch (t_oper) { - case Operators::sum: + case Operators::Opers::sum: return const_var(t + u); - case Operators::quotient: + case Operators::Opers::quotient: check_divide_by_zero(u); return const_var(t / u); - case Operators::product: + case Operators::Opers::product: return const_var(t * u); - case Operators::difference: + case Operators::Opers::difference: return const_var(t - u); default: throw chaiscript::detail::exception::bad_any_cast(); @@ -328,16 +328,16 @@ namespace chaiscript -> typename std::enable_if::value && !std::is_floating_point::value, Boxed_Value>::type { typedef typename std::common_type::type common_type; - if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) + if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag) { return boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + } else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { return binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs), t_lhs); - } else if (t_oper > Operators::non_const_int_flag && t_oper < Operators::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + } else if (t_oper > Operators::Opers::non_const_int_flag && t_oper < Operators::Opers::const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { return binary_int_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs), t_lhs); - } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { + } else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) { return const_binary_int_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else if (t_oper > Operators::const_flag) { + } else if (t_oper > Operators::Opers::const_flag) { return const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); } else { throw chaiscript::detail::exception::bad_any_cast(); @@ -349,12 +349,12 @@ namespace chaiscript -> typename std::enable_if::value || std::is_floating_point::value, Boxed_Value>::type { typedef typename std::common_type::type common_type; - if (t_oper > Operators::boolean_flag && t_oper < Operators::non_const_flag) + if (t_oper > Operators::Opers::boolean_flag && t_oper < Operators::Opers::non_const_flag) { return boolean_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); - } else if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + } else if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { return binary_go(t_oper, *static_cast(t_lhs.get_ptr()), get_as_aux(t_rhs), t_lhs); - } else if (t_oper > Operators::const_flag) { + } else if (t_oper > Operators::Opers::const_flag) { return const_binary_go(t_oper, get_as_aux(t_lhs), get_as_aux(t_rhs)); } else { throw chaiscript::detail::exception::bad_any_cast(); @@ -366,11 +366,11 @@ namespace chaiscript static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) -> typename std::enable_if::value, Boxed_Value>::type { - if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { return unary_go(t_oper, *static_cast(t_lhs.get_ptr()), t_lhs); - } else if (t_oper > Operators::const_int_flag && t_oper < Operators::const_flag) { + } else if (t_oper > Operators::Opers::const_int_flag && t_oper < Operators::Opers::const_flag) { return const_unary_int_go(t_oper, *static_cast(t_lhs.get_const_ptr())); - } else if (t_oper > Operators::const_flag) { + } else if (t_oper > Operators::Opers::const_flag) { return const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); } else { throw chaiscript::detail::exception::bad_any_cast(); @@ -381,9 +381,9 @@ namespace chaiscript static auto go(Operators::Opers t_oper, const Boxed_Value &t_lhs) -> typename std::enable_if::value, Boxed_Value>::type { - if (t_oper > Operators::non_const_flag && t_oper < Operators::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { + if (t_oper > Operators::Opers::non_const_flag && t_oper < Operators::Opers::non_const_int_flag && !t_lhs.is_const() && !t_lhs.is_return_value()) { return unary_go(t_oper, *static_cast(t_lhs.get_ptr()), t_lhs); - } else if (t_oper > Operators::const_flag) { + } else if (t_oper > Operators::Opers::const_flag) { return const_unary_go(t_oper, *static_cast(t_lhs.get_const_ptr())); } else { throw chaiscript::detail::exception::bad_any_cast(); @@ -647,67 +647,67 @@ namespace chaiscript bool operator==(const Boxed_Number &t_rhs) const { - return boxed_cast(oper(Operators::equals, this->bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::equals, this->bv, t_rhs.bv)); } bool operator<(const Boxed_Number &t_rhs) const { - return boxed_cast(oper(Operators::less_than, this->bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::less_than, this->bv, t_rhs.bv)); } bool operator>(const Boxed_Number &t_rhs) const { - return boxed_cast(oper(Operators::greater_than, this->bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::greater_than, this->bv, t_rhs.bv)); } bool operator>=(const Boxed_Number &t_rhs) const { - return boxed_cast(oper(Operators::greater_than_equal, this->bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::greater_than_equal, this->bv, t_rhs.bv)); } bool operator<=(const Boxed_Number &t_rhs) const { - return boxed_cast(oper(Operators::less_than_equal, this->bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::less_than_equal, this->bv, t_rhs.bv)); } bool operator!=(const Boxed_Number &t_rhs) const { - return boxed_cast(oper(Operators::not_equal, this->bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::not_equal, this->bv, t_rhs.bv)); } Boxed_Number operator--() { - return oper(Operators::pre_decrement, this->bv); + return oper(Operators::Opers::pre_decrement, this->bv); } Boxed_Number operator++() { - return oper(Operators::pre_increment, this->bv); + return oper(Operators::Opers::pre_increment, this->bv); } Boxed_Number operator+(const Boxed_Number &t_rhs) const { - return oper(Operators::sum, this->bv, t_rhs.bv); + return oper(Operators::Opers::sum, this->bv, t_rhs.bv); } Boxed_Number operator+() const { - return oper(Operators::unary_plus, this->bv); + return oper(Operators::Opers::unary_plus, this->bv); } Boxed_Number operator-() const { - return oper(Operators::unary_minus, this->bv); + return oper(Operators::Opers::unary_minus, this->bv); } Boxed_Number operator-(const Boxed_Number &t_rhs) const { - return oper(Operators::difference, this->bv, t_rhs.bv); + return oper(Operators::Opers::difference, this->bv, t_rhs.bv); } Boxed_Number operator&=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_bitwise_and, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_bitwise_and, this->bv, t_rhs.bv); } static void validate_boxed_number(const Boxed_Value &v) @@ -735,255 +735,255 @@ namespace chaiscript // cppcheck-suppress operatorEq Boxed_Number operator=(const Boxed_Number &t_rhs) const { - return oper(Operators::assign, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign, this->bv, t_rhs.bv); } Boxed_Number operator|=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_bitwise_or, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_bitwise_or, this->bv, t_rhs.bv); } Boxed_Number operator^=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_bitwise_xor, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_bitwise_xor, this->bv, t_rhs.bv); } Boxed_Number operator%=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_remainder, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_remainder, this->bv, t_rhs.bv); } Boxed_Number operator<<=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_shift_left, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_shift_left, this->bv, t_rhs.bv); } Boxed_Number operator>>=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_shift_right, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_shift_right, this->bv, t_rhs.bv); } Boxed_Number operator&(const Boxed_Number &t_rhs) const { - return oper(Operators::bitwise_and, this->bv, t_rhs.bv); + return oper(Operators::Opers::bitwise_and, this->bv, t_rhs.bv); } Boxed_Number operator~() const { - return oper(Operators::bitwise_complement, this->bv); + return oper(Operators::Opers::bitwise_complement, this->bv); } Boxed_Number operator^(const Boxed_Number &t_rhs) const { - return oper(Operators::bitwise_xor, this->bv, t_rhs.bv); + return oper(Operators::Opers::bitwise_xor, this->bv, t_rhs.bv); } Boxed_Number operator|(const Boxed_Number &t_rhs) const { - return oper(Operators::bitwise_or, this->bv, t_rhs.bv); + return oper(Operators::Opers::bitwise_or, this->bv, t_rhs.bv); } Boxed_Number operator*=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_product, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_product, this->bv, t_rhs.bv); } Boxed_Number operator/=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_quotient, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_quotient, this->bv, t_rhs.bv); } Boxed_Number operator+=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_sum, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_sum, this->bv, t_rhs.bv); } Boxed_Number operator-=(const Boxed_Number &t_rhs) { - return oper(Operators::assign_difference, this->bv, t_rhs.bv); + return oper(Operators::Opers::assign_difference, this->bv, t_rhs.bv); } Boxed_Number operator/(const Boxed_Number &t_rhs) const { - return oper(Operators::quotient, this->bv, t_rhs.bv); + return oper(Operators::Opers::quotient, this->bv, t_rhs.bv); } Boxed_Number operator<<(const Boxed_Number &t_rhs) const { - return oper(Operators::shift_left, this->bv, t_rhs.bv); + return oper(Operators::Opers::shift_left, this->bv, t_rhs.bv); } Boxed_Number operator*(const Boxed_Number &t_rhs) const { - return oper(Operators::product, this->bv, t_rhs.bv); + return oper(Operators::Opers::product, this->bv, t_rhs.bv); } Boxed_Number operator%(const Boxed_Number &t_rhs) const { - return oper(Operators::remainder, this->bv, t_rhs.bv); + return oper(Operators::Opers::remainder, this->bv, t_rhs.bv); } Boxed_Number operator>>(const Boxed_Number &t_rhs) const { - return oper(Operators::shift_right, this->bv, t_rhs.bv); + return oper(Operators::Opers::shift_right, this->bv, t_rhs.bv); } static bool equals(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return boxed_cast(oper(Operators::equals, t_lhs.bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::equals, t_lhs.bv, t_rhs.bv)); } static bool less_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return boxed_cast(oper(Operators::less_than, t_lhs.bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::less_than, t_lhs.bv, t_rhs.bv)); } static bool greater_than(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return boxed_cast(oper(Operators::greater_than, t_lhs.bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::greater_than, t_lhs.bv, t_rhs.bv)); } static bool greater_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return boxed_cast(oper(Operators::greater_than_equal, t_lhs.bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::greater_than_equal, t_lhs.bv, t_rhs.bv)); } static bool less_than_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return boxed_cast(oper(Operators::less_than_equal, t_lhs.bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::less_than_equal, t_lhs.bv, t_rhs.bv)); } static bool not_equal(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return boxed_cast(oper(Operators::not_equal, t_lhs.bv, t_rhs.bv)); + return boxed_cast(oper(Operators::Opers::not_equal, t_lhs.bv, t_rhs.bv)); } static Boxed_Number pre_decrement(Boxed_Number t_lhs) { - return oper(Operators::pre_decrement, t_lhs.bv); + return oper(Operators::Opers::pre_decrement, t_lhs.bv); } static Boxed_Number pre_increment(Boxed_Number t_lhs) { - return oper(Operators::pre_increment, t_lhs.bv); + return oper(Operators::Opers::pre_increment, t_lhs.bv); } static const Boxed_Number sum(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::sum, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::sum, t_lhs.bv, t_rhs.bv); } static const Boxed_Number unary_plus(const Boxed_Number &t_lhs) { - return oper(Operators::unary_plus, t_lhs.bv); + return oper(Operators::Opers::unary_plus, t_lhs.bv); } static const Boxed_Number unary_minus(const Boxed_Number &t_lhs) { - return oper(Operators::unary_minus, t_lhs.bv); + return oper(Operators::Opers::unary_minus, t_lhs.bv); } static const Boxed_Number difference(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::difference, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::difference, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_bitwise_and(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_bitwise_and, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_bitwise_and, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_bitwise_or(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_bitwise_or, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_bitwise_or, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_bitwise_xor(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_bitwise_xor, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_bitwise_xor, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_remainder(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_remainder, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_remainder, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_shift_left(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_shift_left, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_shift_left, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_shift_right(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_shift_right, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_shift_right, t_lhs.bv, t_rhs.bv); } static const Boxed_Number bitwise_and(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::bitwise_and, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::bitwise_and, t_lhs.bv, t_rhs.bv); } static const Boxed_Number bitwise_complement(const Boxed_Number &t_lhs) { - return oper(Operators::bitwise_complement, t_lhs.bv, Boxed_Value(0)); + return oper(Operators::Opers::bitwise_complement, t_lhs.bv, Boxed_Value(0)); } static const Boxed_Number bitwise_xor(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::bitwise_xor, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::bitwise_xor, t_lhs.bv, t_rhs.bv); } static const Boxed_Number bitwise_or(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::bitwise_or, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::bitwise_or, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_product(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_product, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_product, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_quotient(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_quotient, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_quotient, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_sum(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_sum, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_sum, t_lhs.bv, t_rhs.bv); } static Boxed_Number assign_difference(Boxed_Number t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::assign_difference, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::assign_difference, t_lhs.bv, t_rhs.bv); } static const Boxed_Number quotient(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::quotient, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::quotient, t_lhs.bv, t_rhs.bv); } static const Boxed_Number shift_left(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::shift_left, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::shift_left, t_lhs.bv, t_rhs.bv); } static const Boxed_Number product(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::product, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::product, t_lhs.bv, t_rhs.bv); } static const Boxed_Number remainder(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::remainder, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::remainder, t_lhs.bv, t_rhs.bv); } static const Boxed_Number shift_right(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) { - return oper(Operators::shift_right, t_lhs.bv, t_rhs.bv); + return oper(Operators::Opers::shift_right, t_lhs.bv, t_rhs.bv); } diff --git a/include/chaiscript/language/chaiscript_algebraic.hpp b/include/chaiscript/language/chaiscript_algebraic.hpp index b196db4..0338a02 100644 --- a/include/chaiscript/language/chaiscript_algebraic.hpp +++ b/include/chaiscript/language/chaiscript_algebraic.hpp @@ -13,7 +13,7 @@ namespace chaiscript { struct Operators { - enum Opers + enum class Opers { boolean_flag, equals, less_than, greater_than, less_than_equal, greater_than_equal, not_equal, @@ -46,80 +46,80 @@ namespace chaiscript "+", "/", "*", "-", "+", "-", "" }; - return opers[t_oper]; + return opers[static_cast(t_oper)]; } static Opers to_operator(const std::string &t_str, bool t_is_unary = false) { if (t_str == "==") { - return equals; + return Opers::equals; } else if (t_str == "<") { - return less_than; + return Opers::less_than; } else if (t_str == ">") { - return greater_than; + return Opers::greater_than; } else if (t_str == "<=") { - return less_than_equal; + return Opers::less_than_equal; } else if (t_str == ">=") { - return greater_than_equal; + return Opers::greater_than_equal; } else if (t_str == "!=") { - return not_equal; + return Opers::not_equal; } else if (t_str == "=") { - return assign; + return Opers::assign; } else if (t_str == "++") { - return pre_increment; + return Opers::pre_increment; } else if (t_str == "--") { - return pre_decrement; + return Opers::pre_decrement; } else if (t_str == "*=") { - return assign_product; + return Opers::assign_product; } else if (t_str == "+=") { - return assign_sum; + return Opers::assign_sum; } else if (t_str == "-=") { - return assign_difference; + return Opers::assign_difference; } else if (t_str == "&=") { - return assign_bitwise_and; + return Opers::assign_bitwise_and; } else if (t_str == "|=") { - return assign_bitwise_or; + return Opers::assign_bitwise_or; } else if (t_str == "<<=") { - return assign_shift_left; + return Opers::assign_shift_left; } else if (t_str == ">>=") { - return assign_shift_right; + return Opers::assign_shift_right; } else if (t_str == "%=") { - return assign_remainder; + return Opers::assign_remainder; } else if (t_str == "^=") { - return assign_bitwise_xor; + return Opers::assign_bitwise_xor; } else if (t_str == "<<") { - return shift_left; + return Opers::shift_left; } else if (t_str == ">>") { - return shift_right; + return Opers::shift_right; } else if (t_str == "%") { - return remainder; + return Opers::remainder; } else if (t_str == "&") { - return bitwise_and; + return Opers::bitwise_and; } else if (t_str == "|") { - return bitwise_or; + return Opers::bitwise_or; } else if (t_str == "^") { - return bitwise_xor; + return Opers::bitwise_xor; } else if (t_str == "~") { - return bitwise_complement; + return Opers::bitwise_complement; } else if (t_str == "+") { if (t_is_unary) { - return unary_plus; + return Opers::unary_plus; } else { - return sum; + return Opers::sum; } } else if (t_str == "-") { if (t_is_unary) { - return unary_minus; + return Opers::unary_minus; } else { - return difference; + return Opers::difference; } } else if (t_str == "/") { - return quotient; + return Opers::quotient; } else if (t_str == "*") { - return product; + return Opers::product; } else { - return invalid; + return Opers::invalid; } } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index f20ed09..22f7548 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -98,6 +98,18 @@ namespace chaiscript /// \brief Classes which may be thrown during error cases when ChaiScript is executing. namespace exception { + /// \brief Thrown if an error occurs while attempting to load a binary module + struct load_module_error : std::runtime_error + { + load_module_error(const std::string &t_reason) noexcept + : std::runtime_error(t_reason) + { + } + + load_module_error(const load_module_error &) = default; + virtual ~load_module_error() noexcept {} + }; + /// Errors generated during parsing or evaluation struct eval_error : std::runtime_error { diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index b692538..a4ac5fe 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -103,7 +103,7 @@ namespace chaiscript Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) const { try { - if (t_oper != Operators::invalid && t_lhs.get_type_info().is_arithmetic() && t_rhs.get_type_info().is_arithmetic()) + if (t_oper != Operators::Opers::invalid && t_lhs.get_type_info().is_arithmetic() && t_rhs.get_type_info().is_arithmetic()) { // If it's an arithmetic operation we want to short circuit dispatch try{ @@ -384,7 +384,7 @@ namespace chaiscript Boxed_Value rhs = this->children[2]->eval(t_ss); Boxed_Value lhs = this->children[0]->eval(t_ss); - if (m_oper != Operators::invalid && lhs.get_type_info().is_arithmetic() && + if (m_oper != Operators::Opers::invalid && lhs.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) { try { @@ -392,7 +392,7 @@ namespace chaiscript } catch (const std::exception &) { throw exception::eval_error("Error with unsupported arithmetic assignment operation"); } - } else if (m_oper == Operators::assign) { + } else if (m_oper == Operators::Opers::assign) { if (lhs.is_return_value()) { throw exception::eval_error("Error, cannot assign to temporary value."); } @@ -1076,7 +1076,7 @@ namespace chaiscript try { // short circuit arithmetic operations - if (m_oper != Operators::invalid && m_oper != Operators::bitwise_and && bv.get_type_info().is_arithmetic()) + if (m_oper != Operators::Opers::invalid && m_oper != Operators::Opers::bitwise_and && bv.get_type_info().is_arithmetic()) { return Boxed_Number::do_oper(m_oper, bv); } else { From 4bf619c80fc370b181c207cb5ce3a034b4249822 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 9 Apr 2016 22:10:06 -0600 Subject: [PATCH 05/37] some initialization and destructor cleanups --- .../chaiscript/dispatchkit/dispatchkit.hpp | 18 +++------------- .../chaiscript/language/chaiscript_common.hpp | 11 +++++++++- .../chaiscript/language/chaiscript_engine.hpp | 21 ------------------- .../chaiscript/language/chaiscript_posix.hpp | 6 ++++-- .../language/chaiscript_windows.hpp | 5 +++++ 5 files changed, 22 insertions(+), 39 deletions(-) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 352b086..54bef22 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -418,11 +418,9 @@ namespace chaiscript std::vector> m_boxed_functions; std::map m_global_objects; Type_Name_Map m_types; - std::set m_reserved_words; - - State &operator=(const State &) = default; - State() = default; - State(const State &) = default; + std::set m_reserved_words + = {"def", "fun", "while", "for", "if", "else", "&&", "||", ",", "auto", + "return", "break", "true", "false", "class", "attr", "var", "global", "GLOBAL", "_"}; }; Dispatch_Engine() @@ -430,10 +428,6 @@ namespace chaiscript { } - ~Dispatch_Engine() - { - } - /// \brief casts an object while applying any Dynamic_Conversion available template typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) const @@ -892,12 +886,6 @@ namespace chaiscript return rets; } - void add_reserved_word(const std::string &name) - { - chaiscript::detail::threading::unique_lock l(m_mutex); - - m_state.m_reserved_words.insert(name); - } const Type_Conversions &conversions() const { diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 22f7548..a36bc1a 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -513,7 +513,10 @@ namespace chaiscript std::replace(children.begin(), children.end(), t_child, t_new_child); } - virtual ~AST_Node() {} + virtual ~AST_Node() = default; + AST_Node(AST_Node &&) = default; + AST_Node &operator=(AST_Node &&) = default; + protected: AST_Node(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc, @@ -563,6 +566,8 @@ namespace chaiscript /// Creates a new scope then pops it on destruction struct Scope_Push_Pop { + Scope_Push_Pop(Scope_Push_Pop &&) = default; + Scope_Push_Pop& operator=(Scope_Push_Pop &&) = default; Scope_Push_Pop(const Scope_Push_Pop &) = delete; Scope_Push_Pop& operator=(const Scope_Push_Pop &) = delete; @@ -585,6 +590,8 @@ namespace chaiscript /// Creates a new function call and pops it on destruction struct Function_Push_Pop { + Function_Push_Pop(Function_Push_Pop &&) = default; + Function_Push_Pop& operator=(Function_Push_Pop &&) = default; Function_Push_Pop(const Function_Push_Pop &) = delete; Function_Push_Pop& operator=(const Function_Push_Pop &) = delete; @@ -617,6 +624,8 @@ namespace chaiscript /// Creates a new scope then pops it on destruction struct Stack_Push_Pop { + Stack_Push_Pop(Stack_Push_Pop &&) = default; + Stack_Push_Pop& operator=(Stack_Push_Pop &&) = default; Stack_Push_Pop(const Stack_Push_Pop &) = delete; Stack_Push_Pop& operator=(const Stack_Push_Pop &) = delete; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 4aaf0f4..bc00f7a 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -128,27 +128,6 @@ namespace chaiscript /// Builds all the requirements for ChaiScript, including its evaluator and a run of its prelude. void build_eval_system(const ModulePtr &t_lib) { - m_engine.add_reserved_word("def"); - m_engine.add_reserved_word("fun"); - m_engine.add_reserved_word("while"); - m_engine.add_reserved_word("for"); - m_engine.add_reserved_word("if"); - m_engine.add_reserved_word("else"); - m_engine.add_reserved_word("&&"); - m_engine.add_reserved_word("||"); - m_engine.add_reserved_word(","); - m_engine.add_reserved_word("auto"); - m_engine.add_reserved_word("return"); - m_engine.add_reserved_word("break"); - m_engine.add_reserved_word("true"); - m_engine.add_reserved_word("false"); - m_engine.add_reserved_word("class"); - m_engine.add_reserved_word("attr"); - m_engine.add_reserved_word("var"); - m_engine.add_reserved_word("global"); - m_engine.add_reserved_word("GLOBAL"); - m_engine.add_reserved_word("_"); - if (t_lib) { add(t_lib); diff --git a/include/chaiscript/language/chaiscript_posix.hpp b/include/chaiscript/language/chaiscript_posix.hpp index 08cb53d..c22fe87 100644 --- a/include/chaiscript/language/chaiscript_posix.hpp +++ b/include/chaiscript/language/chaiscript_posix.hpp @@ -24,8 +24,10 @@ namespace chaiscript } } - DLModule(const DLModule &); // Explicitly unimplemented copy constructor - DLModule &operator=(const DLModule &); // Explicitly unimplemented assignment operator + DLModule(DLModule &&) = default; + DLModule &operator=(DLModule &&) = default; + DLModule(const DLModule &) = delete; + DLModule &operator=(const DLModule &) = delete; ~DLModule() { diff --git a/include/chaiscript/language/chaiscript_windows.hpp b/include/chaiscript/language/chaiscript_windows.hpp index f36db1e..049e341 100644 --- a/include/chaiscript/language/chaiscript_windows.hpp +++ b/include/chaiscript/language/chaiscript_windows.hpp @@ -89,6 +89,11 @@ namespace chaiscript } } + DLModule(DLModule &&) = default; + DLModule &operator=(DLModule &&) = default; + DLModule(const DLModule &) = delete; + DLModule &operator=(const DLModule &) = delete; + ~DLModule() { FreeLibrary(m_data); From 61dfcb00c0f3f8b3ec5ad4fec3137dcd1506e45e Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Apr 2016 17:19:48 -0600 Subject: [PATCH 06/37] Move int/float into Constant --- .../chaiscript/language/chaiscript_common.hpp | 8 +- .../chaiscript/language/chaiscript_eval.hpp | 76 ++++--------------- .../chaiscript/language/chaiscript_parser.hpp | 49 ++++++++---- 3 files changed, 54 insertions(+), 79 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index a36bc1a..09e16d2 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -32,11 +32,11 @@ namespace chaiscript /// Types of AST nodes available to the parser and eval - enum class AST_Node_Type { Error, Int, Float, Id, Char, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, + enum class AST_Node_Type { Error, Id, Char, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, - Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl + Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant }; namespace @@ -44,11 +44,11 @@ namespace chaiscript /// Helper lookup to get the name of each node type const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { - static const char * const ast_node_types[] = { "Internal Parser Error", "Int", "Float", "Id", "Char", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", + static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Char", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", - "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg"}; + "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Constant"}; return ast_node_types[static_cast(ast_node_type)]; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index a4ac5fe..61413a7 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -129,72 +129,38 @@ namespace chaiscript mutable std::atomic_uint_fast32_t m_loc; }; - struct Int_AST_Node final : AST_Node { - Int_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, Boxed_Value t_bv) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Int, std::move(t_loc)), - m_value(std::move(t_bv)) { assert(text != ""); } - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override { - return m_value; - } - private: - Boxed_Value m_value; - }; + struct Constant_AST_Node final : AST_Node { + Constant_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, Boxed_Value t_value) + : AST_Node(t_ast_node_text, AST_Node_Type::Constant, std::move(t_loc)), + m_value(std::move(t_value)) + { + } - struct Float_AST_Node final : AST_Node { - Float_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, Boxed_Value t_bv) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Float, std::move(t_loc)), - m_value(std::move(t_bv)) { } - - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override { - return m_value; - } - - private: - Boxed_Value m_value; + Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override { + return m_value; + } + Boxed_Value m_value; }; struct Id_AST_Node final : AST_Node { Id_AST_Node(const std::string &t_ast_node_text, Parse_Location t_loc) : AST_Node(t_ast_node_text, AST_Node_Type::Id, std::move(t_loc)), - m_value(get_value(t_ast_node_text)), m_loc(0) + m_loc(0) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - if (!m_value.is_undef()) - { - return m_value; - } else { - try { - return t_ss.get_object(this->text, m_loc); - } - catch (std::exception &) { - throw exception::eval_error("Can not find object: " + this->text); - } + try { + return t_ss.get_object(this->text, m_loc); + } + catch (std::exception &) { + throw exception::eval_error("Can not find object: " + this->text); } } private: - static Boxed_Value get_value(const std::string &t_text) - { - if (t_text == "true") { - return const_var(true); - } else if (t_text == "false") { - return const_var(false); - } else if (t_text == "Infinity") { - return const_var(std::numeric_limits::infinity()); - } else if (t_text == "NaN") { - return const_var(std::numeric_limits::quiet_NaN()); - } else if (t_text == "_") { - return Boxed_Value(std::make_shared()); - } else { - return Boxed_Value(); - } - } - - Boxed_Value m_value; mutable std::atomic_uint_fast32_t m_loc; }; @@ -209,16 +175,6 @@ namespace chaiscript AST_Node(std::move(t_ast_node_text), AST_Node_Type::Str, std::move(t_loc)) { } }; - struct Eol_AST_Node final : AST_Node { - Eol_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Eol, std::move(t_loc)) { } - - std::string pretty_print() const override - { - return "\n"; - } - }; - struct Fun_Call_AST_Node final : AST_Node { Fun_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 2c61d83..ee745b7 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -741,20 +741,20 @@ namespace chaiscript if (Hex_()) { auto match = Position::str(start, m_position); auto bv = buildInt(16, match, true); - m_match_stack.emplace_back(make_node(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.emplace_back(make_node(std::move(match), start.line, start.col, std::move(bv))); return true; } if (Binary_()) { auto match = Position::str(start, m_position); auto bv = buildInt(2, match, true); - m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); return true; } if (Float_()) { auto match = Position::str(start, m_position); auto bv = buildFloat(match); - m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); return true; } else { @@ -762,11 +762,11 @@ namespace chaiscript auto match = Position::str(start, m_position); if (!match.empty() && (match[0] == '0')) { auto bv = buildInt(8, match, false); - m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); } else if (!match.empty()) { auto bv = buildInt(10, match, false); - m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); + m_match_stack.push_back(make_node(std::move(match), start.line, start.col, std::move(bv))); } else { return false; } @@ -824,16 +824,35 @@ namespace chaiscript const auto start = m_position; if (Id_()) { - m_match_stack.push_back(make_node( - [&]()->std::string{ - if (*start == '`') { - //Id Literal - return Position::str(start+1, m_position-1); - } else { - return Position::str(start, m_position); - } - }(), - start.line, start.col)); + + const auto text = Position::str(start, m_position); + if (text == "true") { + m_match_stack.push_back(make_node(text, start.line, start.col, const_var(true))); + } else if (text == "false") { + m_match_stack.push_back(make_node(text, start.line, start.col, const_var(false))); + } else if (text == "Infinity") { + m_match_stack.push_back(make_node(text, start.line, start.col, + const_var(std::numeric_limits::infinity()))); + } else if (text == "NaN") { + m_match_stack.push_back(make_node(text, start.line, start.col, + const_var(std::numeric_limits::quiet_NaN()))); + } else if (text == "_") { + m_match_stack.push_back(make_node(text, start.line, start.col, + Boxed_Value(std::make_shared()))); + } else { + m_match_stack.push_back(make_node( + [&]()->std::string{ + if (*start == '`') { + // 'escaped' literal, like an operator name + return Position::str(start+1, m_position-1); + } else { + return text; + } + }(), + start.line, start.col)); + } + + return true; } else { return false; From 62cd8031ac8b1bd20ffdc113f5cdd44182e974fd Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Apr 2016 18:29:16 -0600 Subject: [PATCH 07/37] Make quoted strings into Constants --- .../chaiscript/language/chaiscript_common.hpp | 4 +-- .../chaiscript/language/chaiscript_eval.hpp | 35 ------------------- .../chaiscript/language/chaiscript_parser.hpp | 10 +++--- 3 files changed, 7 insertions(+), 42 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 09e16d2..38cf8e6 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -33,7 +33,7 @@ namespace chaiscript /// Types of AST nodes available to the parser and eval enum class AST_Node_Type { Error, Id, Char, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, - Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Quoted_String, Single_Quoted_String, + Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant @@ -45,7 +45,7 @@ namespace chaiscript /// Helper lookup to get the name of each node type const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Char", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", - "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Quoted_String", "Single_Quoted_String", + "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Constant"}; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 61413a7..bb4fa3c 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -562,41 +562,6 @@ namespace chaiscript const std::string m_fun_name; }; - struct Quoted_String_AST_Node final : AST_Node { - Quoted_String_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Quoted_String, std::move(t_loc)), - m_value(const_var(text)) { } - - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override { - return m_value; - } - - std::string pretty_print() const override - { - return "\"" + text + "\""; - } - - private: - Boxed_Value m_value; - }; - - struct Single_Quoted_String_AST_Node final : AST_Node { - Single_Quoted_String_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Single_Quoted_String, std::move(t_loc)), - m_value(const_var(char(text.at(0)))) { } - - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{ - return m_value; - } - - std::string pretty_print() const override - { - return "'" + text + "'"; - } - - private: - Boxed_Value m_value; - }; struct Lambda_AST_Node final : AST_Node { Lambda_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index ee745b7..2df9d3f 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1106,11 +1106,11 @@ namespace chaiscript if (cparser.is_interpolated) { //If we've seen previous interpolation, add on instead of making a new one - m_match_stack.push_back(make_node(match, start.line, start.col)); + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); build_match(prev_stack_top, "+"); } else { - m_match_stack.push_back(make_node(match, start.line, start.col)); + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); } //We've finished with the part of the string up to this point, so clear it @@ -1162,11 +1162,11 @@ namespace chaiscript }(); if (is_interpolated) { - m_match_stack.push_back(make_node(match, start.line, start.col)); + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); build_match(prev_stack_top, "+"); } else { - m_match_stack.push_back(make_node(match, start.line, start.col)); + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); } return true; } else { @@ -1227,7 +1227,7 @@ namespace chaiscript throw exception::eval_error("Single-quoted strings must be 1 character long", File_Position(m_position.line, m_position.col), *m_filename); } - m_match_stack.push_back(make_node(match, start.line, start.col)); + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(char(match.at(0))))); return true; } else { From e02ac7819570897c3d468d8a736e39762617dd10 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Apr 2016 18:57:23 -0600 Subject: [PATCH 08/37] Remove Char_AST_Node --- .../chaiscript/language/chaiscript_common.hpp | 4 ++-- .../chaiscript/language/chaiscript_eval.hpp | 12 ++++-------- .../chaiscript/language/chaiscript_parser.hpp | 19 ++++--------------- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 38cf8e6..7d0a6df 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -32,7 +32,7 @@ namespace chaiscript /// Types of AST nodes available to the parser and eval - enum class AST_Node_Type { Error, Id, Char, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, + enum class AST_Node_Type { Error, Id, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, @@ -44,7 +44,7 @@ namespace chaiscript /// Helper lookup to get the name of each node type const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { - static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Char", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", + static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index bb4fa3c..63e4e85 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -165,10 +165,6 @@ namespace chaiscript mutable std::atomic_uint_fast32_t m_loc; }; - struct Char_AST_Node final : AST_Node { - Char_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Char, std::move(t_loc)) { } - }; struct Str_AST_Node final : AST_Node { Str_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) : @@ -989,11 +985,11 @@ namespace chaiscript struct Prefix_AST_Node final : AST_Node { Prefix_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Prefix, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(children[0]->text, true)) + m_oper(Operators::to_operator(text, true)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ - Boxed_Value bv(children[1]->eval(t_ss)); + Boxed_Value bv(children[0]->eval(t_ss)); try { // short circuit arithmetic operations @@ -1003,10 +999,10 @@ namespace chaiscript } else { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); fpp.save_params({bv}); - return t_ss->call_function(children[0]->text, m_loc, {std::move(bv)}, t_ss.conversions()); + return t_ss->call_function(text, m_loc, {std::move(bv)}, t_ss.conversions()); } } catch (const exception::dispatch_error &e) { - throw exception::eval_error("Error with prefix operator evaluation: '" + children[0]->text + "'", e.parameters, e.functions, false, *t_ss); + throw exception::eval_error("Error with prefix operator evaluation: '" + text + "'", e.parameters, e.functions, false, *t_ss); } } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 2df9d3f..aa922b2 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1247,20 +1247,9 @@ namespace chaiscript } /// Reads (and potentially captures) a char from input if it matches the parameter - bool Char(const char t_c, bool t_capture = false) { + bool Char(const char t_c) { SkipWS(); - - if (!t_capture) { - return Char_(t_c); - } else { - const auto start = m_position; - if (Char_(t_c)) { - m_match_stack.push_back(make_node(Position::str(start, m_position), start.line, start.col)); - return true; - } else { - return false; - } - } + return Char_(t_c); } /// Reads a string from input if it matches the parameter, without skipping initial whitespace @@ -2200,13 +2189,13 @@ namespace chaiscript for (const auto &oper : prefix_opers) { bool is_char = oper.size() == 1; - if ((is_char && Char(oper[0], true)) || (!is_char && Symbol(oper.c_str(), true))) + if ((is_char && Char(oper[0])) || (!is_char && Symbol(oper.c_str()))) { if (!Operator(m_operators.size()-1)) { throw exception::eval_error("Incomplete prefix '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } - build_match(prev_stack_top); + build_match(prev_stack_top, oper); return true; } } From 5e97f459d8599e134b2c49ce949251bc475ce19a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Apr 2016 19:01:55 -0600 Subject: [PATCH 09/37] Remove unnecessary false --- include/chaiscript/language/chaiscript_parser.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index aa922b2..1141351 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1615,7 +1615,7 @@ namespace chaiscript while (has_matches) { while (Eol()) {} has_matches = false; - if (Keyword("catch", false)) { + if (Keyword("catch")) { const auto catch_stack_top = m_match_stack.size(); if (Char('(')) { if (!(Arg() && Char(')'))) { @@ -1638,7 +1638,7 @@ namespace chaiscript } } while (Eol()) {} - if (Keyword("finally", false)) { + if (Keyword("finally")) { const auto finally_stack_top = m_match_stack.size(); while (Eol()) {} From 866db4ee8b95463055153253adccb0a2d65c27a0 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Apr 2016 21:38:44 -0600 Subject: [PATCH 10/37] Reduce instances of Str_AST_Node --- .../chaiscript/language/chaiscript_eval.hpp | 16 +++---- .../chaiscript/language/chaiscript_parser.hpp | 46 +++++++++---------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 63e4e85..7debbec 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -327,13 +327,13 @@ namespace chaiscript struct Equation_AST_Node final : AST_Node { Equation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Equation, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(children[1]->text)) - { assert(children.size() == 3); } + m_oper(Operators::to_operator(text)) + { assert(children.size() == 2); } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - Boxed_Value rhs = this->children[2]->eval(t_ss); + Boxed_Value rhs = this->children[1]->eval(t_ss); Boxed_Value lhs = this->children[0]->eval(t_ss); if (m_oper != Operators::Opers::invalid && lhs.get_type_info().is_arithmetic() && @@ -371,17 +371,17 @@ namespace chaiscript } try { - return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); + return t_ss->call_function(this->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ - throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss); + throw exception::eval_error("Unable to find appropriate'" + this->text + "' operator.", e.parameters, e.functions, false, *t_ss); } } catch(const exception::dispatch_error &e){ throw exception::eval_error("Missing clone or copy constructor for right hand side of equation", e.parameters, e.functions, false, *t_ss); } } - else if (this->children[1]->text == ":=") { + else if (this->text == ":=") { if (lhs.is_undef() || Boxed_Value::type_match(lhs, rhs)) { lhs.assign(rhs); lhs.reset_return_value(); @@ -391,9 +391,9 @@ namespace chaiscript } else { try { - return t_ss->call_function(this->children[1]->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); + return t_ss->call_function(this->text, m_loc, {std::move(lhs), rhs}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ - throw exception::eval_error("Unable to find appropriate'" + this->children[1]->text + "' operator.", e.parameters, e.functions, false, *t_ss); + throw exception::eval_error("Unable to find appropriate'" + this->text + "' operator.", e.parameters, e.functions, false, *t_ss); } } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 1141351..9b4370f 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1272,7 +1272,7 @@ namespace chaiscript } /// Reads (and potentially captures) a string from input if it matches the parameter - bool Keyword(const char *t_s, bool t_capture = false) { + bool Keyword(const char *t_s) { SkipWS(); const auto start = m_position; bool retval = Keyword_(t_s); @@ -1282,9 +1282,6 @@ namespace chaiscript retval = false; } - if ( t_capture && retval ) { - m_match_stack.push_back(make_node(Position::str(start, m_position), start.line, start.col)); - } return retval; } @@ -1553,7 +1550,7 @@ namespace chaiscript bool is_method = false; - if (Symbol("::", false)) { + if (Symbol("::")) { //We're now a method is_method = true; @@ -1682,12 +1679,11 @@ namespace chaiscript while (has_matches) { while (Eol()) {} has_matches = false; - if (Keyword("else", true)) { + const auto line = m_position.line; + const auto col = m_position.col; + if (Keyword("else")) { if (Keyword("if")) { - const AST_NodePtr back(m_match_stack.back()); - m_match_stack.back() = - chaiscript::make_shared("else if", back->location, back->children); - m_match_stack.back()->annotation = back->annotation; + m_match_stack.emplace_back(make_node("else if", line, col, std::vector())); if (!Char('(')) { throw exception::eval_error("Incomplete 'else if' expression", File_Position(m_position.line, m_position.col), *m_filename); } @@ -1703,6 +1699,7 @@ namespace chaiscript } has_matches = true; } else { + m_match_stack.emplace_back(make_node("else", line, col, std::vector())); while (Eol()) {} if (!Block()) { @@ -2105,7 +2102,7 @@ namespace chaiscript if (!Id()) { throw exception::eval_error("Incomplete attribute declaration", File_Position(m_position.line, m_position.col), *m_filename); } - if (!Symbol("::", false)) { + if (!Symbol("::")) { throw exception::eval_error("Incomplete attribute declaration", File_Position(m_position.line, m_position.col), *m_filename); } if (!Id()) { @@ -2169,7 +2166,7 @@ namespace chaiscript bool Reference() { const auto prev_stack_top = m_match_stack.size(); - if (Symbol("&", false)) { + if (Symbol("&")) { if (!Id()) { throw exception::eval_error("Incomplete '&' expression", File_Position(m_position.line, m_position.col), *m_filename); } @@ -2345,26 +2342,25 @@ namespace chaiscript /// Parses a string of binary equation operators bool Equation() { - bool retval = false; - const auto prev_stack_top = m_match_stack.size(); if (Operator()) { - retval = true; - if (Symbol("=", true, true) || Symbol(":=", true, true) || Symbol("+=", true, true) || - Symbol("-=", true, true) || Symbol("*=", true, true) || Symbol("/=", true, true) || - Symbol("%=", true, true) || Symbol("<<=", true, true) || Symbol(">>=", true, true) || - Symbol("&=", true, true) || Symbol("^=", true, true) || Symbol("|=", true, true)) { - SkipWS(true); - if (!Equation()) { - throw exception::eval_error("Incomplete equation", File_Position(m_position.line, m_position.col), *m_filename); - } + for (const auto sym : {"=", ":=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", "&=", "^=", "|="}) + { + if (Symbol(sym, false, true)) { + SkipWS(true); + if (!Equation()) { + throw exception::eval_error("Incomplete equation", File_Position(m_position.line, m_position.col), *m_filename); + } - build_match(prev_stack_top); + build_match(prev_stack_top, sym); + return true; + } } + return true; } - return retval; + return false; } /// Parses statements allowed inside of a class block From 443828fa2375d2e7f0168f5958d1db394ea533d0 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Apr 2016 22:27:35 -0600 Subject: [PATCH 11/37] More parser simplification --- .../chaiscript/language/chaiscript_eval.hpp | 12 +-- .../chaiscript/language/chaiscript_parser.hpp | 96 +++++++++---------- 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 7debbec..e1a2e19 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -505,8 +505,8 @@ namespace chaiscript Dot_Access_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Dot_Access, std::move(t_loc), std::move(t_children)), m_fun_name( - ((children[2]->identifier == AST_Node_Type::Fun_Call) || (children[2]->identifier == AST_Node_Type::Array_Call))? - children[2]->children[0]->text:children[2]->text) { } + ((children[1]->identifier == AST_Node_Type::Fun_Call) || (children[1]->identifier == AST_Node_Type::Array_Call))? + children[1]->children[0]->text:children[1]->text) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); @@ -516,9 +516,9 @@ namespace chaiscript std::vector params{retval}; bool has_function_params = false; - if (children[2]->children.size() > 1) { + if (children[1]->children.size() > 1) { has_function_params = true; - for (const auto &child : children[2]->children[1]->children) { + for (const auto &child : children[1]->children[1]->children) { params.push_back(child->eval(t_ss)); } } @@ -540,9 +540,9 @@ namespace chaiscript retval = std::move(rv.retval); } - if (this->children[2]->identifier == AST_Node_Type::Array_Call) { + if (this->children[1]->identifier == AST_Node_Type::Array_Call) { try { - retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[2]->children[1]->eval(t_ss)}, t_ss.conversions()); + retval = t_ss->call_function("[]", m_array_loc, {retval, this->children[1]->children[1]->eval(t_ss)}, t_ss.conversions()); } catch(const exception::dispatch_error &e){ throw exception::eval_error("Can not find appropriate array lookup operator '[]'.", e.parameters, e.functions, true, *t_ss); diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 9b4370f..879ab60 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -2036,7 +2036,7 @@ namespace chaiscript func_call->children.insert(func_call->children.begin(), dot_access->children.back()); dot_access->children.pop_back(); dot_access->children.push_back(std::move(func_call)); - if (dot_access->children.size() != 3) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename); + if (dot_access->children.size() != 2) throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename); m_match_stack.push_back(std::move(dot_access)); } } @@ -2049,13 +2049,13 @@ namespace chaiscript build_match(prev_stack_top); } - else if (Symbol(".", true)) { + else if (Symbol(".")) { has_more = true; if (!(Id())) { throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename); } - if ( std::distance(m_match_stack.begin() + static_cast(prev_stack_top), m_match_stack.end()) != 3) { + if ( std::distance(m_match_stack.begin() + static_cast(prev_stack_top), m_match_stack.end()) != 2) { throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename); } build_match(prev_stack_top); @@ -2221,61 +2221,59 @@ namespace chaiscript if (t_precedence < m_operators.size()) { if (Operator(t_precedence+1)) { retval = true; - if (Operator_Helper(t_precedence)) { - do { - while (Eol()) {} - if (!Operator(t_precedence+1)) { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", - File_Position(m_position.line, m_position.col), *m_filename); - } + while (Operator_Helper(t_precedence)) { + while (Eol()) {} + if (!Operator(t_precedence+1)) { + throw exception::eval_error("Incomplete " + + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + File_Position(m_position.line, m_position.col), *m_filename); + } - AST_NodePtr oper = m_match_stack.at(m_match_stack.size()-2); + AST_NodePtr oper = m_match_stack.at(m_match_stack.size()-2); - switch (m_operators[t_precedence]) { - case(AST_Node_Type::Ternary_Cond) : - m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), - advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); - if (Symbol(":")) { - if (!Operator(t_precedence+1)) { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", - File_Position(m_position.line, m_position.col), *m_filename); - } - build_match(prev_stack_top); - } - else { + switch (m_operators[t_precedence]) { + case(AST_Node_Type::Ternary_Cond) : + m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), + advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); + if (Symbol(":")) { + if (!Operator(t_precedence+1)) { throw exception::eval_error("Incomplete " + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", File_Position(m_position.line, m_position.col), *m_filename); } - break; + build_match(prev_stack_top); + } + else { + throw exception::eval_error("Incomplete " + + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + File_Position(m_position.line, m_position.col), *m_filename); + } + break; - case(AST_Node_Type::Addition) : - case(AST_Node_Type::Multiplication) : - case(AST_Node_Type::Shift) : - case(AST_Node_Type::Equality) : - case(AST_Node_Type::Bitwise_And) : - case(AST_Node_Type::Bitwise_Xor) : - case(AST_Node_Type::Bitwise_Or) : - case(AST_Node_Type::Comparison) : - assert(m_match_stack.size() > 1); - m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), - advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); - build_match(prev_stack_top, oper->text); - break; + case(AST_Node_Type::Addition) : + case(AST_Node_Type::Multiplication) : + case(AST_Node_Type::Shift) : + case(AST_Node_Type::Equality) : + case(AST_Node_Type::Bitwise_And) : + case(AST_Node_Type::Bitwise_Xor) : + case(AST_Node_Type::Bitwise_Or) : + case(AST_Node_Type::Comparison) : + assert(m_match_stack.size() > 1); + m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), + advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); + build_match(prev_stack_top, oper->text); + break; - case(AST_Node_Type::Logical_And) : - build_match(prev_stack_top); - break; - case(AST_Node_Type::Logical_Or) : - build_match(prev_stack_top); - break; + case(AST_Node_Type::Logical_And) : + build_match(prev_stack_top); + break; + case(AST_Node_Type::Logical_Or) : + build_match(prev_stack_top); + break; - default: - throw exception::eval_error("Internal error: unhandled ast_node", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Operator_Helper(t_precedence)); + default: + throw exception::eval_error("Internal error: unhandled ast_node", File_Position(m_position.line, m_position.col), *m_filename); + } } } } From 40694c798c4f4a488aa14568b5da0ed9173ea3f4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 10 Apr 2016 23:12:35 -0600 Subject: [PATCH 12/37] Eliminate Str_AST_Node --- .../chaiscript/language/chaiscript_common.hpp | 4 +-- .../chaiscript/language/chaiscript_eval.hpp | 13 +++------ .../chaiscript/language/chaiscript_parser.hpp | 29 +++++++------------ 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 7d0a6df..cb1266d 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -32,7 +32,7 @@ namespace chaiscript /// Types of AST nodes available to the parser and eval - enum class AST_Node_Type { Error, Id, Str, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, + enum class AST_Node_Type { Error, Id, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, @@ -44,7 +44,7 @@ namespace chaiscript /// Helper lookup to get the name of each node type const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { - static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Str", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", + static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index e1a2e19..ba36c7a 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -166,11 +166,6 @@ namespace chaiscript }; - struct Str_AST_Node final : AST_Node { - Str_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Str, std::move(t_loc)) { } - }; - struct Fun_Call_AST_Node final : AST_Node { Fun_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : @@ -1323,12 +1318,12 @@ namespace chaiscript struct Logical_And_AST_Node final : AST_Node { Logical_And_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Logical_And, std::move(t_loc), std::move(t_children)) - { assert(children.size() == 3); } + { assert(children.size() == 2); } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { return const_var(get_bool_condition(children[0]->eval(t_ss)) - && get_bool_condition(children[2]->eval(t_ss))); + && get_bool_condition(children[1]->eval(t_ss))); } std::string pretty_print() const override @@ -1340,12 +1335,12 @@ namespace chaiscript struct Logical_Or_AST_Node final : AST_Node { Logical_Or_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Logical_Or, std::move(t_loc), std::move(t_children)) - { assert(children.size() == 3); } + { assert(children.size() == 2); } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { return const_var(get_bool_condition(children[0]->eval(t_ss)) - || get_bool_condition(children[2]->eval(t_ss))); + || get_bool_condition(children[1]->eval(t_ss))); } std::string pretty_print() const override diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 879ab60..4980014 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1315,7 +1315,7 @@ namespace chaiscript } /// Reads (and potentially captures) a symbol group from input if it matches the parameter - bool Symbol(const char *t_s, const bool t_capture = false, const bool t_disallow_prevention=false) { + bool Symbol(const char *t_s, const bool t_disallow_prevention=false) { SkipWS(); const auto start = m_position; bool retval = Symbol_(t_s); @@ -1330,10 +1330,6 @@ namespace chaiscript } } - if ( t_capture && retval ) { - m_match_stack.push_back(make_node(Position::str(start, m_position), start.line, start.col)); - } - return retval; } @@ -2205,9 +2201,10 @@ namespace chaiscript return Var_Decl() || Dot_Fun_Array() || Prefix(); } - bool Operator_Helper(const size_t t_precedence) { + bool Operator_Helper(const size_t t_precedence, std::string &oper) { for (auto & elem : m_operator_matches[t_precedence]) { - if (Symbol(elem.c_str(), true)) { + if (Symbol(elem.c_str())) { + oper = elem; return true; } } @@ -2221,7 +2218,8 @@ namespace chaiscript if (t_precedence < m_operators.size()) { if (Operator(t_precedence+1)) { retval = true; - while (Operator_Helper(t_precedence)) { + std::string oper; + while (Operator_Helper(t_precedence, oper)) { while (Eol()) {} if (!Operator(t_precedence+1)) { throw exception::eval_error("Incomplete " @@ -2229,12 +2227,8 @@ namespace chaiscript File_Position(m_position.line, m_position.col), *m_filename); } - AST_NodePtr oper = m_match_stack.at(m_match_stack.size()-2); - switch (m_operators[t_precedence]) { case(AST_Node_Type::Ternary_Cond) : - m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), - advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); if (Symbol(":")) { if (!Operator(t_precedence+1)) { throw exception::eval_error("Incomplete " @@ -2258,17 +2252,14 @@ namespace chaiscript case(AST_Node_Type::Bitwise_Xor) : case(AST_Node_Type::Bitwise_Or) : case(AST_Node_Type::Comparison) : - assert(m_match_stack.size() > 1); - m_match_stack.erase(advance_copy(m_match_stack.begin(), m_match_stack.size() - 2), - advance_copy(m_match_stack.begin(), m_match_stack.size() - 1)); - build_match(prev_stack_top, oper->text); + build_match(prev_stack_top, oper); break; case(AST_Node_Type::Logical_And) : - build_match(prev_stack_top); + build_match(prev_stack_top, oper); break; case(AST_Node_Type::Logical_Or) : - build_match(prev_stack_top); + build_match(prev_stack_top, oper); break; default: @@ -2345,7 +2336,7 @@ namespace chaiscript if (Operator()) { for (const auto sym : {"=", ":=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", "&=", "^=", "|="}) { - if (Symbol(sym, false, true)) { + if (Symbol(sym, true)) { SkipWS(true); if (!Equation()) { throw exception::eval_error("Incomplete equation", File_Position(m_position.line, m_position.col), *m_filename); From fe8f8a89a7abc61c0e106888e3fcc70bb22e6899 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 11 Apr 2016 08:19:02 -0600 Subject: [PATCH 13/37] Implement constant expression folding --- .../chaiscript/language/chaiscript_eval.hpp | 1 + .../chaiscript/language/chaiscript_parser.hpp | 32 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index ba36c7a..6ef776b 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -737,6 +737,7 @@ namespace chaiscript } else { if (children.size() > 2) { size_t i = 2; + /// \todo these string comparisons are clunky while (i < children.size()) { if (children[i]->text == "else") { return children[i+1]->eval(t_ss); diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 4980014..d1d8084 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -2252,7 +2252,37 @@ namespace chaiscript case(AST_Node_Type::Bitwise_Xor) : case(AST_Node_Type::Bitwise_Or) : case(AST_Node_Type::Comparison) : - build_match(prev_stack_top, oper); + { + bool folded = false; + const auto size = m_match_stack.size(); + + try { + if (m_match_stack[size - 1]->identifier == AST_Node_Type::Constant + && m_match_stack[size - 2]->identifier == AST_Node_Type::Constant) { + const auto parsed = Operators::to_operator(oper); + if (parsed != Operators::Opers::invalid) { + const auto lhs = std::dynamic_pointer_cast(m_match_stack[size-2])->m_value; + const auto rhs = std::dynamic_pointer_cast(m_match_stack[size-1])->m_value; + if (lhs.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) { + const auto val = Boxed_Number::do_oper(parsed, lhs, rhs); + const auto start = m_match_stack[size-2]->location; + const auto match = m_match_stack[size-2]->text + " " + oper + " " + m_match_stack[size-1]->text; + m_match_stack.resize(size-2); + m_match_stack.push_back( + make_node(std::move(match), start.start.line, start.start.column, std::move(val))); + folded = true; + } + } + } + } catch (const std::exception &) { + //failure to fold + } + + if (!folded) { + build_match(prev_stack_top, oper); + } + } + break; case(AST_Node_Type::Logical_And) : From b594043eef0e9dd06db3d8c08007c4f6ef1c1321 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 11 Apr 2016 09:36:23 -0600 Subject: [PATCH 14/37] Clean up redundant code --- include/chaiscript/dispatchkit/bootstrap.hpp | 5 +-- .../chaiscript/language/chaiscript_common.hpp | 5 --- .../chaiscript/language/chaiscript_engine.hpp | 42 +++---------------- 3 files changed, 8 insertions(+), 44 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 1f519dc..6776e9f 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -629,14 +629,13 @@ namespace chaiscript {fun(&AST_Node::start), "start"}, {fun(&AST_Node::end), "end"}, {fun(&AST_Node::to_string), "to_string"}, - {fun(std::function (const chaiscript::AST_Node &t_node)>([](const chaiscript::AST_Node &t_node) -> std::vector { + {fun([](const chaiscript::AST_Node &t_node) -> std::vector { std::vector retval; std::transform(t_node.children.begin(), t_node.children.end(), std::back_inserter(retval), &chaiscript::var &>); return retval; - })), "children"}, - {fun(&AST_Node::replace_child), "replace_child"} + }), "children"} } ); diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index cb1266d..14b9034 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -508,11 +508,6 @@ namespace chaiscript } - void replace_child(const AST_NodePtr &t_child, const AST_NodePtr &t_new_child) - { - std::replace(children.begin(), children.end(), t_child, t_new_child); - } - virtual ~AST_Node() = default; AST_Node(AST_Node &&) = default; AST_Node &operator=(AST_Node &&) = default; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index bc00f7a..84f25bc 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -619,16 +619,14 @@ namespace chaiscript std::string errstring; - for (std::vector::const_iterator itr = errors.begin(); - itr != errors.end(); - ++itr) + for (const auto &err : errors) { if (!errstring.empty()) { errstring += "; "; } - errstring += itr->what(); + errstring += err.what(); } throw chaiscript::exception::load_module_error("Unable to find module: " + t_module_name + " Errors: " + errstring); @@ -668,14 +666,7 @@ namespace chaiscript /// \throw chaiscript::exception::eval_error In the case that evaluation fails. Boxed_Value operator()(const std::string &t_script, const Exception_Handler &t_handler = Exception_Handler()) { - try { - return do_eval(t_script); - } catch (Boxed_Value &bv) { - if (t_handler) { - t_handler->handle(bv, m_engine); - } - throw; - } + return eval(t_script, t_handler); } /// \brief Evaluates a string and returns a typesafe result. @@ -694,14 +685,7 @@ namespace chaiscript template T eval(const std::string &t_input, const Exception_Handler &t_handler = Exception_Handler(), const std::string &t_filename="__EVAL__") { - try { - return m_engine.boxed_cast(do_eval(t_input, t_filename)); - } catch (Boxed_Value &bv) { - if (t_handler) { - t_handler->handle(bv, m_engine); - } - throw; - } + return m_engine.boxed_cast(eval(t_input, t_handler, t_filename)); } /// \brief casts an object while applying any Dynamic_Conversion available @@ -740,14 +724,7 @@ namespace chaiscript /// \return result of the script execution /// \throw chaiscript::exception::eval_error In the case that evaluation fails. Boxed_Value eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { - try { - return do_eval(load_file(t_filename), t_filename); - } catch (Boxed_Value &bv) { - if (t_handler) { - t_handler->handle(bv, m_engine); - } - throw; - } + return eval(load_file(t_filename), t_handler, t_filename); } /// \brief Loads the file specified by filename, evaluates it, and returns the type safe result. @@ -760,14 +737,7 @@ namespace chaiscript /// to the requested type. template T eval_file(const std::string &t_filename, const Exception_Handler &t_handler = Exception_Handler()) { - try { - return m_engine.boxed_cast(do_eval(load_file(t_filename), t_filename)); - } catch (Boxed_Value &bv) { - if (t_handler) { - t_handler->handle(bv, m_engine); - } - throw; - } + return m_engine.boxed_cast(eval_file(t_filename, t_handler)); } }; From 8d808f75c0a113ca9ec12cac883435e8f6e28b38 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 13 Apr 2016 12:04:55 -0600 Subject: [PATCH 15/37] Remove pretty_print functionality --- .../chaiscript/language/chaiscript_common.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 85 ------------------- 2 files changed, 2 insertions(+), 87 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 14b9034..ca29b16 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -461,7 +461,7 @@ namespace chaiscript return location.end; } - virtual std::string pretty_print() const + std::string pretty_print() const { std::ostringstream oss; @@ -528,7 +528,7 @@ namespace chaiscript } private: - // Copy and assignment explicitly unimplemented + // Copy and assignment explicitly deleted AST_Node(const AST_Node &) = delete; AST_Node& operator=(const AST_Node &) = delete; }; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 6ef776b..0b9311d 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -93,11 +93,6 @@ namespace chaiscript return do_oper(t_ss, m_oper, text, lhs, rhs); } - std::string pretty_print() const override - { - return "(" + this->children[0]->pretty_print() + " " + text + " " + this->children[1]->pretty_print() + ")"; - } - protected: Boxed_Value do_oper(const chaiscript::detail::Dispatch_State &t_ss, Operators::Opers t_oper, const std::string &t_oper_string, const Boxed_Value &t_lhs, const Boxed_Value &t_rhs) const @@ -212,25 +207,6 @@ namespace chaiscript } } - std::string pretty_print() const override - { - std::ostringstream oss; - - int count = 0; - for (const auto &child : this->children) { - oss << child->pretty_print(); - - if (count == 0) - { - oss << "("; - } - ++count; - } - - oss << ")"; - - return oss.str(); - } }; @@ -240,40 +216,12 @@ namespace chaiscript Arg_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Arg_List, std::move(t_loc), std::move(t_children)) { } - std::string pretty_print() const override - { - std::ostringstream oss; - for (size_t j = 0; j < this->children.size(); ++j) { - if (j != 0) - { - oss << " "; - } - - oss << this->children[j]->pretty_print(); - } - - return oss.str(); - } }; struct Arg_List_AST_Node final : AST_Node { Arg_List_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Arg_List, std::move(t_loc), std::move(t_children)) { } - std::string pretty_print() const override - { - std::ostringstream oss; - for (size_t j = 0; j < this->children.size(); ++j) { - if (j != 0) - { - oss << ", "; - } - - oss << this->children[j]->pretty_print(); - } - - return oss.str(); - } static std::string get_arg_name(const AST_NodePtr &t_node) { if (t_node->children.empty()) @@ -451,10 +399,6 @@ namespace chaiscript } - std::string pretty_print() const override - { - return "var " + this->children[0]->text; - } }; @@ -477,20 +421,6 @@ namespace chaiscript } } - std::string pretty_print() const override - { - std::ostringstream oss; - oss << this->children[0]->pretty_print(); - - for (size_t i = 1; i < this->children.size(); ++i) - { - oss << "["; - oss << this->children[i]->pretty_print(); - oss << "]"; - } - - return oss.str(); - } private: mutable std::atomic_uint_fast32_t m_loc; @@ -886,11 +816,6 @@ namespace chaiscript } } - std::string pretty_print() const override - { - return "[" + AST_Node::pretty_print() + "]"; - } - private: mutable std::atomic_uint_fast32_t m_loc; }; @@ -1327,10 +1252,6 @@ namespace chaiscript && get_bool_condition(children[1]->eval(t_ss))); } - std::string pretty_print() const override - { - return "(" + AST_Node::pretty_print() + ")"; - } }; struct Logical_Or_AST_Node final : AST_Node { @@ -1343,12 +1264,6 @@ namespace chaiscript return const_var(get_bool_condition(children[0]->eval(t_ss)) || get_bool_condition(children[1]->eval(t_ss))); } - - std::string pretty_print() const override - { - return "(" + AST_Node::pretty_print() + ")"; - } - }; } From 6f0d02f158bc4a141e3fed452b69c2f7ccf868da Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 13 Apr 2016 14:09:08 -0600 Subject: [PATCH 16/37] Massive simplification of boxed_cast. More planned --- include/chaiscript/dispatchkit/boxed_cast.hpp | 2 +- .../dispatchkit/boxed_cast_helper.hpp | 103 +++++++----------- .../chaiscript/dispatchkit/boxed_number.hpp | 4 +- .../chaiscript/dispatchkit/dispatchkit.hpp | 2 +- .../chaiscript/dispatchkit/function_call.hpp | 12 +- .../chaiscript/language/chaiscript_engine.hpp | 2 +- 6 files changed, 46 insertions(+), 79 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index 5a11ee9..395cf83 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -69,7 +69,7 @@ namespace chaiscript /// assert(i == 5); /// \endcode template - typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr) + auto boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr) -> decltype(detail::Cast_Helper::cast(bv, nullptr)) { if (!t_conversions || bv.get_type_info().bare_equal(user_type()) || (t_conversions && !(*t_conversions)->convertable_type())) { try { diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index da1e222..36c15f7 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -29,21 +29,36 @@ namespace chaiscript throw std::runtime_error("Attempted to dereference null Boxed_Value"); } + const void *verify_type(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { + if (!ob.get_type_info().bare_equal_type_info(ti)) { + throw chaiscript::detail::exception::bad_any_cast(); + } else { + return throw_if_null(ptr); + } + } + + void *verify_type(const Boxed_Value &ob, const std::type_info &ti, void *ptr) { + if (ptr == nullptr || !ob.get_type_info().bare_equal_type_info(ti)) { + throw chaiscript::detail::exception::bad_any_cast(); + } else { + return ptr; + } + } + + /* + template> + Result cast_helper_inner(const Boxed_Value &ob, const Type_Conversions_State *) + { + } +*/ + /// Generic Cast_Helper_Inner, for casting to any type template struct Cast_Helper_Inner { - typedef typename std::add_const::type Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static Result cast(const Boxed_Value &ob, const Type_Conversions_State *) { - if (ob.get_type_info().bare_equal_type_info(typeid(Result))) - { - auto p = throw_if_null(ob.get_const_ptr()); - return *static_cast(p); - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } + return *static_cast(verify_type(ob, typeid(Result), ob.get_const_ptr())); } }; @@ -57,15 +72,9 @@ namespace chaiscript template struct Cast_Helper_Inner { - typedef const Result * Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static auto cast(const Boxed_Value &ob, const Type_Conversions_State *) { - if (ob.get_type_info().bare_equal_type_info(typeid(Result))) - { - return static_cast(ob.get_const_ptr()); - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } + return static_cast(verify_type(ob, typeid(Result), ob.get_const_ptr())); } }; @@ -73,15 +82,9 @@ namespace chaiscript template struct Cast_Helper_Inner { - typedef Result * Result_Type; - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static auto cast(const Boxed_Value &ob, const Type_Conversions_State *) { - if (!ob.get_type_info().is_const() && ob.get_type_info() == typeid(Result)) - { - return static_cast(ob.get_ptr()); - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } + return static_cast(verify_type(ob, typeid(Result), ob.get_ptr())); } }; @@ -100,17 +103,9 @@ namespace chaiscript template struct Cast_Helper_Inner { - typedef const Result& Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static const Result & cast(const Boxed_Value &ob, const Type_Conversions_State *) { - if (ob.get_type_info().bare_equal_type_info(typeid(Result))) - { - auto p = throw_if_null(ob.get_const_ptr()); - return *static_cast(p); - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } + return *static_cast(verify_type(ob, typeid(Result), ob.get_const_ptr())); } }; @@ -120,16 +115,9 @@ namespace chaiscript template struct Cast_Helper_Inner { - typedef Result& Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static Result& cast(const Boxed_Value &ob, const Type_Conversions_State *) { - if (!ob.get_type_info().is_const() && ob.get_type_info().bare_equal_type_info(typeid(Result))) - { - return *(static_cast(throw_if_null(ob.get_ptr()))); - } else { - throw chaiscript::detail::exception::bad_any_cast(); - } + return *static_cast(verify_type(ob, typeid(Result), ob.get_ptr())); } }; @@ -137,9 +125,7 @@ namespace chaiscript template struct Cast_Helper_Inner > { - typedef std::shared_ptr Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static auto cast(const Boxed_Value &ob, const Type_Conversions_State *) { return ob.get().cast >(); } @@ -149,9 +135,7 @@ namespace chaiscript template struct Cast_Helper_Inner > { - typedef std::shared_ptr Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static auto cast(const Boxed_Value &ob, const Type_Conversions_State *) { if (!ob.get_type_info().is_const()) { @@ -177,10 +161,7 @@ namespace chaiscript struct Cast_Helper_Inner &> { static_assert(!std::is_const::value, "Non-const reference to std::shared_ptr is not supported"); - - typedef Boxed_Value::Sentinel Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static auto cast(const Boxed_Value &ob, const Type_Conversions_State *) { std::shared_ptr &res = ob.get().cast >(); return ob.pointer_sentinel(res); @@ -204,9 +185,7 @@ namespace chaiscript template<> struct Cast_Helper_Inner { - typedef Boxed_Value Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static Boxed_Value cast(const Boxed_Value &ob, const Type_Conversions_State *) { return ob; } @@ -216,9 +195,7 @@ namespace chaiscript template<> struct Cast_Helper_Inner { - typedef std::reference_wrapper Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static std::reference_wrapper cast(const Boxed_Value &ob, const Type_Conversions_State *) { return std::ref(const_cast(ob)); } @@ -272,9 +249,7 @@ namespace chaiscript template struct Cast_Helper { - typedef typename Cast_Helper_Inner::Result_Type Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) + static auto cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) -> decltype(Cast_Helper_Inner::cast(ob, t_conversions)) { return Cast_Helper_Inner::cast(ob, t_conversions); } diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index 6bbf088..ad2775b 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -1009,9 +1009,7 @@ namespace chaiscript template<> struct Cast_Helper { - typedef Boxed_Number Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *) + static Boxed_Number cast(const Boxed_Value &ob, const Type_Conversions_State *) { return Boxed_Number(ob); } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index f10d340..1c5809c 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -424,7 +424,7 @@ namespace chaiscript /// \brief casts an object while applying any Dynamic_Conversion available template - typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) const + auto boxed_cast(const Boxed_Value &bv) const -> decltype(chaiscript::boxed_cast(bv, nullptr)) { Type_Conversions_State state(m_conversions, m_conversions.conversion_saves()); return chaiscript::boxed_cast(bv, &state); diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 990be95..3efb703 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -81,9 +81,7 @@ namespace chaiscript template struct Cast_Helper &> { - typedef std::function Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) + static std::function cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { @@ -98,9 +96,7 @@ namespace chaiscript template struct Cast_Helper > { - typedef std::function Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) + static std::function cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { @@ -115,9 +111,7 @@ namespace chaiscript template struct Cast_Helper > { - typedef std::function Result_Type; - - static Result_Type cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) + static std::function cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { if (ob.get_type_info().bare_equal(user_type())) { diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 84f25bc..761bd61 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -690,7 +690,7 @@ namespace chaiscript /// \brief casts an object while applying any Dynamic_Conversion available template - typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) const + auto boxed_cast(const Boxed_Value &bv) const -> decltype(m_engine.boxed_cast(bv)) { return m_engine.boxed_cast(bv); } From 9603d3910a5a8427abb9e67f5f0c6d8f79a18d5e Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 13 Apr 2016 15:26:36 -0600 Subject: [PATCH 17/37] Get multifile compiling --- include/chaiscript/dispatchkit/boxed_cast_helper.hpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index 36c15f7..5178a73 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -29,7 +29,7 @@ namespace chaiscript throw std::runtime_error("Attempted to dereference null Boxed_Value"); } - const void *verify_type(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { + static const void *verify_type(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { if (!ob.get_type_info().bare_equal_type_info(ti)) { throw chaiscript::detail::exception::bad_any_cast(); } else { @@ -37,7 +37,7 @@ namespace chaiscript } } - void *verify_type(const Boxed_Value &ob, const std::type_info &ti, void *ptr) { + static void *verify_type(const Boxed_Value &ob, const std::type_info &ti, void *ptr) { if (ptr == nullptr || !ob.get_type_info().bare_equal_type_info(ti)) { throw chaiscript::detail::exception::bad_any_cast(); } else { @@ -45,13 +45,6 @@ namespace chaiscript } } - /* - template> - Result cast_helper_inner(const Boxed_Value &ob, const Type_Conversions_State *) - { - } -*/ - /// Generic Cast_Helper_Inner, for casting to any type template struct Cast_Helper_Inner From 5e0a882b182d7a2c5a848036a5abe6d6bd0f8645 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 13 Apr 2016 21:08:25 -0600 Subject: [PATCH 18/37] Bootstrap simplifications --- include/chaiscript/dispatchkit/bootstrap.hpp | 48 ++++---------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 4c0b5a4..17352bc 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -138,15 +138,6 @@ namespace chaiscript } - /// to_string function for internal use. Uses ostream operator<< - template - std::string to_string(Input i) - { - std::stringstream ss; - ss << i; - return ss.str(); - } - /// Internal function for converting from a string to a value /// uses ostream operator >> to perform the conversion template @@ -288,8 +279,6 @@ namespace chaiscript m.add(fun(&Boxed_Number::product), "*"); m.add(fun(&Boxed_Number::remainder), "%"); m.add(fun(&Boxed_Number::shift_right), ">>"); - - } /// Create a bound function object. The first param is the function to bind @@ -329,26 +318,6 @@ namespace chaiscript } } - static void throw_exception(const Boxed_Value &bv) { - throw bv; - } - - static std::string what(const std::exception &e) - { - return e.what(); - } - - /// Boolean specialization of internal to_string function - static std::string bool_to_string(bool b) - { - if (b) - { - return "true"; - } else { - return "false"; - } - } - template static std::vector do_return_boxed_value_vector(FunctionType f, const dispatch::Proxy_Function_Base *b) @@ -384,7 +353,7 @@ namespace chaiscript } template - static std::function (const dispatch::Proxy_Function_Base*)> return_boxed_value_vector(const Function &f) + static auto return_boxed_value_vector(const Function &f) { return [f](const dispatch::Proxy_Function_Base *b) { return do_return_boxed_value_vector(f, b); @@ -414,6 +383,7 @@ namespace chaiscript m.add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_param_types)), "get_param_types"); m.add(fun(return_boxed_value_vector(&dispatch::Proxy_Function_Base::get_contained_functions)), "get_contained_functions"); + m.add(fun([](const std::exception &e){ return std::string(e.what()); }), "what"); m.add(user_type(), "out_of_range"); m.add(user_type(), "logic_error"); @@ -425,7 +395,6 @@ namespace chaiscript m.add(chaiscript::base_class()); m.add(constructor(), "runtime_error"); - m.add(fun(std::function(&what)), "what"); m.add(user_type(), "Dynamic_Object"); m.add(constructor(), "Dynamic_Object"); @@ -520,13 +489,12 @@ namespace chaiscript operators::equal(m); operators::not_equal(m); - m.add(fun([](const std::string &s) -> std::string { return s; }), "to_string"); - m.add(fun(&Bootstrap::bool_to_string), "to_string"); + m.add(fun([](const std::string &s) { return s; }), "to_string"); + m.add(fun([](const bool b) { return std::string(b?"true":"false"); }), "to_string"); m.add(fun(&unknown_assign), "="); - m.add(fun(&throw_exception), "throw"); - m.add(fun(&what), "what"); + m.add(fun([](const Boxed_Value &bv) { throw bv; }), "throw"); - m.add(fun(&to_string), "to_string"); + m.add(fun([](const char c) { return std::string(1, c); }), "to_string"); m.add(fun(&Boxed_Number::to_string), "to_string"); bootstrap_pod_type("double", m); @@ -593,13 +561,13 @@ namespace chaiscript { }, { {fun(&chaiscript::exception::eval_error::reason), "reason"}, {fun(&chaiscript::exception::eval_error::pretty_print), "pretty_print"}, - {fun(std::function (const chaiscript::exception::eval_error &t_eval_error)>([](const chaiscript::exception::eval_error &t_eval_error) -> std::vector { + {fun([](const chaiscript::exception::eval_error &t_eval_error) { std::vector retval; std::transform(t_eval_error.call_stack.begin(), t_eval_error.call_stack.end(), std::back_inserter(retval), &chaiscript::var &>); return retval; - })), "call_stack"} } + }), "call_stack"} } ); From 720395e47a280ec54130b470ef81482ba5eb4c7f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 14 Apr 2016 09:31:38 -0600 Subject: [PATCH 19/37] clean up reflection tests for new capabilities --- unittests/3.x/reflection_test.chai | 36 ------------------------------ unittests/reflection_test.chai | 15 ++----------- 2 files changed, 2 insertions(+), 49 deletions(-) delete mode 100644 unittests/3.x/reflection_test.chai diff --git a/unittests/3.x/reflection_test.chai b/unittests/3.x/reflection_test.chai deleted file mode 100644 index 25a2416..0000000 --- a/unittests/3.x/reflection_test.chai +++ /dev/null @@ -1,36 +0,0 @@ -var parser := ChaiScript_Parser() -var parse_success = parser.parse("3 + 4", "INPUT") -var a := parser.ast() - -assert_equal(eval(a), 7) - -var childs := a.children.front().children -var node := childs[0] - -var parser2 := ChaiScript_Parser() -parser2.parse("9", "INPUT") - - -a.children.front().replace_child(childs[0], parser2.ast()) - -assert_equal(eval(a), 13) -assert_equal(node.filename, "INPUT") - - - -def my_fun() -{ - return 1; -} - - -assert_equal(true, my_fun.has_parse_tree()); -assert_equal(false, `+`.has_parse_tree()); - -assert_throws("Function does not have a parse tree", fun() { `+`.get_parse_tree(); } ); - -var parsetree := my_fun.get_parse_tree(); - -assert_equal(1, eval(parsetree)); - -print(parsetree.text()); diff --git a/unittests/reflection_test.chai b/unittests/reflection_test.chai index 16ef7e9..80e8f26 100644 --- a/unittests/reflection_test.chai +++ b/unittests/reflection_test.chai @@ -4,19 +4,8 @@ auto& a = parser.ast() assert_equal(eval(a), 7) -auto& childs = a.children.front().children -auto& node = childs[0] - -auto& parser2 = ChaiScript_Parser() -parser2.parse("9", "INPUT") - - -a.children.front().replace_child(childs[0], parser2.ast()) - -assert_equal(eval(a), 13) -assert_equal(node.filename, "INPUT") - - +assert_equal(1, a.children.size()); +assert_equal("3 + 4", a.children[0].text()); def my_fun() { From 49dfdfd15afb30365dac96701750ad31744971fd Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 14 Apr 2016 12:03:55 -0600 Subject: [PATCH 20/37] Fix some boxed_cast and exception issues --- include/chaiscript/dispatchkit/bootstrap.hpp | 2 ++ include/chaiscript/dispatchkit/boxed_cast.hpp | 8 ++++---- .../chaiscript/dispatchkit/boxed_cast_helper.hpp | 16 ++++++++-------- include/chaiscript/dispatchkit/dispatchkit.hpp | 4 ++-- .../chaiscript/language/chaiscript_engine.hpp | 4 ++-- include/chaiscript/utility/utility.hpp | 2 +- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 17352bc..74614f8 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -548,9 +548,11 @@ namespace chaiscript m.add(chaiscript::fun(&get_parse_tree), "get_parse_tree"); m.add(chaiscript::base_class()); + m.add(chaiscript::base_class()); m.add(chaiscript::user_type(), "arithmetic_error"); m.add(chaiscript::base_class()); + m.add(chaiscript::base_class()); // chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index 395cf83..7fbe78d 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -69,11 +69,11 @@ namespace chaiscript /// assert(i == 5); /// \endcode template - auto boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr) -> decltype(detail::Cast_Helper::cast(bv, nullptr)) + decltype(auto) boxed_cast(const Boxed_Value &bv, const Type_Conversions_State *t_conversions = nullptr) { if (!t_conversions || bv.get_type_info().bare_equal(user_type()) || (t_conversions && !(*t_conversions)->convertable_type())) { try { - return detail::Cast_Helper::cast(bv, t_conversions); + return(detail::Cast_Helper::cast(bv, t_conversions)); } catch (const chaiscript::detail::exception::bad_any_cast &) { } } @@ -84,11 +84,11 @@ namespace chaiscript try { // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it // either way, we are not responsible if it doesn't work - return detail::Cast_Helper::cast((*t_conversions)->boxed_type_conversion(t_conversions->saves(), bv), t_conversions); + return(detail::Cast_Helper::cast((*t_conversions)->boxed_type_conversion(t_conversions->saves(), bv), t_conversions)); } catch (...) { try { // try going the other way - return detail::Cast_Helper::cast((*t_conversions)->boxed_type_down_conversion(t_conversions->saves(), bv), t_conversions); + return(detail::Cast_Helper::cast((*t_conversions)->boxed_type_down_conversion(t_conversions->saves(), bv), t_conversions)); } catch (const chaiscript::detail::exception::bad_any_cast &) { throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type)); } diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index 5178a73..9476e0a 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -30,18 +30,18 @@ namespace chaiscript } static const void *verify_type(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { - if (!ob.get_type_info().bare_equal_type_info(ti)) { - throw chaiscript::detail::exception::bad_any_cast(); - } else { + if (ob.get_type_info().bare_equal_type_info(ti)) { return throw_if_null(ptr); + } else { + throw chaiscript::detail::exception::bad_any_cast(); } } static void *verify_type(const Boxed_Value &ob, const std::type_info &ti, void *ptr) { - if (ptr == nullptr || !ob.get_type_info().bare_equal_type_info(ti)) { - throw chaiscript::detail::exception::bad_any_cast(); + if (!ob.is_const() && ob.get_type_info().bare_equal_type_info(ti)) { + return throw_if_null(ptr); } else { - return ptr; + throw chaiscript::detail::exception::bad_any_cast(); } } @@ -242,9 +242,9 @@ namespace chaiscript template struct Cast_Helper { - static auto cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) -> decltype(Cast_Helper_Inner::cast(ob, t_conversions)) + static decltype(auto) cast(const Boxed_Value &ob, const Type_Conversions_State *t_conversions) { - return Cast_Helper_Inner::cast(ob, t_conversions); + return(Cast_Helper_Inner::cast(ob, t_conversions)); } }; } diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 1c5809c..b5ed3f7 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -424,10 +424,10 @@ namespace chaiscript /// \brief casts an object while applying any Dynamic_Conversion available template - auto boxed_cast(const Boxed_Value &bv) const -> decltype(chaiscript::boxed_cast(bv, nullptr)) + decltype(auto) boxed_cast(const Boxed_Value &bv) const { Type_Conversions_State state(m_conversions, m_conversions.conversion_saves()); - return chaiscript::boxed_cast(bv, &state); + return(chaiscript::boxed_cast(bv, &state)); } /// Add a new conversion for upcasting to a base class diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 761bd61..fca14de 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -690,9 +690,9 @@ namespace chaiscript /// \brief casts an object while applying any Dynamic_Conversion available template - auto boxed_cast(const Boxed_Value &bv) const -> decltype(m_engine.boxed_cast(bv)) + decltype(auto) boxed_cast(const Boxed_Value &bv) const { - return m_engine.boxed_cast(bv); + return(m_engine.boxed_cast(bv)); } diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 1ca0dfb..87dd876 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -15,7 +15,7 @@ #include "../chaiscript.hpp" #include "../dispatchkit/proxy_functions.hpp" #include "../dispatchkit/type_info.hpp" -#include "../dispatchkit/operators.hpp" +//#include "../dispatchkit/operators.hpp" namespace chaiscript From 7d9dbc3d86582c36cb9e5a40212c33f2fe70b013 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Thu, 14 Apr 2016 19:06:37 -0600 Subject: [PATCH 21/37] Fix some boxed_cast issues introduced with refactor --- .../dispatchkit/boxed_cast_helper.hpp | 25 ++++++++++++++++--- include/chaiscript/utility/utility.hpp | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index 9476e0a..104abc7 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -29,6 +29,23 @@ namespace chaiscript throw std::runtime_error("Attempted to dereference null Boxed_Value"); } + static const void *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { + if (ob.get_type_info() == ti) { + return ptr; + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + } + + static void *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, void *ptr) { + if (!ob.is_const() && ob.get_type_info() == ti) { + return ptr; + } else { + throw chaiscript::detail::exception::bad_any_cast(); + } + } + + static const void *verify_type(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { if (ob.get_type_info().bare_equal_type_info(ti)) { return throw_if_null(ptr); @@ -65,9 +82,9 @@ namespace chaiscript template struct Cast_Helper_Inner { - static auto cast(const Boxed_Value &ob, const Type_Conversions_State *) + static const Result * cast(const Boxed_Value &ob, const Type_Conversions_State *) { - return static_cast(verify_type(ob, typeid(Result), ob.get_const_ptr())); + return static_cast(verify_type_no_throw(ob, typeid(Result), ob.get_const_ptr())); } }; @@ -75,9 +92,9 @@ namespace chaiscript template struct Cast_Helper_Inner { - static auto cast(const Boxed_Value &ob, const Type_Conversions_State *) + static Result * cast(const Boxed_Value &ob, const Type_Conversions_State *) { - return static_cast(verify_type(ob, typeid(Result), ob.get_ptr())); + return static_cast(verify_type_no_throw(ob, typeid(Result), ob.get_ptr())); } }; diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 87dd876..1ca0dfb 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -15,7 +15,7 @@ #include "../chaiscript.hpp" #include "../dispatchkit/proxy_functions.hpp" #include "../dispatchkit/type_info.hpp" -//#include "../dispatchkit/operators.hpp" +#include "../dispatchkit/operators.hpp" namespace chaiscript From 6fa83bca857e277c1ad5fdd98162619135eb88a1 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 15 Apr 2016 15:31:19 -0600 Subject: [PATCH 22/37] Remove Do_Call helper class --- .../chaiscript/dispatchkit/boxed_value.hpp | 77 +++++++++---------- .../dispatchkit/proxy_functions.hpp | 5 +- .../dispatchkit/proxy_functions_detail.hpp | 52 ++++--------- 3 files changed, 54 insertions(+), 80 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 538391f..d394d69 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -226,48 +226,47 @@ namespace chaiscript return m_data->m_type_info.bare_equal(ti); } - template - struct Sentinel { - Sentinel(std::shared_ptr &ptr, Data &data) - : m_ptr(ptr), m_data(data) - { - } - - ~Sentinel() - { - // save new pointer data - m_data.get().m_data_ptr = m_ptr.get().get(); - m_data.get().m_const_data_ptr = m_ptr.get().get(); - } - - Sentinel& operator=(Sentinel&&s) { - m_ptr = std::move(s.m_ptr); - m_data = std::move(s.m_data); - } - - Sentinel(Sentinel &&s) - : m_ptr(std::move(s.m_ptr)), - m_data(std::move(s.m_data)) - { - } - - operator std::shared_ptr&() const - { - return m_ptr.get(); - } - - Sentinel &operator=(const Sentinel &) = delete; - Sentinel(Sentinel&) = delete; - - std::reference_wrapper> m_ptr; - std::reference_wrapper m_data; - }; - template - Sentinel pointer_sentinel(std::shared_ptr &ptr) const + auto pointer_sentinel(std::shared_ptr &ptr) const { - return Sentinel(ptr, *(m_data.get())); + struct Sentinel { + Sentinel(std::shared_ptr &ptr, Data &data) + : m_ptr(ptr), m_data(data) + { + } + + ~Sentinel() + { + // save new pointer data + m_data.get().m_data_ptr = m_ptr.get().get(); + m_data.get().m_const_data_ptr = m_ptr.get().get(); + } + + Sentinel& operator=(Sentinel&&s) { + m_ptr = std::move(s.m_ptr); + m_data = std::move(s.m_data); + } + + Sentinel(Sentinel &&s) + : m_ptr(std::move(s.m_ptr)), + m_data(std::move(s.m_data)) + { + } + + operator std::shared_ptr&() const + { + return m_ptr.get(); + } + + Sentinel &operator=(const Sentinel &) = delete; + Sentinel(Sentinel&) = delete; + + std::reference_wrapper> m_ptr; + std::reference_wrapper m_data; + }; + + return Sentinel(ptr, *(m_data.get())); } bool is_null() const noexcept diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index e7a8ad9..7a2fa28 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -595,8 +595,7 @@ namespace chaiscript protected: Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { - typedef typename detail::Function_Signature::Return_Type Return_Type; - return detail::Do_Call::template go(m_f, params, t_conversions); + return detail::call_func(detail::Function_Signature(), m_f, params, t_conversions); } private: @@ -648,7 +647,7 @@ namespace chaiscript protected: Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { - return detail::Do_Call::result_type>::template go(m_f.get(), params, t_conversions); + return detail::call_func(detail::Function_Signature(), m_f.get(), params, t_conversions); } diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 69b88a8..54a1c6e 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -99,17 +99,23 @@ namespace chaiscript } - /** - * Used by Proxy_Function_Impl to perform typesafe execution of a function. - * The function attempts to unbox each parameter to the expected type. - * if any unboxing fails the execution of the function fails and - * the bad_boxed_cast is passed up to the caller. - */ + /// Used by Proxy_Function_Impl to perform typesafe execution of a function. + /// The function attempts to unbox each parameter to the expected type. + /// if any unboxing fails the execution of the function fails and + /// the bad_boxed_cast is passed up to the caller. template - Ret call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, + Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, const std::vector ¶ms, const Type_Conversions_State &t_conversions) { - return call_func(sig, std::index_sequence_for{}, f, params, t_conversions); + return Handle_Return::handle(call_func(sig, std::index_sequence_for{}, f, params, t_conversions)); + } + + template + Boxed_Value call_func(const chaiscript::dispatch::detail::Function_Signature &sig, const Callable &f, + const std::vector ¶ms, const Type_Conversions_State &t_conversions) + { + call_func(sig, std::index_sequence_for{}, f, params, t_conversions); + return Handle_Return::handle(); } } @@ -118,34 +124,4 @@ namespace chaiscript } -namespace chaiscript -{ - namespace dispatch - { - namespace detail - { - template - struct Do_Call - { - template - static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - return Handle_Return::handle(call_func(Function_Signature(), fun, params, t_conversions)); - } - }; - - template<> - struct Do_Call - { - template - static Boxed_Value go(const Callable &fun, const std::vector ¶ms, const Type_Conversions_State &t_conversions) - { - call_func(Function_Signature(), fun, params, t_conversions); - return Handle_Return::handle(); - } - }; - } - } -} - #endif From 1a4261444161bfc3d5c4bf89e741d8e7152581a9 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 15 Apr 2016 23:02:42 -0600 Subject: [PATCH 23/37] Remove unnecessary code --- .../dispatchkit/boxed_cast_helper.hpp | 12 +- .../chaiscript/dispatchkit/boxed_value.hpp | 12 +- .../chaiscript/dispatchkit/handle_return.hpp | 13 +- include/chaiscript/dispatchkit/operators.hpp | 278 +++--------------- .../dispatchkit/proxy_functions.hpp | 4 +- 5 files changed, 53 insertions(+), 266 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp index 104abc7..6347437 100644 --- a/include/chaiscript/dispatchkit/boxed_cast_helper.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast_helper.hpp @@ -29,7 +29,8 @@ namespace chaiscript throw std::runtime_error("Attempted to dereference null Boxed_Value"); } - static const void *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { + template + static const T *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, const T *ptr) { if (ob.get_type_info() == ti) { return ptr; } else { @@ -37,7 +38,8 @@ namespace chaiscript } } - static void *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, void *ptr) { + template + static T *verify_type_no_throw(const Boxed_Value &ob, const std::type_info &ti, T *ptr) { if (!ob.is_const() && ob.get_type_info() == ti) { return ptr; } else { @@ -46,7 +48,8 @@ namespace chaiscript } - static const void *verify_type(const Boxed_Value &ob, const std::type_info &ti, const void *ptr) { + template + static const T *verify_type(const Boxed_Value &ob, const std::type_info &ti, const T *ptr) { if (ob.get_type_info().bare_equal_type_info(ti)) { return throw_if_null(ptr); } else { @@ -54,7 +57,8 @@ namespace chaiscript } } - static void *verify_type(const Boxed_Value &ob, const std::type_info &ti, void *ptr) { + template + static T *verify_type(const Boxed_Value &ob, const std::type_info &ti, T *ptr) { if (!ob.is_const() && ob.get_type_info().bare_equal_type_info(ti)) { return throw_if_null(ptr); } else { diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index d394d69..1e0ec99 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -243,16 +243,8 @@ namespace chaiscript m_data.get().m_const_data_ptr = m_ptr.get().get(); } - Sentinel& operator=(Sentinel&&s) { - m_ptr = std::move(s.m_ptr); - m_data = std::move(s.m_data); - } - - Sentinel(Sentinel &&s) - : m_ptr(std::move(s.m_ptr)), - m_data(std::move(s.m_data)) - { - } + Sentinel& operator=(Sentinel&&s) = default; + Sentinel(Sentinel &&s) = default; operator std::shared_ptr&() const { diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index ca353ec..8ac2d9e 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -146,6 +146,14 @@ namespace chaiscript } }; + template + struct Handle_Return + { + static Boxed_Value handle(const Ret &r) + { + return Boxed_Value(std::cref(r)); + } + }; template struct Handle_Return @@ -154,11 +162,6 @@ namespace chaiscript { return Boxed_Value(std::ref(r)); } - - static Boxed_Value handle(const Ret &r) - { - return Boxed_Value(std::cref(r)); - } }; template<> diff --git a/include/chaiscript/dispatchkit/operators.hpp b/include/chaiscript/dispatchkit/operators.hpp index 8dc54ba..4ebaec5 100644 --- a/include/chaiscript/dispatchkit/operators.hpp +++ b/include/chaiscript/dispatchkit/operators.hpp @@ -16,414 +16,202 @@ namespace chaiscript { namespace operators { - namespace detail - { - /// \todo make this return a decltype once we drop gcc 4.6 - template - auto assign(L l, R r) -> L& - { - return (l = r); - } - - template - auto assign_bitwise_and(L l, R r) -> decltype((l &= r)) - { - return (l &= r); - } - - template - auto assign_xor(L l, R r) -> decltype((l^=r)) - { - return (l ^= r); - } - - template - auto assign_bitwise_or(L l, R r) -> decltype((l |= r)) - { - return (l |= r); - } - - template - auto assign_difference(L l, R r) -> decltype(( l -= r)) - { - return (l -= r); - } - - template - auto assign_left_shift(L l, R r) -> decltype(( l <<= r)) - { - return (l <<= r); - } - - template - auto assign_product(L l, R r) -> decltype(( l *= r )) - { - return (l *= r); - } - - template - auto assign_quotient(L l, R r) -> decltype(( l /= r )) - { - return (l /= r); - } - - template - auto assign_remainder(L l, R r) -> decltype(( l %= r )) - { - return (l %= r); - } - - template - auto assign_right_shift(L l, R r) -> decltype(( l >>= r)) - { - return (l >>= r); - } - - /// \todo make this return a decltype once we drop gcc 4.6 - template - auto assign_sum(L l, R r) -> L& - { - return (l += r); - } - - template - auto prefix_decrement(L l) -> decltype(( --l )) - { - return (--l); - } - - template - auto prefix_increment(L l) -> decltype(( ++l )) - { - return (++l); - } - - template - auto equal(L l, R r) -> decltype(( l == r )) - { - return (l == r); - } - - template - auto greater_than(L l, R r) -> decltype(( l > r )) - { - return (l > r); - } - - template - auto greater_than_equal(L l, R r) -> decltype(( l >= r )) - { - return (l >= r); - } - - template - auto less_than(L l, R r) -> decltype(( l < r )) - { - return (l < r); - } - - template - auto less_than_equal(L l, R r) -> decltype(( l <= r )) - { - return (l <= r); - } - - template - auto logical_compliment(L l) -> decltype(( !l )) - { - return (!l); - } - - template - auto not_equal(L l, R r) -> decltype(( l != r )) - { - return (l != r); - } - - template - auto addition(L l, R r) -> decltype(( l + r )) - { - return (l + r); - } - - template - auto unary_plus(L l) -> decltype(( +l )) - { - return (+l); - } - - template - auto subtraction(L l, R r) -> decltype(( l - r )) - { - return (l - r); - } - - template - auto unary_minus(L l) -> decltype(( -l )) - { -#ifdef CHAISCRIPT_MSVC -#pragma warning(push) -#pragma warning(disable : 4146) - return (-l); -#pragma warning(pop) -#else - return (-l); -#endif - } - - template - auto bitwise_and(L l, R r) -> decltype(( l & r )) - { - return (l & r); - } - - template - auto bitwise_compliment(L l) -> decltype(( ~l )) - { - return (~l); - } - - template - auto bitwise_xor(L l, R r) -> decltype(( l ^ r )) - { - return (l ^ r); - } - - template - auto bitwise_or(L l, R r) -> decltype(( l | r )) - { - return (l | r); - } - - template - auto division(L l, R r) -> decltype(( l / r )) - { - return (l / r); - } - - template - auto left_shift(L l, R r) -> decltype(( l << r )) - { - return l << r; - } - - template - auto multiplication(L l, R r) -> decltype(( l * r )) - { - return l * r; - } - - template - auto remainder(L l, R r) -> decltype(( l % r )) - { - return (l % r); - } - - template - auto right_shift(L l, R r) -> decltype(( l >> r )) - { - return (l >> r); - } - } - - - template void assign(Module& m) { - m.add(chaiscript::fun(&detail::assign), "="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs = rhs;}), "="); } template void assign_bitwise_and(Module& m) { - m.add(chaiscript::fun(&detail::assign_bitwise_and), "&="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs &= rhs;}), "&="); } template void assign_xor(Module& m) { - m.add(chaiscript::fun(&detail::assign_xor), "^="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs ^= rhs;}), "^="); } template void assign_bitwise_or(Module& m) { - m.add(chaiscript::fun(&detail::assign_bitwise_or), "|="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs |= rhs;}), "|="); } template void assign_difference(Module& m) { - m.add(chaiscript::fun(&detail::assign_difference), "-="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs -= rhs;}), "-="); } template void assign_left_shift(Module& m) { - m.add(chaiscript::fun(&detail::assign_left_shift), "<<="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs <<= rhs;}), "<<="); } template void assign_product(Module& m) { - m.add(chaiscript::fun(&detail::assign_product), "*="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs <<= rhs;}), "*="); } template void assign_quotient(Module& m) { - m.add(chaiscript::fun(&detail::assign_quotient), "/="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs /= rhs;}), "/="); } template void assign_remainder(Module& m) { - m.add(chaiscript::fun(&detail::assign_remainder), "%="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs %= rhs;}), "%="); } template void assign_right_shift(Module& m) { - m.add(chaiscript::fun(&detail::assign_right_shift), ">>="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs >>= rhs;}), ">>="); } template void assign_sum(Module& m) { - m.add(chaiscript::fun(&detail::assign_sum), "+="); + m.add(chaiscript::fun([](T &lhs, const T&rhs)->T&{return lhs += rhs;}), "+="); } template void prefix_decrement(Module& m) { - m.add(chaiscript::fun(&detail::prefix_decrement), "--"); + m.add(chaiscript::fun([](T &lhs)->T&{return --lhs;}), "--"); } template void prefix_increment(Module& m) { - m.add(chaiscript::fun(&detail::prefix_increment), "++"); + m.add(chaiscript::fun([](T &lhs)->T&{return ++lhs;}), "++"); } template void equal(Module& m) { - m.add(chaiscript::fun(&detail::equal), "=="); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs==rhs;}), "=="); } template void greater_than(Module& m) { - m.add(chaiscript::fun(&detail::greater_than), ">"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs>rhs;}), ">"); } template void greater_than_equal(Module& m) { - m.add(chaiscript::fun(&detail::greater_than_equal), ">="); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs>=rhs;}), ">="); } template void less_than(Module& m) { - m.add(chaiscript::fun(&detail::less_than), "<"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs void less_than_equal(Module& m) { - m.add(chaiscript::fun(&detail::less_than_equal), "<="); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs<=rhs;}), "<="); } template void logical_compliment(Module& m) { - m.add(chaiscript::fun(&detail::logical_compliment), "!"); + m.add(chaiscript::fun([](const T &lhs){return !lhs;}), "!"); } template void not_equal(Module& m) { - m.add(chaiscript::fun(&detail::not_equal), "!="); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs!=rhs;}), "!="); } template void addition(Module& m) { - m.add(chaiscript::fun(&detail::addition), "+"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs+rhs;}), "+"); } template void unary_plus(Module& m) { - m.add(chaiscript::fun(&detail::unary_plus), "+"); + m.add(chaiscript::fun([](const T &lhs){return +lhs;}), "+"); } template void subtraction(Module& m) { - m.add(chaiscript::fun(&detail::subtraction), "-"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs-rhs;}), "-"); } template void unary_minus(Module& m) { - m.add(chaiscript::fun(&detail::unary_minus), "-"); + m.add(chaiscript::fun([](const T &lhs){return -lhs;}), "-"); } template void bitwise_and(Module& m) { - m.add(chaiscript::fun(&detail::bitwise_and), "&"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs&rhs;}), "&"); } template void bitwise_compliment(Module& m) { - m.add(chaiscript::fun(&detail::bitwise_compliment), "~"); + m.add(chaiscript::fun([](const T &lhs){return ~lhs;}), "~"); } template void bitwise_xor(Module& m) { - m.add(chaiscript::fun(&detail::bitwise_xor), "^"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs^rhs;}), "^"); } template void bitwise_or(Module& m) { - m.add(chaiscript::fun(&detail::bitwise_or), "|"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs|rhs;}), "|"); } template void division(Module& m) { - m.add(chaiscript::fun(&detail::division), "/"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs/rhs;}), "/"); } template void left_shift(Module& m) { - m.add(chaiscript::fun(&detail::left_shift), "<<"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs< void multiplication(Module& m) { - m.add(chaiscript::fun(&detail::multiplication), "*"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs*rhs;}), "*"); } template void remainder(Module& m) { - m.add(chaiscript::fun(&detail::remainder), "%"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs%rhs;}), "%"); } template void right_shift(Module& m) { - m.add(chaiscript::fun(&detail::right_shift), ">>"); + m.add(chaiscript::fun([](const T &lhs, const T &rhs){return lhs>>rhs;}), ">>"); } } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 7a2fa28..8723d82 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -727,13 +727,13 @@ namespace chaiscript template auto do_call_impl(Class *o) const -> std::enable_if_t::value, Boxed_Value> { - return detail::Handle_Return::type>::handle(o->*m_attr); + return detail::Handle_Return::type>::handle(o->*m_attr); } template auto do_call_impl(const Class *o) const -> std::enable_if_t::value, Boxed_Value> { - return detail::Handle_Return::type>::handle(o->*m_attr); + return detail::Handle_Return::type>::type>::handle(o->*m_attr); } From 56b4f465a140660b8c59926a292fa2464c9cb367 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Fri, 15 Apr 2016 23:09:20 -0600 Subject: [PATCH 24/37] Add warning on platforms without thread_local --- include/chaiscript/chaiscript_threading.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 2250693..0d2825f 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -108,6 +108,9 @@ namespace chaiscript #else +#pragma message ("Threading without thread_local support is not well supported.") + + /// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If /// threading is not enabled, the class always returns the same data, regardless of which thread it is called from. /// From 498339c202d4e57d42a76e10b92aedd39ea551a7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 07:35:30 -0600 Subject: [PATCH 25/37] Remove some dead parser code --- .../chaiscript/language/chaiscript_parser.hpp | 69 ++----------------- 1 file changed, 5 insertions(+), 64 deletions(-) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index d1d8084..5a6c1c6 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -177,8 +177,7 @@ namespace chaiscript struct Position { - Position() - : line(-1), col(-1), m_last_col(-1) {} + Position() = default; Position(std::string::const_iterator t_pos, std::string::const_iterator t_end) : line(1), col(1), m_pos(std::move(t_pos)), m_end(std::move(t_end)), m_last_col(1) @@ -265,13 +264,13 @@ namespace chaiscript } } - int line; - int col; + int line = -1; + int col = -1; private: std::string::const_iterator m_pos; std::string::const_iterator m_end; - int m_last_col; + int m_last_col = -1; }; Position m_position; @@ -297,59 +296,12 @@ namespace chaiscript } } - - /// Shows the current stack of matched ast_nodes - void show_match_stack() const { - for (auto & elem : m_match_stack) { - //debug_print(match_stack[i]); - std::cout << elem->to_string(); - } - } - - /// Clears the stack of matched ast_nodes - void clear_match_stack() { - m_match_stack.clear(); - } - /// 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(); } - static std::map count_fun_calls(const AST_NodePtr &p, bool in_loop) { - if (p->identifier == AST_Node_Type::Fun_Call) { - if (p->children[0]->identifier == AST_Node_Type::Id) { - return std::map{ {p->children[0]->text, in_loop?99:1} }; - } - return std::map(); - } else { - std::map counts; - for (const auto &child : p->children) { - auto childcounts = count_fun_calls(child, in_loop || p->identifier == AST_Node_Type::For || p->identifier == AST_Node_Type::While); - for (const auto &count : childcounts) { - counts[count.first] += count.second; - } - } - return counts; - } - - } - - - static void optimize_blocks(AST_NodePtr &p) - { - for (auto &c : p->children) - { - if (c->identifier == AST_Node_Type::Block) { - if (c->children.size() == 1) { - // std::cout << "swapping out block child for block\n"; - c = c->children[0]; - } - } - optimize_blocks(c); - } - } static void optimize_returns(AST_NodePtr &p) { @@ -371,19 +323,8 @@ namespace chaiscript } - static int count_nodes(const AST_NodePtr &p) - { - int count = 1; - for (auto &c : p->children) { - count += count_nodes(c); - } - return count; - } - - AST_NodePtr optimized_ast(bool t_optimize_blocks = false, bool t_optimize_returns = true) { + AST_NodePtr optimized_ast(bool t_optimize_returns = true) { 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); } return p; } From 32bd936a18be10167c343b060e88cf172edd11ed Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 07:52:39 -0600 Subject: [PATCH 26/37] Remove 'annotation' feature --- include/chaiscript/chaiscript.hpp | 5 +- include/chaiscript/dispatchkit/bootstrap.hpp | 1 - .../chaiscript/dispatchkit/dispatchkit.hpp | 10 +--- .../dispatchkit/dynamic_object_detail.hpp | 11 ----- .../dispatchkit/proxy_functions.hpp | 27 +--------- .../chaiscript/language/chaiscript_common.hpp | 5 +- .../chaiscript/language/chaiscript_eval.hpp | 13 ++--- .../chaiscript/language/chaiscript_parser.hpp | 49 ++++++------------- unittests/3.x/dispatch_functions.chai | 1 - unittests/3.x/function_introspection.chai | 1 - unittests/function_introspection.chai | 1 - 11 files changed, 23 insertions(+), 101 deletions(-) diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index 79ef8cf..43d3b4f 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -695,11 +695,10 @@ /// Begins a function or method definition /// /// ~~~~~~~~ -/// Function Definition ::= [annotation + CR/LF] "def" identifier "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block -/// Method Definition ::= [annotation + CR/LF] "def" class_name "::" method_name "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block +/// Function Definition ::= "def" identifier "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block +/// Method Definition ::= "def" class_name "::" method_name "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block /// ~~~~~~~~ /// -/// annotation: meta-annotation on function, currently used as documentation. Optional. /// identifier: name of function. Required. /// args: comma-delimited list of parameter names with optional type specifiers. Optional. /// guards: guarding statement that act as a prerequisite for the function. Optional. diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 74614f8..918d9ce 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -376,7 +376,6 @@ namespace chaiscript m.add(user_type(), "exception"); m.add(fun(&dispatch::Proxy_Function_Base::get_arity), "get_arity"); - m.add(fun(&dispatch::Proxy_Function_Base::annotation), "get_annotation"); m.add(fun(&dispatch::Proxy_Function_Base::operator==), "=="); diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index b5ed3f7..ec47d50 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -310,11 +310,6 @@ namespace chaiscript [&vals, &t_conversions](const Proxy_Function &f){ return f->call_match(vals, t_conversions); }); } - std::string annotation() const override - { - return "Multiple method dispatch function wrapper."; - } - protected: Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { @@ -1046,11 +1041,7 @@ namespace chaiscript void dump_function(const std::pair &f) const { std::vector params = f.second->get_param_types(); - std::string annotation = f.second->annotation(); - if (annotation.size() > 0) { - std::cout << annotation; - } dump_type(params.front()); std::cout << " " << f.first << "("; @@ -1524,3 +1515,4 @@ namespace chaiscript #endif + diff --git a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp index 76e3cbf..93031cf 100644 --- a/include/chaiscript/dispatchkit/dynamic_object_detail.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object_detail.hpp @@ -98,12 +98,6 @@ namespace chaiscript return {m_func}; } - std::string annotation() const override - { - return m_func->annotation(); - } - - protected: virtual Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { @@ -219,11 +213,6 @@ namespace chaiscript return m_func->call_match(new_vals, t_conversions); } - std::string annotation() const override - { - return m_func->annotation(); - } - protected: Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 8723d82..ae6952d 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -204,8 +204,6 @@ namespace chaiscript return m_arity; } - virtual std::string annotation() const = 0; - static bool compare_type_to_param(const Type_Info &ti, const Boxed_Value &bv, const Type_Conversions_State &t_conversions) { if (ti.is_undef() @@ -306,11 +304,10 @@ namespace chaiscript int t_arity=-1, AST_NodePtr t_parsenode = AST_NodePtr(), Param_Types t_param_types = Param_Types(), - std::string t_description = "", Proxy_Function t_guard = Proxy_Function()) : Proxy_Function_Base(build_param_type_list(t_param_types), t_arity), m_param_types(std::move(t_param_types)), - m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)), m_description(std::move(t_description)) + m_guard(std::move(t_guard)), m_parsenode(std::move(t_parsenode)) { } @@ -343,11 +340,6 @@ namespace chaiscript return m_parsenode; } - virtual std::string annotation() const override - { - return m_description; - } - protected: bool test_guard(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const @@ -387,7 +379,6 @@ namespace chaiscript Param_Types m_param_types; Proxy_Function m_guard; AST_NodePtr m_parsenode; - std::string m_description; }; @@ -401,13 +392,11 @@ namespace chaiscript int t_arity=-1, AST_NodePtr t_parsenode = AST_NodePtr(), Param_Types t_param_types = Param_Types(), - std::string t_description = "", Proxy_Function t_guard = Proxy_Function()) : Dynamic_Proxy_Function( t_arity, std::move(t_parsenode), std::move(t_param_types), - std::move(t_description), std::move(t_guard) ), m_f(std::move(t_f)) @@ -506,10 +495,6 @@ namespace chaiscript return args; } - virtual std::string annotation() const override - { - return "Bound: " + m_f->annotation(); - } protected: static std::vector build_param_type_info(const Const_Proxy_Function &t_f, @@ -554,11 +539,6 @@ namespace chaiscript { } - std::string annotation() const override - { - return ""; - } - bool call_match(const std::vector &vals, const Type_Conversions_State &t_conversions) const override { return static_cast(vals.size()) == get_arity() @@ -692,11 +672,6 @@ namespace chaiscript return vals[0].get_type_info().bare_equal(user_type()); } - std::string annotation() const override - { - return ""; - } - protected: Boxed_Value do_call(const std::vector ¶ms, const Type_Conversions_State &t_conversions) const override { diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index ca29b16..3efe902 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -35,7 +35,7 @@ namespace chaiscript enum class AST_Node_Type { Error, Id, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, - Inline_Range, Annotation, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, + Inline_Range, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant }; @@ -47,7 +47,7 @@ namespace chaiscript static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", - "Inline_Range", "Annotation", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", + "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Constant"}; return ast_node_types[static_cast(ast_node_type)]; @@ -447,7 +447,6 @@ namespace chaiscript const std::string text; Parse_Location location; std::vector children; - AST_NodePtr annotation; const std::string &filename() const { return *location.filename; diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 0b9311d..20593c1 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -578,7 +578,6 @@ namespace chaiscript try { const std::string & l_function_name = this->children[0]->text; - const std::string & l_annotation = this->annotation?this->annotation->text:""; const auto & func_node = this->children.back(); t_ss->add( dispatch::make_dynamic_proxy_function( @@ -587,7 +586,7 @@ namespace chaiscript return detail::eval_function(engine, func_node, t_param_names, t_params); }, static_cast(numparams), this->children.back(), - param_types, l_annotation, guard), l_function_name); + param_types, guard), l_function_name); } catch (const exception::reserved_word_error &e) { throw exception::eval_error("Reserved word used as function name '" + e.word() + "'"); @@ -991,11 +990,6 @@ namespace chaiscript mutable std::atomic_uint_fast32_t m_loc; }; - struct Annotation_AST_Node final : AST_Node { - Annotation_AST_Node(std::string t_ast_node_text, Parse_Location t_loc) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::Annotation, std::move(t_loc)) { } - }; - struct Try_AST_Node final : AST_Node { Try_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : AST_Node(std::move(t_ast_node_text), AST_Node_Type::Try, std::move(t_loc), std::move(t_children)) { } @@ -1162,7 +1156,6 @@ namespace chaiscript } try { - const std::string & l_annotation = annotation?annotation->text:""; const std::string & function_name = children[static_cast(1 + class_offset)]->text; auto node = children.back(); @@ -1175,7 +1168,7 @@ namespace chaiscript [engine, t_param_names, node](const std::vector &t_params) { return chaiscript::eval::detail::eval_function(engine, node, t_param_names, t_params); }, - static_cast(numparams), node, param_types, l_annotation, guard + static_cast(numparams), node, param_types, guard ) ), function_name); @@ -1191,7 +1184,7 @@ namespace chaiscript [engine, t_param_names, node](const std::vector &t_params) { return chaiscript::eval::detail::eval_function(engine, node, t_param_names, t_params); }, - static_cast(numparams), node, param_types, l_annotation, guard), type), + static_cast(numparams), node, param_types, guard), type), function_name); } } diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 5a6c1c6..2377d1e 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -166,6 +166,7 @@ namespace chaiscript static constexpr const char * const m_multiline_comment_begin = "/*"; static constexpr const char * const m_multiline_comment_end = "*/"; static constexpr const char * const m_singleline_comment = "//"; + static constexpr const char * const m_annotation = "#"; const std::array, detail::max_alphabet> &m_alphabet = create_alphabet(); const std::vector> &m_operator_matches = create_operator_matches(); @@ -398,6 +399,19 @@ namespace chaiscript } } return true; + } else if (Symbol_(m_annotation)) { + while (m_position.has_more()) { + if (Symbol_("\r\n")) { + m_position -= 2; + break; + } else if (Char_('\n')) { + --m_position; + break; + } else { + ++m_position; + } + } + return true; } return false; } @@ -822,31 +836,6 @@ namespace chaiscript - /// Checks for a node annotation of the form "#" - bool Annotation() { - SkipWS(); - const auto start = m_position; - if (Symbol_("#")) { - do { - while (m_position.has_more()) { - if (Eol_()) { - break; - } - else { - ++m_position; - } - } - } while (Symbol("#")); - - auto match = Position::str(start, m_position); - m_match_stack.push_back(make_node(std::move(match), start.line, start.col)); - return true; - } - else { - return false; - } - } - /// Reads a quoted string from input, without skipping initial whitespace bool Quoted_String_() { if (m_position.has_more() && (*m_position == '\"')) { @@ -1468,13 +1457,6 @@ namespace chaiscript /// Reads a function definition from input bool Def(const bool t_class_context = false) { bool retval = false; - AST_NodePtr annotation; - - if (Annotation()) { - while (Eol_()) {} - annotation = m_match_stack.back(); - m_match_stack.pop_back(); - } const auto prev_stack_top = m_match_stack.size(); @@ -1522,9 +1504,6 @@ namespace chaiscript build_match(prev_stack_top); } - if (annotation) { - m_match_stack.back()->annotation = std::move(annotation); - } } return retval; diff --git a/unittests/3.x/dispatch_functions.chai b/unittests/3.x/dispatch_functions.chai index 528d5b3..f25ae01 100644 --- a/unittests/3.x/dispatch_functions.chai +++ b/unittests/3.x/dispatch_functions.chai @@ -1,7 +1,6 @@ assert_equal(`==`, `==`); assert_not_equal(`==`, `<`); assert_equal(`<`.get_arity(), 2); -assert_equal(`+`.get_annotation(), "Multiple method dispatch function wrapper."); assert_equal(get_arity.get_contained_functions().size(), 0); assert_equal(get_arity.get_arity(), 1); assert_equal(get_arity.get_param_types().size(), 2); diff --git a/unittests/3.x/function_introspection.chai b/unittests/3.x/function_introspection.chai index 5ad76fc..96b2ec6 100644 --- a/unittests/3.x/function_introspection.chai +++ b/unittests/3.x/function_introspection.chai @@ -10,7 +10,6 @@ def test_function(a) // test_function tests assert_equal(test_function.get_arity(), 1); -assert_equal(trim(test_function.get_annotation()), "#Test Function Description"); assert_equal(test_function.get_contained_functions().size(), 0); assert_equal(test_function.get_param_types().size(), 2); diff --git a/unittests/function_introspection.chai b/unittests/function_introspection.chai index 6d808df..fbfee5a 100644 --- a/unittests/function_introspection.chai +++ b/unittests/function_introspection.chai @@ -10,7 +10,6 @@ def test_function(a) // test_function tests assert_equal(test_function.get_arity(), 1); -assert_equal(trim(test_function.get_annotation()), "#Test Function Description"); assert_equal(test_function.get_contained_functions().size(), 0); assert_equal(test_function.get_param_types().size(), 2); From 57aa874c6e70ca4c289400499eb7179ac77fd4d2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 09:02:38 -0600 Subject: [PATCH 27/37] Revert "Prefer make_unique over make_shared" This reverts commit 5a947b5035dc99d2dbef35a220340036886e189c. --- .../chaiscript/dispatchkit/boxed_value.hpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 1e0ec99..53c5867 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -77,9 +77,9 @@ namespace chaiscript struct Object_Data { - static std::unique_ptr get(Boxed_Value::Void_Type, bool t_return_value) + static std::shared_ptr get(Boxed_Value::Void_Type, bool t_return_value) { - return std::make_unique( + return std::make_shared( detail::Get_Type_Info::get(), chaiscript::detail::Any(), false, @@ -89,15 +89,15 @@ namespace chaiscript } template - static std::unique_ptr get(const std::shared_ptr *obj, bool t_return_value) + static std::shared_ptr get(const std::shared_ptr *obj, bool t_return_value) { return get(*obj, t_return_value); } template - static std::unique_ptr get(const std::shared_ptr &obj, bool t_return_value) + static std::shared_ptr get(const std::shared_ptr &obj, bool t_return_value) { - return std::make_unique( + return std::make_shared( detail::Get_Type_Info::get(), chaiscript::detail::Any(obj), false, @@ -107,10 +107,10 @@ namespace chaiscript } template - static std::unique_ptr get(std::shared_ptr &&obj, bool t_return_value) + static std::shared_ptr get(std::shared_ptr &&obj, bool t_return_value) { auto ptr = obj.get(); - return std::make_unique( + return std::make_shared( detail::Get_Type_Info::get(), chaiscript::detail::Any(std::move(obj)), false, @@ -120,23 +120,23 @@ namespace chaiscript } template - static std::unique_ptr get(T *t, bool t_return_value) + static std::shared_ptr get(T *t, bool t_return_value) { return get(std::ref(*t), t_return_value); } template - static std::unique_ptr get(const T *t, bool t_return_value) + static std::shared_ptr get(const T *t, bool t_return_value) { return get(std::cref(*t), t_return_value); } template - static std::unique_ptr get(std::reference_wrapper obj, bool t_return_value) + static std::shared_ptr get(std::reference_wrapper obj, bool t_return_value) { auto p = &obj.get(); - return std::make_unique( + return std::make_shared( detail::Get_Type_Info::get(), chaiscript::detail::Any(std::move(obj)), true, @@ -146,11 +146,11 @@ namespace chaiscript } template - static std::unique_ptr get(T t, bool t_return_value) + static std::shared_ptr get(T t, bool t_return_value) { auto p = std::make_shared(std::move(t)); auto ptr = p.get(); - return std::make_unique( + return std::make_shared( detail::Get_Type_Info::get(), chaiscript::detail::Any(std::move(p)), false, @@ -159,9 +159,9 @@ namespace chaiscript ); } - static std::unique_ptr get() + static std::shared_ptr get() { - return std::make_unique( + return std::make_shared( Type_Info(), chaiscript::detail::Any(), false, From f3f84594eedb928062ff30889b94df5ee359fb03 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 12:04:18 -0600 Subject: [PATCH 28/37] A few parser cleanups --- .../chaiscript/language/chaiscript_common.hpp | 14 +- .../chaiscript/language/chaiscript_parser.hpp | 151 ++++++++---------- unittests/dispatch_functions.chai | 1 - 3 files changed, 74 insertions(+), 92 deletions(-) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 3efe902..cda7671 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -32,22 +32,24 @@ namespace chaiscript /// Types of AST nodes available to the parser and eval - enum class AST_Node_Type { Error, Id, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, - Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, + enum class AST_Node_Type { Id, Fun_Call, Arg_List, Equation, Var_Decl, + Array_Call, Dot_Access, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, - Inline_Range, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, + Inline_Range, Try, Catch, Finally, Method, Attr_Decl, Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant }; + enum class Operator_Precidence { Ternary_Cond, Logical_Or, Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And, Equality, Comparison, Shift, Addition, Multiplication }; + namespace { /// Helper lookup to get the name of each node type const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { - static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", - "Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", + static const char * const ast_node_types[] = { "Id", "Fun_Call", "Arg_List", "Equation", "Var_Decl", + "Array_Call", "Dot_Access", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", - "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", + "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Constant"}; return ast_node_types[static_cast(ast_node_type)]; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 2377d1e..fec5458 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -146,19 +146,19 @@ namespace chaiscript } - static const std::array &create_operators() { - static const std::array operators = { { - AST_Node_Type::Ternary_Cond, - AST_Node_Type::Logical_Or, - AST_Node_Type::Logical_And, - AST_Node_Type::Bitwise_Or, - AST_Node_Type::Bitwise_Xor, - AST_Node_Type::Bitwise_And, - AST_Node_Type::Equality, - AST_Node_Type::Comparison, - AST_Node_Type::Shift, - AST_Node_Type::Addition, - AST_Node_Type::Multiplication + static const std::array &create_operators() { + static const std::array operators = { { + Operator_Precidence::Ternary_Cond, + Operator_Precidence::Logical_Or, + Operator_Precidence::Logical_And, + Operator_Precidence::Bitwise_Or, + Operator_Precidence::Bitwise_Xor, + Operator_Precidence::Bitwise_And, + Operator_Precidence::Equality, + Operator_Precidence::Comparison, + Operator_Precidence::Shift, + Operator_Precidence::Addition, + Operator_Precidence::Multiplication } }; return operators; } @@ -170,7 +170,7 @@ namespace chaiscript const std::array, detail::max_alphabet> &m_alphabet = create_alphabet(); const std::vector> &m_operator_matches = create_operator_matches(); - const std::array &m_operators = create_operators(); + const std::array &m_operators = create_operators(); std::shared_ptr m_filename; std::vector m_match_stack; @@ -881,11 +881,11 @@ namespace chaiscript { string_type &match; typedef typename string_type::value_type char_type; - bool is_escaped; - bool is_interpolated; - bool saw_interpolation_marker; - bool is_octal; - bool is_hex; + bool is_escaped = false; + bool is_interpolated = false; + bool saw_interpolation_marker = false; + bool is_octal = false; + bool is_hex = false; const bool interpolation_allowed; string_type octal_matches; @@ -893,11 +893,6 @@ namespace chaiscript Char_Parser(string_type &t_match, const bool t_interpolation_allowed) : match(t_match), - is_escaped(false), - is_interpolated(false), - saw_interpolation_marker(false), - is_octal(false), - is_hex(false), interpolation_allowed(t_interpolation_allowed) { } @@ -1034,13 +1029,11 @@ namespace chaiscript if (*s == '{') { //We've found an interpolation point + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); + if (cparser.is_interpolated) { //If we've seen previous interpolation, add on instead of making a new one - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); - build_match(prev_stack_top, "+"); - } else { - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); } //We've finished with the part of the string up to this point, so clear it @@ -1091,13 +1084,12 @@ namespace chaiscript return cparser.is_interpolated; }(); - if (is_interpolated) { - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); + m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); + if (is_interpolated) { build_match(prev_stack_top, "+"); - } else { - m_match_stack.push_back(make_node(match, start.line, start.col, const_var(match))); } + return true; } else { return false; @@ -1302,14 +1294,13 @@ namespace chaiscript if (Arg(false)) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Arg(false)) { - throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); - } + + while (Char(',')) { + while (Eol()) {} + if (!Arg(false)) { + throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); + } + } } build_match(prev_stack_top); @@ -1328,13 +1319,12 @@ namespace chaiscript if (Arg()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Arg()) { - throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + + while (Char(',')) { + while (Eol()) {} + if (!Arg()) { + throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); + } } } build_match(prev_stack_top); @@ -1355,13 +1345,11 @@ namespace chaiscript if (Equation()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Equation()) { - throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + while (Char(',')) { + while (Eol()) {} + if (!Equation()) { + throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); + } } } @@ -1385,25 +1373,21 @@ namespace chaiscript } else if (Map_Pair()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Map_Pair()) { - throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + while (Char(',')) { + while (Eol()) {} + if (!Map_Pair()) { + throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); + } } build_match(prev_stack_top); } else if (Operator()) { retval = true; while (Eol()) {} - if (Char(',')) { - do { - while (Eol()) {} - if (!Operator()) { - throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); - } - } while (Char(',')); + while (Char(',')) { + while (Eol()) {} + if (!Operator()) { + throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); + } } build_match(prev_stack_top); } @@ -2142,36 +2126,33 @@ namespace chaiscript while (Operator_Helper(t_precedence, oper)) { while (Eol()) {} if (!Operator(t_precedence+1)) { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + throw exception::eval_error("Incomplete '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } switch (m_operators[t_precedence]) { - case(AST_Node_Type::Ternary_Cond) : + case(Operator_Precidence::Ternary_Cond) : if (Symbol(":")) { if (!Operator(t_precedence+1)) { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + throw exception::eval_error("Incomplete '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } build_match(prev_stack_top); } else { - throw exception::eval_error("Incomplete " - + std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression", + throw exception::eval_error("Incomplete '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } break; - case(AST_Node_Type::Addition) : - case(AST_Node_Type::Multiplication) : - case(AST_Node_Type::Shift) : - case(AST_Node_Type::Equality) : - case(AST_Node_Type::Bitwise_And) : - case(AST_Node_Type::Bitwise_Xor) : - case(AST_Node_Type::Bitwise_Or) : - case(AST_Node_Type::Comparison) : + case(Operator_Precidence::Addition) : + case(Operator_Precidence::Multiplication) : + case(Operator_Precidence::Shift) : + case(Operator_Precidence::Equality) : + case(Operator_Precidence::Bitwise_And) : + case(Operator_Precidence::Bitwise_Xor) : + case(Operator_Precidence::Bitwise_Or) : + case(Operator_Precidence::Comparison) : { bool folded = false; const auto size = m_match_stack.size(); @@ -2205,10 +2186,10 @@ namespace chaiscript break; - case(AST_Node_Type::Logical_And) : + case(Operator_Precidence::Logical_And) : build_match(prev_stack_top, oper); break; - case(AST_Node_Type::Logical_Or) : + case(Operator_Precidence::Logical_Or) : build_match(prev_stack_top, oper); break; diff --git a/unittests/dispatch_functions.chai b/unittests/dispatch_functions.chai index 1887844..6780516 100644 --- a/unittests/dispatch_functions.chai +++ b/unittests/dispatch_functions.chai @@ -1,7 +1,6 @@ assert_equal(`==`, `==`); assert_not_equal(`==`, `<`); assert_equal(`<`.get_arity(), 2); -assert_equal(`+`.get_annotation(), "Multiple method dispatch function wrapper."); assert_equal(get_arity.get_contained_functions().size(), 0); assert_equal(get_arity.get_arity(), 1); assert_equal(get_arity.get_param_types().size(), 2); From cf2fa09d6cbc395c6e1a39b49634f148869eeac3 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 14:13:14 -0600 Subject: [PATCH 29/37] Eliminate branching in var decl --- .../chaiscript/language/chaiscript_eval.hpp | 33 +++++++------------ .../chaiscript/language/chaiscript_parser.hpp | 7 ++-- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 20593c1..8ba24e5 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -295,9 +295,8 @@ namespace chaiscript try { if (lhs.is_undef()) { - if (!this->children.empty() && - !this->children[0]->children.empty() - && this->children[0]->children[0]->identifier == AST_Node_Type::Reference) + if (!this->children.empty() + && this->children[0]->identifier == AST_Node_Type::Reference) { /// \todo This does not handle the case of an unassigned reference variable /// being assigned outside of its declaration @@ -379,27 +378,19 @@ namespace chaiscript AST_Node(std::move(t_ast_node_text), AST_Node_Type::Var_Decl, std::move(t_loc), std::move(t_children)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - if (this->children[0]->identifier == AST_Node_Type::Reference) - { - return this->children[0]->eval(t_ss); - } else { - const std::string &idname = this->children[0]->text; + const std::string &idname = this->children[0]->text; - try { - Boxed_Value bv; - t_ss.add_object(idname, bv); - return bv; - } - catch (const exception::reserved_word_error &) { - throw exception::eval_error("Reserved word used as variable '" + idname + "'"); - } catch (const exception::name_conflict_error &e) { - throw exception::eval_error("Variable redefined '" + e.name() + "'"); - } + try { + Boxed_Value bv; + t_ss.add_object(idname, bv); + return bv; + } + catch (const exception::reserved_word_error &) { + throw exception::eval_error("Reserved word used as variable '" + idname + "'"); + } catch (const exception::name_conflict_error &e) { + throw exception::eval_error("Variable redefined '" + e.name() + "'"); } - } - - }; diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index fec5458..6422e3b 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1983,11 +1983,14 @@ namespace chaiscript } else if (Keyword("auto") || Keyword("var") ) { retval = true; - if (!(Reference() || Id())) { + if (Reference()) { + // we built a reference node - continue + } else if (Id()) { + build_match(prev_stack_top); + } else { throw exception::eval_error("Incomplete variable declaration", File_Position(m_position.line, m_position.col), *m_filename); } - build_match(prev_stack_top); } else if (Keyword("GLOBAL") || Keyword("global")) { retval = true; From 10b984556d8f24247c81c5a5f5470ed0cf2191b7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 14:23:11 -0600 Subject: [PATCH 30/37] Add global & test --- unittests/global_lcase.chai | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/unittests/global_lcase.chai b/unittests/global_lcase.chai index 7f8959a..21fdecd 100644 --- a/unittests/global_lcase.chai +++ b/unittests/global_lcase.chai @@ -16,3 +16,8 @@ def f() { f(); + +global &h = v; +assert_true(h == v) +v = 3; +assert_true(h == 3) From 83c6df11f008d7e758736997c23605647543bd30 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 14:30:12 -0600 Subject: [PATCH 31/37] Fix global reference assignment --- include/chaiscript/language/chaiscript_eval.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 8ba24e5..eafa01c 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -295,8 +295,13 @@ namespace chaiscript try { if (lhs.is_undef()) { - if (!this->children.empty() - && this->children[0]->identifier == AST_Node_Type::Reference) + if ((!this->children.empty() + && ((this->children[0]->identifier == AST_Node_Type::Reference) + || (!this->children[0]->children.empty() + && this->children[0]->children[0]->identifier == AST_Node_Type::Reference) + ) + ) + ) { /// \todo This does not handle the case of an unassigned reference variable /// being assigned outside of its declaration From 7d5a97aa2f2c4fd8391bd2a71fb4107fc77e05e2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 15:39:32 -0600 Subject: [PATCH 32/37] Clean up if block parsing and eval --- .../chaiscript/language/chaiscript_eval.hpp | 27 ++++++------------- .../chaiscript/language/chaiscript_parser.hpp | 19 +------------ 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index eafa01c..2977043 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -653,33 +653,22 @@ namespace chaiscript struct If_AST_Node final : AST_Node { If_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector t_children) : - AST_Node(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children)) { } + AST_Node(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children)) + { + assert(children.size() == 2 || children.size() == 3); + } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - if (get_bool_condition(children[0]->eval(t_ss))) { return children[1]->eval(t_ss); } else { - if (children.size() > 2) { - size_t i = 2; - /// \todo these string comparisons are clunky - while (i < children.size()) { - if (children[i]->text == "else") { - return children[i+1]->eval(t_ss); - } - else if (children[i]->text == "else if") { - if (get_bool_condition(children[i+1]->eval(t_ss))) { - return children[i+2]->eval(t_ss); - } - } - i += 3; - } + if (children.size() == 3) { + return children[2]->eval(t_ss); + } else { + return void_var(); } } - - return void_var(); } - }; struct For_AST_Node final : AST_Node { diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 6422e3b..2bdddc1 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1579,27 +1579,10 @@ namespace chaiscript while (has_matches) { while (Eol()) {} has_matches = false; - const auto line = m_position.line; - const auto col = m_position.col; if (Keyword("else")) { - if (Keyword("if")) { - m_match_stack.emplace_back(make_node("else if", line, col, std::vector())); - if (!Char('(')) { - throw exception::eval_error("Incomplete 'else if' expression", File_Position(m_position.line, m_position.col), *m_filename); - } - - if (!(Operator() && Char(')'))) { - throw exception::eval_error("Incomplete 'else if' expression", File_Position(m_position.line, m_position.col), *m_filename); - } - - while (Eol()) {} - - if (!Block()) { - throw exception::eval_error("Incomplete 'else if' block", File_Position(m_position.line, m_position.col), *m_filename); - } + if (If()) { has_matches = true; } else { - m_match_stack.emplace_back(make_node("else", line, col, std::vector())); while (Eol()) {} if (!Block()) { From c68488388e1abe2affbd299b739998a01330bef4 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 16 Apr 2016 22:14:02 -0600 Subject: [PATCH 33/37] Remove some unused code in Boxed_Value --- .../chaiscript/dispatchkit/boxed_number.hpp | 166 ------------------ .../chaiscript/dispatchkit/dispatchkit.hpp | 7 +- .../chaiscript/language/chaiscript_common.hpp | 22 +-- 3 files changed, 12 insertions(+), 183 deletions(-) diff --git a/include/chaiscript/dispatchkit/boxed_number.hpp b/include/chaiscript/dispatchkit/boxed_number.hpp index ad2775b..2cc06c7 100644 --- a/include/chaiscript/dispatchkit/boxed_number.hpp +++ b/include/chaiscript/dispatchkit/boxed_number.hpp @@ -645,71 +645,6 @@ namespace chaiscript throw chaiscript::detail::exception::bad_any_cast(); } - bool operator==(const Boxed_Number &t_rhs) const - { - return boxed_cast(oper(Operators::Opers::equals, this->bv, t_rhs.bv)); - } - - bool operator<(const Boxed_Number &t_rhs) const - { - return boxed_cast(oper(Operators::Opers::less_than, this->bv, t_rhs.bv)); - } - - bool operator>(const Boxed_Number &t_rhs) const - { - return boxed_cast(oper(Operators::Opers::greater_than, this->bv, t_rhs.bv)); - } - - bool operator>=(const Boxed_Number &t_rhs) const - { - return boxed_cast(oper(Operators::Opers::greater_than_equal, this->bv, t_rhs.bv)); - } - - bool operator<=(const Boxed_Number &t_rhs) const - { - return boxed_cast(oper(Operators::Opers::less_than_equal, this->bv, t_rhs.bv)); - } - - bool operator!=(const Boxed_Number &t_rhs) const - { - return boxed_cast(oper(Operators::Opers::not_equal, this->bv, t_rhs.bv)); - } - - Boxed_Number operator--() - { - return oper(Operators::Opers::pre_decrement, this->bv); - } - - Boxed_Number operator++() - { - return oper(Operators::Opers::pre_increment, this->bv); - } - - Boxed_Number operator+(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::sum, this->bv, t_rhs.bv); - } - - Boxed_Number operator+() const - { - return oper(Operators::Opers::unary_plus, this->bv); - } - - Boxed_Number operator-() const - { - return oper(Operators::Opers::unary_minus, this->bv); - } - - Boxed_Number operator-(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::difference, this->bv, t_rhs.bv); - } - - Boxed_Number operator&=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_bitwise_and, this->bv, t_rhs.bv); - } - static void validate_boxed_number(const Boxed_Value &v) { const Type_Info &inp_ = v.get_type_info(); @@ -724,107 +659,6 @@ namespace chaiscript } } - // cppcheck-suppress operatorEq - Boxed_Number operator=(const Boxed_Value &v) - { - validate_boxed_number(v); - bv = v; - return *this; - } - - // cppcheck-suppress operatorEq - Boxed_Number operator=(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::assign, this->bv, t_rhs.bv); - } - - Boxed_Number operator|=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_bitwise_or, this->bv, t_rhs.bv); - } - - Boxed_Number operator^=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_bitwise_xor, this->bv, t_rhs.bv); - } - - Boxed_Number operator%=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_remainder, this->bv, t_rhs.bv); - } - - Boxed_Number operator<<=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_shift_left, this->bv, t_rhs.bv); - } - - Boxed_Number operator>>=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_shift_right, this->bv, t_rhs.bv); - } - - Boxed_Number operator&(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::bitwise_and, this->bv, t_rhs.bv); - } - - Boxed_Number operator~() const - { - return oper(Operators::Opers::bitwise_complement, this->bv); - } - - Boxed_Number operator^(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::bitwise_xor, this->bv, t_rhs.bv); - } - - Boxed_Number operator|(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::bitwise_or, this->bv, t_rhs.bv); - } - - Boxed_Number operator*=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_product, this->bv, t_rhs.bv); - } - Boxed_Number operator/=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_quotient, this->bv, t_rhs.bv); - } - Boxed_Number operator+=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_sum, this->bv, t_rhs.bv); - } - Boxed_Number operator-=(const Boxed_Number &t_rhs) - { - return oper(Operators::Opers::assign_difference, this->bv, t_rhs.bv); - } - - Boxed_Number operator/(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::quotient, this->bv, t_rhs.bv); - } - - Boxed_Number operator<<(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::shift_left, this->bv, t_rhs.bv); - } - - Boxed_Number operator*(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::product, this->bv, t_rhs.bv); - } - - Boxed_Number operator%(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::remainder, this->bv, t_rhs.bv); - } - - Boxed_Number operator>>(const Boxed_Number &t_rhs) const - { - return oper(Operators::Opers::shift_right, this->bv, t_rhs.bv); - } - static bool equals(const Boxed_Number &t_lhs, const Boxed_Number &t_rhs) diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index ec47d50..a5c46e4 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -376,7 +376,6 @@ namespace chaiscript typedef std::vector StackData; Stack_Holder() - : call_depth(0) { stacks.reserve(2); stacks.emplace_back(1); @@ -387,7 +386,7 @@ namespace chaiscript std::vector stacks; std::vector> call_params; - int call_depth; + int call_depth = 0; }; /// Main class for the dispatchkit. Handles management @@ -1328,10 +1327,6 @@ namespace chaiscript if (rt.bare_equal(boxed_type)) { - if (lt.bare_equal(boxed_pod_type)) - { - return true; - } return true; } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index cda7671..9816f36 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -570,17 +570,17 @@ namespace chaiscript Scope_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds) : m_ds(t_ds) { - m_ds.get()->new_scope(m_ds.get().stack_holder()); + m_ds->new_scope(m_ds.stack_holder()); } ~Scope_Push_Pop() { - m_ds.get()->pop_scope(m_ds.get().stack_holder()); + m_ds->pop_scope(m_ds.stack_holder()); } private: - std::reference_wrapper m_ds; + const chaiscript::detail::Dispatch_State &m_ds; }; /// Creates a new function call and pops it on destruction @@ -594,27 +594,27 @@ namespace chaiscript Function_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds) : m_ds(t_ds) { - m_ds.get()->new_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves()); + m_ds->new_function_call(m_ds.stack_holder(), m_ds.conversion_saves()); } ~Function_Push_Pop() { - m_ds.get()->pop_function_call(m_ds.get().stack_holder(), m_ds.get().conversion_saves()); + m_ds->pop_function_call(m_ds.stack_holder(), m_ds.conversion_saves()); } void save_params(const std::vector &t_params) { - m_ds.get()->save_function_params(t_params); + m_ds->save_function_params(t_params); } void save_params(std::initializer_list t_params) { - m_ds.get()->save_function_params(std::move(t_params)); + m_ds->save_function_params(std::move(t_params)); } private: - std::reference_wrapper m_ds; + const chaiscript::detail::Dispatch_State &m_ds; }; /// Creates a new scope then pops it on destruction @@ -628,17 +628,17 @@ namespace chaiscript Stack_Push_Pop(const chaiscript::detail::Dispatch_State &t_ds) : m_ds(t_ds) { - m_ds.get()->new_stack(m_ds.get().stack_holder()); + m_ds->new_stack(m_ds.stack_holder()); } ~Stack_Push_Pop() { - m_ds.get()->pop_stack(m_ds.get().stack_holder()); + m_ds->pop_stack(m_ds.stack_holder()); } private: - std::reference_wrapper m_ds; + const chaiscript::detail::Dispatch_State &m_ds; }; } } From 80cc18bf2f901fdc2c34c5bbce78ec272fdd9821 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 17 Apr 2016 08:15:24 -0600 Subject: [PATCH 34/37] Make type_info fully constexpr - Minor hit in compile size - Minor improvement in runtime --- include/chaiscript/dispatchkit/type_info.hpp | 28 +++++++------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 9dfdb8f..664e4d3 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -29,8 +29,8 @@ namespace chaiscript class Type_Info { public: - 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) + constexpr Type_Info(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void, + const 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_flags((static_cast(t_is_const) << is_const_flag) + (static_cast(t_is_reference) << is_reference_flag) @@ -121,9 +121,7 @@ namespace chaiscript template struct Get_Type_Info { - typedef T type; - - static Type_Info get() + static constexpr Type_Info get() { return Type_Info(std::is_const::type>::type>::value, std::is_reference::value, std::is_pointer::value, @@ -138,9 +136,9 @@ namespace chaiscript template struct Get_Type_Info > { - typedef T type; +// typedef T type; - static Type_Info get() + static constexpr Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -158,9 +156,7 @@ namespace chaiscript template struct Get_Type_Info &> { - typedef T type; - - static Type_Info get() + static constexpr Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -173,9 +169,7 @@ namespace chaiscript template struct Get_Type_Info > { - typedef T type; - - static Type_Info get() + static constexpr Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -188,9 +182,7 @@ namespace chaiscript template struct Get_Type_Info &> { - typedef T type; - - static Type_Info get() + static constexpr Type_Info get() { return Type_Info(std::is_const::value, std::is_reference::value, std::is_pointer::value, std::is_void::value, @@ -212,7 +204,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(i); /// \endcode template - Type_Info user_type(const T &/*t*/) + constexpr Type_Info user_type(const T &/*t*/) { return detail::Get_Type_Info::get(); } @@ -227,7 +219,7 @@ namespace chaiscript /// chaiscript::Type_Info ti = chaiscript::user_type(); /// \endcode template - Type_Info user_type() + constexpr Type_Info user_type() { return detail::Get_Type_Info::get(); } From f9294c8cbe8c1787dc38f60c798c85ffed798cc2 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 17 Apr 2016 16:55:08 -0600 Subject: [PATCH 35/37] Remove ChaiScript_Parser from stdlib, unnecessary --- include/chaiscript/dispatchkit/bootstrap.hpp | 18 +++++++++++------- .../chaiscript/language/chaiscript_common.hpp | 8 +++----- .../chaiscript/language/chaiscript_engine.hpp | 9 +-------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 918d9ce..1d6532f 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -496,6 +496,7 @@ namespace chaiscript m.add(fun([](const char c) { return std::string(1, c); }), "to_string"); m.add(fun(&Boxed_Number::to_string), "to_string"); + bootstrap_pod_type("double", m); bootstrap_pod_type("long_double", m); bootstrap_pod_type("float", m); @@ -519,10 +520,20 @@ namespace chaiscript bootstrap_pod_type("uint32_t", m); bootstrap_pod_type("uint64_t", m); + operators::logical_compliment(m); opers_arithmetic_pod(m); + m.add(fun(&ChaiScript::version_major), "version_major"); + m.add(fun(&ChaiScript::version_minor), "version_minor"); + m.add(fun(&ChaiScript::version_patch), "version_patch"); + m.add(fun(&ChaiScript::version), "version"); + m.add(fun(&ChaiScript::compiler_version), "compiler_version"); + m.add(fun(&ChaiScript::compiler_name), "compiler_name"); + m.add(fun(&ChaiScript::compiler_id), "compiler_id"); + m.add(fun(&ChaiScript::debug_build), "debug_build"); + m.add(fun(&print), "print_string"); m.add(fun(&println), "println_string"); @@ -600,13 +611,6 @@ namespace chaiscript } ); - - chaiscript::utility::add_class(m, - "ChaiScript_Parser", - { constructor() }, - { {fun(&parser::ChaiScript_Parser::parse), "parse"}, - {fun(&parser::ChaiScript_Parser::ast), "ast"} } - ); } }; } diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 9816f36..2fed03a 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -469,7 +469,7 @@ namespace chaiscript oss << text; for (auto & elem : this->children) { - oss << elem->pretty_print(); + oss << elem->pretty_print() << ' '; } return oss.str(); @@ -512,6 +512,8 @@ namespace chaiscript virtual ~AST_Node() = default; AST_Node(AST_Node &&) = default; AST_Node &operator=(AST_Node &&) = default; + AST_Node(const AST_Node &) = delete; + AST_Node& operator=(const AST_Node &) = delete; protected: @@ -528,10 +530,6 @@ namespace chaiscript throw std::runtime_error("Undispatched ast_node (internal error)"); } - private: - // Copy and assignment explicitly deleted - AST_Node(const AST_Node &) = delete; - AST_Node& operator=(const AST_Node &) = delete; }; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index fca14de..bfd9cca 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -179,16 +179,9 @@ namespace chaiscript m_engine.add(fun([this](const std::string &t_file){ return internal_eval_file(t_file); }), "eval_file"); m_engine.add(fun([this](const std::string &t_str){ return internal_eval(t_str); }), "eval"); m_engine.add(fun([this](const AST_NodePtr &t_ast){ return eval(t_ast); }), "eval"); + m_engine.add(fun(&parse), "parse"); - m_engine.add(fun(&ChaiScript::version_major), "version_major"); - m_engine.add(fun(&ChaiScript::version_minor), "version_minor"); - m_engine.add(fun(&ChaiScript::version_patch), "version_patch"); - m_engine.add(fun(&ChaiScript::version), "version"); - m_engine.add(fun(&ChaiScript::compiler_version), "compiler_version"); - m_engine.add(fun(&ChaiScript::compiler_name), "compiler_name"); - m_engine.add(fun(&ChaiScript::compiler_id), "compiler_id"); - m_engine.add(fun(&ChaiScript::debug_build), "debug_build"); m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global_const(t_bv, t_name); }), "add_global_const"); m_engine.add(fun([this](const Boxed_Value &t_bv, const std::string &t_name){ add_global(t_bv, t_name); }), "add_global"); From 7ab6bce7faf0ba466b38a9ed31ccbdadbbd99ecd Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 17 Apr 2016 21:14:01 -0600 Subject: [PATCH 36/37] Untangle chaiscript_engine from the rest of it --- include/chaiscript/chaiscript_defines.hpp | 48 +++++++++++++++++ include/chaiscript/chaiscript_stdlib.hpp | 20 +++++--- include/chaiscript/dispatchkit/bootstrap.hpp | 43 ++++------------ .../chaiscript/language/chaiscript_common.hpp | 5 +- .../chaiscript/language/chaiscript_engine.hpp | 51 +------------------ include/chaiscript/utility/utility.hpp | 5 +- 6 files changed, 76 insertions(+), 96 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 4049381..4c31b6e 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -89,6 +89,54 @@ namespace chaiscript { #endif } + struct Build_Info { + static int version_major() + { + return chaiscript::version_major; + } + + static int version_minor() + { + return chaiscript::version_minor; + } + + static int version_patch() + { + return chaiscript::version_patch; + } + + static std::string version() + { + return std::to_string(version_major()) + '.' + std::to_string(version_minor()) + '.' + std::to_string(version_patch()); + } + + static std::string compiler_id() + { + return compiler_name() + '-' + compiler_version(); + } + + static std::string build_id() + { + return compiler_id() + (debug_build()?"-Debug":"-Release"); + } + + static std::string compiler_version() + { + return chaiscript::compiler_version; + } + + static std::string compiler_name() + { + return chaiscript::compiler_name; + } + + static bool debug_build() + { + return chaiscript::debug_build; + } + }; + + template Iter advance_copy(Iter iter, Distance distance) { std::advance(iter, static_cast::difference_type>(distance)); diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp index 50aa087..a1082c5 100644 --- a/include/chaiscript/chaiscript_stdlib.hpp +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -14,11 +14,15 @@ #include #include "chaiscript_defines.hpp" -#include "dispatchkit/dispatchkit.hpp" +#include "language/chaiscript_common.hpp" + +//#include "dispatchkit/dispatchkit.hpp" +#include "dispatchkit/operators.hpp" #include "dispatchkit/bootstrap.hpp" #include "dispatchkit/bootstrap_stl.hpp" -#include "dispatchkit/boxed_value.hpp" +//#include "dispatchkit/boxed_value.hpp" #include "language/chaiscript_prelude.hpp" +#include "dispatchkit/register_function.hpp" #include "utility/json_wrap.hpp" #ifndef CHAISCRIPT_NO_THREADS @@ -38,15 +42,15 @@ namespace chaiscript static ModulePtr library() { - using namespace bootstrap; + // using namespace bootstrap; auto lib = std::make_shared(); - Bootstrap::bootstrap(*lib); + bootstrap::Bootstrap::bootstrap(*lib); - standard_library::vector_type >("Vector", *lib); - standard_library::string_type("string", *lib); - standard_library::map_type >("Map", *lib); - standard_library::pair_type >("Pair", *lib); + bootstrap::standard_library::vector_type >("Vector", *lib); + bootstrap::standard_library::string_type("string", *lib); + bootstrap::standard_library::map_type >("Map", *lib); + bootstrap::standard_library::pair_type >("Pair", *lib); #ifndef CHAISCRIPT_NO_THREADS standard_library::future_type>("future", *lib); diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 1d6532f..0d7e8a3 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -7,32 +7,8 @@ #ifndef CHAISCRIPT_BOOTSTRAP_HPP_ #define CHAISCRIPT_BOOTSTRAP_HPP_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bad_boxed_cast.hpp" -#include "boxed_cast.hpp" -#include "boxed_number.hpp" -#include "boxed_value.hpp" -#include "dispatchkit.hpp" -#include "type_conversions.hpp" -#include "dynamic_object.hpp" -#include "operators.hpp" -#include "proxy_constructors.hpp" -#include "proxy_functions.hpp" -#include "proxy_functions_detail.hpp" -#include "register_function.hpp" -#include "type_info.hpp" #include "../utility/utility.hpp" -#include "../language/chaiscript_common.hpp" +#include "register_function.hpp" namespace chaiscript { @@ -525,14 +501,15 @@ namespace chaiscript opers_arithmetic_pod(m); - m.add(fun(&ChaiScript::version_major), "version_major"); - m.add(fun(&ChaiScript::version_minor), "version_minor"); - m.add(fun(&ChaiScript::version_patch), "version_patch"); - m.add(fun(&ChaiScript::version), "version"); - m.add(fun(&ChaiScript::compiler_version), "compiler_version"); - m.add(fun(&ChaiScript::compiler_name), "compiler_name"); - m.add(fun(&ChaiScript::compiler_id), "compiler_id"); - m.add(fun(&ChaiScript::debug_build), "debug_build"); + + m.add(fun(&Build_Info::version_major), "version_major"); + m.add(fun(&Build_Info::version_minor), "version_minor"); + m.add(fun(&Build_Info::version_patch), "version_patch"); + m.add(fun(&Build_Info::version), "version"); + m.add(fun(&Build_Info::compiler_version), "compiler_version"); + m.add(fun(&Build_Info::compiler_name), "compiler_name"); + m.add(fun(&Build_Info::compiler_id), "compiler_id"); + m.add(fun(&Build_Info::debug_build), "debug_build"); m.add(fun(&print), "print_string"); diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 2fed03a..0ab8a4f 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -43,7 +43,6 @@ namespace chaiscript namespace { - /// Helper lookup to get the name of each node type const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { static const char * const ast_node_types[] = { "Id", "Fun_Call", "Arg_List", "Equation", "Var_Decl", @@ -109,7 +108,7 @@ namespace chaiscript } load_module_error(const load_module_error &) = default; - virtual ~load_module_error() noexcept {} + virtual ~load_module_error() noexcept = default; }; @@ -172,7 +171,7 @@ namespace chaiscript return ss.str(); } - virtual ~eval_error() noexcept {} + virtual ~eval_error() noexcept = default; private: diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index bfd9cca..95c8165 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -292,7 +292,7 @@ namespace chaiscript // attempt to load the stdlib - load_module("chaiscript_stdlib-" + version()); + load_module("chaiscript_stdlib-" + Build_Info::version()); build_eval_system(ModulePtr()); } @@ -319,53 +319,6 @@ namespace chaiscript } - static int version_major() - { - return chaiscript::version_major; - } - - static int version_minor() - { - return chaiscript::version_minor; - } - - static int version_patch() - { - return chaiscript::version_patch; - } - - static std::string version() - { - return std::to_string(version_major()) + '.' + std::to_string(version_minor()) + '.' + std::to_string(version_patch()); - } - - static std::string compiler_id() - { - return compiler_name() + '-' + compiler_version(); - } - - static std::string build_id() - { - return compiler_id() + (debug_build()?"-Debug":"-Release"); - } - - static std::string compiler_version() - { - return chaiscript::compiler_version; - } - - static std::string compiler_name() - { - return chaiscript::compiler_name; - } - - static bool debug_build() - { - return chaiscript::debug_build; - } - - - std::string get_type_name(const Type_Info &ti) const { return m_engine.get_type_name(ti); @@ -580,7 +533,7 @@ namespace chaiscript { std::vector errors; std::string version_stripped_name = t_module_name; - size_t version_pos = version_stripped_name.find("-"+version()); + size_t version_pos = version_stripped_name.find("-" + Build_Info::version()); if (version_pos != std::string::npos) { version_stripped_name.erase(version_pos); diff --git a/include/chaiscript/utility/utility.hpp b/include/chaiscript/utility/utility.hpp index 1ca0dfb..fa2bbdb 100644 --- a/include/chaiscript/utility/utility.hpp +++ b/include/chaiscript/utility/utility.hpp @@ -12,9 +12,8 @@ #include #include -#include "../chaiscript.hpp" -#include "../dispatchkit/proxy_functions.hpp" -#include "../dispatchkit/type_info.hpp" +#include "../language/chaiscript_common.hpp" +#include "../dispatchkit/register_function.hpp" #include "../dispatchkit/operators.hpp" From 06b2893bfbc03fde19d1824deb756cf2a7c41bcb Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 17 Apr 2016 21:15:59 -0600 Subject: [PATCH 37/37] Update tests for removal of ChaiScript_Parser from stdlib --- unittests/reflection_test.chai | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/unittests/reflection_test.chai b/unittests/reflection_test.chai index 80e8f26..c7bc89d 100644 --- a/unittests/reflection_test.chai +++ b/unittests/reflection_test.chai @@ -1,6 +1,4 @@ -auto& parser = ChaiScript_Parser() -auto parse_success = parser.parse("3 + 4", "INPUT") -auto& a = parser.ast() +auto a = parse("3 + 4") assert_equal(eval(a), 7)