Skip to content

Commit 0870cb5

Browse files
Add C++20 support
ChaiScript now successfully builds on my Mac with C++20, and passes 100% of the unit tests.
1 parent 3e54818 commit 0870cb5

4 files changed

Lines changed: 111 additions & 100 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.12)
22
cmake_policy(SET CMP0054 NEW)
33

4-
set(CMAKE_CXX_STANDARD 17)
4+
set(CMAKE_CXX_STANDARD 20)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66

77
# required since cmake 3.4 at least for libc++
@@ -167,7 +167,7 @@ if(MSVC)
167167
else()
168168
add_definitions(-Wall -Wextra -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -Wno-noexcept-type -Wpedantic -Werror=return-type)
169169

170-
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
170+
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
171171
add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors -Wno-documentation-unknown-command -Wno-unused-template -Wno-undef -Wno-double-promotion)
172172
else()
173173
add_definitions(-Wnoexcept)

include/chaiscript/language/chaiscript_common.hpp

Lines changed: 101 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
namespace chaiscript {
2828
struct AST_Node;
29+
struct AST_Node_Trace;
30+
namespace exception {
31+
struct eval_error;
32+
}
2933
} // namespace chaiscript
3034

3135
namespace chaiscript {
@@ -166,11 +170,104 @@ namespace chaiscript {
166170
std::shared_ptr<std::string> filename;
167171
};
168172

173+
/// \brief Struct that doubles as both a parser ast_node and an AST node.
174+
struct AST_Node {
175+
public:
176+
const AST_Node_Type identifier;
177+
const std::string text;
178+
Parse_Location location;
179+
180+
const std::string &filename() const noexcept { return *location.filename; }
181+
182+
const File_Position &start() const noexcept { return location.start; }
183+
184+
const File_Position &end() const noexcept { return location.end; }
185+
186+
std::string pretty_print() const {
187+
std::ostringstream oss;
188+
189+
oss << text;
190+
191+
for (auto &elem : get_children()) {
192+
oss << elem.get().pretty_print() << ' ';
193+
}
194+
195+
return oss.str();
196+
}
197+
198+
virtual std::vector<std::reference_wrapper<AST_Node>> get_children() const = 0;
199+
virtual Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const = 0;
200+
201+
/// Prints the contents of an AST node, including its children, recursively
202+
std::string to_string(const std::string &t_prepend = "") const {
203+
std::ostringstream oss;
204+
205+
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") " << this->text << " : " << this->location.start.line
206+
<< ", " << this->location.start.column << '\n';
207+
208+
for (auto &elem : get_children()) {
209+
oss << elem.get().to_string(t_prepend + " ");
210+
}
211+
return oss.str();
212+
}
213+
214+
static inline bool get_bool_condition(const Boxed_Value &t_bv, const chaiscript::detail::Dispatch_State &t_ss);
215+
216+
virtual ~AST_Node() noexcept = default;
217+
AST_Node(AST_Node &&) = default;
218+
AST_Node &operator=(AST_Node &&) = delete;
219+
AST_Node(const AST_Node &) = delete;
220+
AST_Node &operator=(const AST_Node &) = delete;
221+
222+
protected:
223+
AST_Node(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc)
224+
: identifier(t_id)
225+
, text(std::move(t_ast_node_text))
226+
, location(std::move(t_loc)) {
227+
}
228+
};
229+
169230
/// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree
170231
using AST_NodePtr = std::unique_ptr<AST_Node>;
171232
using AST_NodePtr_Const = std::unique_ptr<const AST_Node>;
172233

173-
struct AST_Node_Trace;
234+
struct AST_Node_Trace {
235+
const AST_Node_Type identifier;
236+
const std::string text;
237+
Parse_Location location;
238+
239+
const std::string &filename() const noexcept { return *location.filename; }
240+
241+
const File_Position &start() const noexcept { return location.start; }
242+
243+
const File_Position &end() const noexcept { return location.end; }
244+
245+
std::string pretty_print() const {
246+
std::ostringstream oss;
247+
248+
oss << text;
249+
250+
for (const auto &elem : children) {
251+
oss << elem.pretty_print() << ' ';
252+
}
253+
254+
return oss.str();
255+
}
256+
257+
std::vector<AST_Node_Trace> get_children(const AST_Node &node) {
258+
const auto node_children = node.get_children();
259+
return std::vector<AST_Node_Trace>(node_children.begin(), node_children.end());
260+
}
261+
262+
AST_Node_Trace(const AST_Node &node)
263+
: identifier(node.identifier)
264+
, text(node.text)
265+
, location(node.location)
266+
, children(get_children(node)) {
267+
}
268+
269+
std::vector<AST_Node_Trace> children;
270+
};
174271

175272
/// \brief Classes which may be thrown during error cases when ChaiScript is executing.
176273
namespace exception {
@@ -495,106 +592,14 @@ namespace chaiscript {
495592

496593
} // namespace exception
497594

498-
/// \brief Struct that doubles as both a parser ast_node and an AST node.
499-
struct AST_Node {
500-
public:
501-
const AST_Node_Type identifier;
502-
const std::string text;
503-
Parse_Location location;
504-
505-
const std::string &filename() const noexcept { return *location.filename; }
506-
507-
const File_Position &start() const noexcept { return location.start; }
508-
509-
const File_Position &end() const noexcept { return location.end; }
510-
511-
std::string pretty_print() const {
512-
std::ostringstream oss;
513-
514-
oss << text;
515-
516-
for (auto &elem : get_children()) {
517-
oss << elem.get().pretty_print() << ' ';
518-
}
519-
520-
return oss.str();
521-
}
522-
523-
virtual std::vector<std::reference_wrapper<AST_Node>> get_children() const = 0;
524-
virtual Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const = 0;
525-
526-
/// Prints the contents of an AST node, including its children, recursively
527-
std::string to_string(const std::string &t_prepend = "") const {
528-
std::ostringstream oss;
529-
530-
oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") " << this->text << " : " << this->location.start.line
531-
<< ", " << this->location.start.column << '\n';
532-
533-
for (auto &elem : get_children()) {
534-
oss << elem.get().to_string(t_prepend + " ");
535-
}
536-
return oss.str();
537-
}
538-
539-
static bool get_bool_condition(const Boxed_Value &t_bv, const chaiscript::detail::Dispatch_State &t_ss) {
595+
//static
596+
bool AST_Node::get_bool_condition(const Boxed_Value &t_bv, const chaiscript::detail::Dispatch_State &t_ss) {
540597
try {
541598
return t_ss->boxed_cast<bool>(t_bv);
542599
} catch (const exception::bad_boxed_cast &) {
543600
throw exception::eval_error("Condition not boolean");
544601
}
545-
}
546-
547-
virtual ~AST_Node() noexcept = default;
548-
AST_Node(AST_Node &&) = default;
549-
AST_Node &operator=(AST_Node &&) = delete;
550-
AST_Node(const AST_Node &) = delete;
551-
AST_Node &operator=(const AST_Node &) = delete;
552-
553-
protected:
554-
AST_Node(std::string t_ast_node_text, AST_Node_Type t_id, Parse_Location t_loc)
555-
: identifier(t_id)
556-
, text(std::move(t_ast_node_text))
557-
, location(std::move(t_loc)) {
558-
}
559-
};
560-
561-
struct AST_Node_Trace {
562-
const AST_Node_Type identifier;
563-
const std::string text;
564-
Parse_Location location;
565-
566-
const std::string &filename() const noexcept { return *location.filename; }
567-
568-
const File_Position &start() const noexcept { return location.start; }
569-
570-
const File_Position &end() const noexcept { return location.end; }
571-
572-
std::string pretty_print() const {
573-
std::ostringstream oss;
574-
575-
oss << text;
576-
577-
for (const auto &elem : children) {
578-
oss << elem.pretty_print() << ' ';
579-
}
580-
581-
return oss.str();
582-
}
583-
584-
std::vector<AST_Node_Trace> get_children(const AST_Node &node) {
585-
const auto node_children = node.get_children();
586-
return std::vector<AST_Node_Trace>(node_children.begin(), node_children.end());
587-
}
588-
589-
AST_Node_Trace(const AST_Node &node)
590-
: identifier(node.identifier)
591-
, text(node.text)
592-
, location(node.location)
593-
, children(get_children(node)) {
594-
}
595-
596-
std::vector<AST_Node_Trace> children;
597-
};
602+
}
598603

599604
namespace parser {
600605
class ChaiScript_Parser_Base {

unittests/compiled_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ TEST_CASE("Use unique_ptr") {
10321032
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser());
10331033

10341034
chai.add(chaiscript::fun([](int &i) { ++i; }), "inci");
1035-
chai.add(chaiscript::fun([](int i) { ++i; }), "copyi");
1035+
chai.add(chaiscript::fun([]([[maybe_unused]] int i) { ++i; }), "copyi");
10361036
chai.add(chaiscript::fun([](int *i) { ++(*i); }), "derefi");
10371037
chai.add(chaiscript::fun([](const std::unique_ptr<int> &i) { ++(*i); }), "constrefuniqptri");
10381038
chai.add(chaiscript::fun([](std::unique_ptr<int> &i) { ++(*i); }), "refuniqptri");

unittests/static_chaiscript.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@
66
/// ChaiScript as a static is unsupported with thread support enabled
77
///
88

9+
#if defined(__clang__)
10+
#pragma clang diagnostic push
11+
#pragma clang diagnostic ignored "-Wexit-time-destructors"
12+
#pragma clang diagnostic ignored "-Wglobal-constructors"
13+
#endif
14+
915
#include <chaiscript/chaiscript.hpp>
1016

11-
static chaiscript::ChaiScript chai;
17+
static chaiscript::ChaiScript chai{};
1218

1319
int main() {}

0 commit comments

Comments
 (0)