* Fix#201: Add class inheritance support with Derived : Base syntax
Classes can now inherit methods and attributes from a base class using
C++-style syntax: `class Derived : Base { ... }`. Base class methods and
attributes are automatically available on derived objects. Derived classes
can override base methods by defining a method with the same name.
Inheritance relationships are tracked to support proper type matching
in the dispatch system.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: use implicit derived-to-base matching instead of copying base class functions
Instead of copying all base class methods/attributes into derived classes,
make the type matching system recognize inheritance relationships. Base class
methods now naturally match derived objects through dynamic_object_typename_match,
and dispatch ordering ensures derived overrides are preferred over base methods.
This is simpler (net -25 lines) and avoids duplicating function registrations.
Requested by @lefticus in PR #641 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add tests for passing derived objects to functions expecting Base
Tests cover: free functions calling base methods on derived objects,
polymorphic dispatch through containers, base attribute access on
derived objects, and multi-level inheritance (GrandChild : Derived : Base).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add typed parameter tests for class inheritance
Use typed function signatures (e.g., `def call_do_something(Base obj)`)
instead of untyped parameters to test that derived objects are accepted
by functions expecting a base type, with correct polymorphic dispatch.
Requested by @lefticus in PR #641 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: leftibot <leftibot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add both a compiled C++ test (with registered type_conversion) and a
pure ChaiScript test (with dynamic objects and custom == operator) to
verify that switch case comparisons properly manage object lifetimes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Function_Push_Pop to Switch_AST_Node case comparison to properly
manage the lifetime of temporaries created during type conversions.
Make Binary_Operator_AST_Node::do_oper static and public so it can be
reused by Switch_AST_Node for case equality checks, ensuring consistent
lifetime management across all operator invocations.
Original-PR: #422
Co-Authored-By: dinghram <don.inghram@gmail.com>
The cheatsheet's "ChaiScript Defined Types" section was minimal, showing only
a basic class with one attribute and a getter. Expanded it to document block
syntax, open syntax, attribute keywords (var/attr/auto), constructor and method
guards, operator overloading, cloning, and added a test exercising all examples.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add comprehensive reflection documentation to cheatsheet.md covering type
inspection, object methods, Type_Info, function introspection, system
introspection, and Dynamic_Object reflection. Add missing global reflection
functions (type_name, is_type, function_exists, get_functions, get_objects,
type, dump_system, dump_object) and is_type_arithmetic to the Doxygen
prelude docs. Include a thorough test exercising all documented features.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Using GCC 13.3.0 I get warnings like the following:
```
In file included from .../ChaiScript/static_libs/../include/chaiscript/language/chaiscript_optimizer.hpp:10,
from .../ChaiScript/static_libs/../include/chaiscript/language/chaiscript_parser.hpp:26,
from .../ChaiScript/static_libs/chaiscript_parser.cpp:1:
.../ChaiScript/static_libs/../include/chaiscript/language/chaiscript_eval.hpp: In instantiation of ‘chaiscript::Boxed_Value chaiscript::eval::Global_Decl_AST_Node<T>::eval_internal(const chaiscript::detail::Dispatch_State&) const [with T = chaiscript::eval::Tracer<chaiscript::eval::Noop_Tracer_Detail>]’:
.../ChaiScript/static_libs/../include/chaiscript/language/chaiscript_eval.hpp:503:19: required from here
.../ChaiScript/static_libs/../include/chaiscript/language/chaiscript_eval.hpp:504:28: warning: possibly dangling reference to a temporary [-Wdangling-reference]
504 | const std::string &idname = [&]() -> const std::string & {
| ^~~~~~
.../ChaiScript/static_libs/../include/chaiscript/language/chaiscript_eval.hpp:510:10: note: the temporary was destroyed at the end of the full expression ‘<lambda closure object>chaiscript::eval::Global_Decl_AST_Node<chaiscript::eval::Tracer<chaiscript::eval::Noop_Tracer_Detail> >::eval_internal(const chaiscript::detail::Dispatch_State&) const::<lambda()>{((const chaiscript::eval::Global_Decl_AST_Node<chaiscript::eval::Tracer<chaiscript::eval::Noop_Tracer_Detail> >*)this)}.chaiscript::eval::Global_Decl_AST_Node<chaiscript::eval::Tracer<chaiscript::eval::Noop_Tracer_Detail> >::eval_internal(const chaiscript::detail::Dispatch_State&) const::<lambda()>()’
504 | const std::string &idname = [&]() -> const std::string & {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
505 | if (this->children[0]->identifier == AST_Node_Type::Reference) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
506 | return this->children[0]->children[0]->text;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
507 | } else {
| ~~~~~~~~
508 | return this->children[0]->text;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
509 | }
| ~
510 | }();
| ~^~
```
Fix this by replacing the lambda with a simple ternary operator
expression.
ChaiScript inherits from ChaiScript_Basic, so this is good practice.
I also need to be able to inherit from ChaiScript and dynamic cast, which is impossible without this destructor.
I initially tried to use the existing .clang-format file,
but it does not match the code style (at least with clang-format 11)
and the formatting is not consistent across files.
Therefore, I decided to rewrite the .clang-format with some personal
preferences.
Used command
find . -iname "*.hpp" -o -iname "*.cpp" | xargs clang-format -i -style=file