Add a customizable file reader callback to ChaiScript_Basic, following
the same pattern as set_print_handler. When set, the callback is invoked
instead of the default filesystem read, enabling use cases like encrypted
files, in-memory virtual filesystems, or platform-specific file access
(e.g., Android assets). The callback is settable from both C++ and
ChaiScript.
Co-authored-by: leftibot <leftibot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix#677: Add strong typedefs via 'using Type = BaseType' syntax
Strong typedefs create distinct types backed by Dynamic_Object, so
'using Meters = int' makes Meters a type that is not interchangeable
with int or other typedefs of int. The constructor Meters(val) wraps
the base value, and function dispatch enforces the type distinction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: add to_underlying function for strong typedefs
Registers a to_underlying() function for each strong typedef that
returns the wrapped base value from the Dynamic_Object's __value attr.
Requested by @lefticus in PR #680 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: expose strongly-typed operators for strong typedefs
Register forwarding binary operators at typedef creation time via a
custom Proxy_Function_Base subclass (Strong_Typedef_Binary_Op). Each
operator unwraps __value from both operands, dispatches on the
underlying types, and re-wraps arithmetic results in the typedef.
Comparison operators return the raw bool.
- Arithmetic: +, -, *, /, % → Meters + Meters -> Meters
- Comparison: <, >, <=, >=, ==, != → Meters < Meters -> bool
- Operators that don't exist on the base type error at call time
(e.g. StrongString * StrongString -> error)
- Users can extend typedefs with their own operations using
to_underlying() for unwrapping
Tests cover int-based arithmetic, string-based concatenation, string
multiplication error, comparison ops, type safety of results, and
user-defined operator extensions.
Requested by @lefticus in PR #680 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: conditionally register operators based on underlying type support
Only register strong typedef operators that actually exist for the
underlying type. Previously all operators were added unconditionally,
causing confusing reflection entries (e.g. * for StrongString) that
would fail at runtime. Now each operator is probed via call_match
against default-constructed base type values before registration.
Also adds bitwise/shift operators (&, |, ^, <<, >>) for types that
support them, and expands test coverage for unsupported operator
rejection.
Requested by @lefticus in PR #680 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: register all operators unconditionally and add compound assignment operators
Remove conditional operator registration (op_exists_for_base_type check)
since users could add underlying operators later, and the runtime check was
expensive. Operators that fail on the underlying type now error at call time
instead of being absent. Add compound assignment operators (*=, +=, -=, /=,
%=, <<=, >>=, &=, |=, ^=) via Strong_Typedef_Compound_Assign_Op which
computes the base operation and stores the result back in __value.
Requested by @lefticus in PR #680 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Merge upstream/develop into fix/issue-677-add-strong-typedefs
Resolve merge conflicts with ChaiScript:develop. Upstream added
nested namespace support (#675), grammar railroad diagrams (#673),
and WASM exception support (#689). Conflicts in chaiscript_common.hpp,
chaiscript_eval.hpp, and chaiscript_parser.hpp resolved by keeping
both Using and Namespace_Block AST node types.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: add strong typedef documentation to cheatsheet
Add a new "Strong Typedefs" section to the cheatsheet covering:
- Basic usage with `using Type = BaseType` syntax
- Arithmetic and comparison operator forwarding
- String-based strong typedefs
- Accessing the underlying value via to_underlying
- Extending strong typedefs with custom operations
Requested by @lefticus in PR #680 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>
* Fix#19: Add strongly-typed enum support to ChaiScript
Adds the ability to define enums inside ChaiScript with syntax:
enum Color { Red, Green, Blue }
enum Priority { Low = 10, Medium = 20, High = 30 }
Enum values are strongly typed Dynamic_Objects accessed via :: syntax
(e.g. Color::Red). A validating constructor from int is registered that
rejects values outside the defined range. Functions declared with an enum
parameter type (e.g. def fun(Color val)) correctly reject plain integers,
enforcing type safety at the dispatch level.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: simplify enum implementation
Remove Enum_Access AST node type — reuse Id_AST_Node for enum value
lookups by combining "EnumName::ValueName" at parse time. Replace
std::set with std::vector for valid value tracking (enums are small).
Net removal of ~18 lines.
Requested by @lefticus in PR #679 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: rename to_int to to_underlying, add switch tests
Requested by @lefticus in PR #679 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: enum class syntax, constructor, configurable underlying type
- Change syntax from `enum` to `enum class` (only strongly-typed enums)
- Support optional underlying type: `enum class Flags : char { ... }`
(defaults to `int` when omitted)
- Replace `from_int` with a constructor named after the enum type,
accessed as `Color::Color(1)` — the underlying type is no longer
hardcoded to int
- Use Boxed_Number for type-generic value storage and comparison
- to_underlying now returns the actual underlying type
Note: `Color(1)` syntax is not possible because ChaiScript's global
objects shadow functions with the same name; `Color::Color(1)` is the
C++-consistent alternative.
Requested by @lefticus in PR #679 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: support enum struct syntax alongside enum class
Requested by @lefticus in PR #679 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: update EBNF grammar and cheatsheet with enum documentation
Add enum production rules to the EBNF grammar. Add comprehensive enum
section to the cheatsheet covering syntax, explicit values, underlying
type specification, construction, to_underlying, comparison, type-safe
dispatch, and switch usage. Document that the underlying type must be a
numeric type (string cannot be used) and list all available types.
Requested by @lefticus in PR #679 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>
* Fix#628: Add EBNF grammar for railroad diagram generation
Add a formal EBNF grammar file (grammar/chaiscript.ebnf) that can be
pasted into rr (https://www.bottlecaps.de/rr/ui) to produce navigable
railroad diagrams of ChaiScript's syntax. The grammar was validated
against the parser implementation and covers all language constructs
including class inheritance, guard conditions, raw strings, and const
declarations that were missing from the original proposal. A reference
section was added to the cheatsheet, and a regression test exercises
every documented grammar construct.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: add grammar railroad diagram link to README
Add a Grammar section to readme.md linking to the EBNF grammar file
and to mingodad's railroad diagram generator for direct viewing.
Requested by @lefticus in PR #673 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>
* Fix#571: Add per-instance IO redirection via set_print_handler/set_println_handler
The print_string and println_string functions were previously registered as static
functions writing directly to stdout, making it impossible to redirect ChaiScript
output to custom destinations (e.g., GUI windows, loggers, or buffers). This moves
their registration from Bootstrap::bootstrap() to ChaiScript_Basic::build_eval_system()
as lambdas that dispatch through configurable std::function handlers, allowing each
ChaiScript instance to independently redirect its output via set_print_handler() and
set_println_handler().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: add IO redirection section to cheatsheet
Documents set_print_handler() and set_println_handler() with usage
examples for GUI embedding and output capture.
Requested by @lefticus in PR #657 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: define println in terms of print, expose set_print_handler to ChaiScript
Remove separate println_handler — println_string now dispatches through the
single print handler with a newline appended. Only set_print_handler is
needed to redirect all output. The set_print_handler function is also
registered in the ChaiScript engine, so scripts can capture and redirect
their own output.
Requested by @lefticus in PR #657 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: populate null print handler when No_IO is set
When No_IO is active, the default m_print_handler is now a no-op instead
of writing to stdout. The stdout handler is only installed when No_IO is
not set. Users can still override the handler via set_print_handler()
even with No_IO enabled.
Requested by @lefticus in PR #657 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>
* Fix#146: Add configuration options to selectively disable built-in functions
Add new Options enum values (No_Stdlib, No_IO, No_Prelude, No_JSON) that
allow users to control which parts of the standard library are registered.
Std_Lib::library() now accepts an options vector, and the ChaiScript
convenience class forwards its options to the library builder. This enables
use cases where only custom functions should be exposed to script users.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Address review: split Options into Options and Library_Options enums
Separate system-level options (No_Load_Modules, Load_Modules, No_External_Scripts,
External_Scripts) from library-level options (No_Stdlib, No_IO, No_Prelude, No_JSON)
into two distinct enum types. Add Library_Options as a parameter to the ChaiScript
constructor. Update tests to demonstrate both ChaiScript_Basic (explicit Std_Lib::library
call) and ChaiScript (library options via constructor parameter) usage.
Requested by @lefticus in PR #642 review.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add cheatsheet documentation for Options and Library_Options
Documents the two-enum configuration system: Options (engine-level:
load_module, use, eval_file) and Library_Options (stdlib-level:
No_Stdlib, No_IO, No_Prelude, No_JSON), with usage examples for
both ChaiScript and ChaiScript_Basic constructors.
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>
Updated the cheatsheet to clearly explain that `add` creates thread-local
scoped variables while `add_global`, `add_global_const`, and `set_global`
create global variables shared between all threads. Added a summary table
comparing scope, thread safety, and conflict behavior. Also added a test
exercising the key behavioral differences between these methods.
Co-authored-by: leftibot <leftibot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.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>
Currently, the example where a lambda function was added to chaiscript didn't work for me.
I use g++7, g++8,g++9 both with c++14 and c++17 mode.
It doesn't work either in clang++-7.
If the lambda is wrapped into a std::function<> it will work again!
- Simplified the part about ChaiScript initialization
- Added a link to the ChaiScriptExtras helper library
- Removed the Subsection about built-ins, because they are not longer in the code