Fix #677: Add strong typedefs#680
Conversation
…yntax 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) <[email protected]>
|
@leftibot add a to_underlying function to be able to get the underlying type/value |
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 ChaiScript#680 review. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Addressed review feedback from @lefticus. New commits: |
|
@leftibot strong typedef should demonstrate the same properties of the underlying type. |
|
Yes, this is possible and should be done. Let me explain the current state and what's needed. What already works (partially): The What doesn't work: Arithmetic and relational operators ( if (t_oper != Operators::Opers::invalid && t_lhs.get_type_info().is_arithmetic() && t_rhs.get_type_info().is_arithmetic()) {
return Boxed_Number::do_oper(t_oper, t_lhs, t_rhs);Strong typedefs are What needs to happen: When creating a strong typedef, we should register forwarding operators that unwrap
The cleanest approach: register these as Members: For strong typedefs over class types (e.g.,
Option 1 is more general but requires changes to Recommendation: I'd implement the operator forwarding first (comparison + arithmetic) since that covers the |
|
@leftibot this needs to work generically well with any type. Can we use method_missing or something like that? |
|
Yes, How
|
|
@leftibot I think the strong typedef is useless if the Meters + Meters returns an int. But we also have a problem with integer promotion rules such that uint8 + uint8 => int. this is what I want you to do: Expose all of the common arithmetic operations, if they exist, and make them strongly typed Meters + Meters -> Meters; Meters * Meters -> Meters But also make sure and add tests so that: using StrongString = string; Then also expose all of the comparison operations that exist StrongString < StrongString -> bool Then also make sure that the user can extend the strong typedefs, adding their own operations. def Take the above examples as pseudocode. There might be a better way to accomplish this: TL;DR: All common operators that exist should be exposed and strongly typed, and the user should be able to extend the typdef. |
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 ChaiScript#680 review. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Addressed review feedback from @lefticus. New commits: |
|
@leftibot resolve merge conflicts and add support for the rest of the binary operators - if they exist for the given type. It looks like right now the operators are being added regardless, then may error. This is going to be confusing to anyone using reflection in the ChaiScript system, to see a |
…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 ChaiScript#680 review. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Addressed review feedback from @lefticus. New commits: |
|
@leftibot on second thought - register the functions no matter what - it's possible the user could add them later, plus the tests to see if they could work is complicated and expensive. Also - make sure things like |
…nd 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 ChaiScript#680 review. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Addressed review feedback from @lefticus. New commits: |
|
@leftibot resolve merge conflicts with ChaiScript:develop and update docs to demonstrate this new feature. |
Resolve merge conflicts with ChaiScript:develop. Upstream added nested namespace support (ChaiScript#675), grammar railroad diagrams (ChaiScript#673), and WASM exception support (ChaiScript#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) <[email protected]>
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 ChaiScript#680 review. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Addressed review feedback from @lefticus. New commits: |
|
@leftibot carefully resolve merge conflicts with ChaiScript:develop |
Carefully resolved merge conflicts to preserve both the strong typedef (using) feature from this branch and the enum support (ChaiScript#679), nested namespaces (ChaiScript#552), grammar diagram (ChaiScript#628), and WASM exception (ChaiScript#678) features from upstream develop. All 376 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Addressed review feedback from @lefticus. New commits: |
Automated fix by @leftibot.
What changed
Files
Closes #677
Triggered by @lefticus.