Advertisement

Adding Support for Custom Literal Constants

Started by December 19, 2024 04:02 PM
5 comments, last by WitchLord 1 day, 1 hour ago

My recent project needs fixed point float, it would be nice to have AngelScript support custom literal, e.g. 3.14f32 to define fixed32 literal constant. I've noticed that some people already suggested this feature in To-Do list a decade ago.

I'm investigating the compiler of AngelScript and trying to add something like user-defined literals of C++ (operator""_suffix).

My currently planned solution is to add new behaviors asBEHAVE_LITERAL_CONSTRUCT/FACTORY and use the name of behavior as the suffix, e.g. RegisterObjectBehaviour("void f32(double)") for f32 suffix.

The parameters of special functions can be one of the following (with example usage)

  1. uint64: void h(uint64) for 1h for convenient date time interface
  2. double: void i(double) for imaginary number.
  3. const string&in for constructing a literal from string. It requires the host to register string support at first.
  4. int&in, uint, the C++ side will be const char*, asUINT. It will directly pass the source code of literal in script for parser provided by user. This might need the engine to expose some utilities such as tools for parsing script string literal.

For example, maybe we can implement a fmt suffix for formatting after this feature is done.

int val = 42;
string str = "hello";

string result = "val = {val}, str = {hello}"fmt;
// result is "val = 42, str = hello"

Please give some suggestion on this solution.

For reference: User-defined literals (since C++11) - cppreference.com

None

This sounds nice. I would also recommend instead of only supporting suffix, also support prefix. This is a bit more common in other programming languages when it comes to interpolated strings. For example, in C# you could do: $"val = {val}".

Advertisement

I don't really have any suggestion on this. I never started looking into this. I'm travelling for the next few weeks, so I won't be able to look into it this moment.

But I feel you're on the right path. To Miss' suggestion I think you could add to the function name something like _suffix or _prefix to tell the compiler which option to use.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Your approach is correct. For flexibility, expose utility functions for parsing raw literals (e.g., int&in as const char*). Support numeric (uint64, double) and string-based (const string&in) literals for varied use cases.

Here’s a more detailed example of how your solution might look with the f32 suffix:

// registering behavior for f32 suffix
engine->RegisterObjectBehaviour("Fixed32", asBEHAVE_LITERAL_CONSTRUCT, "void f32(double)", asFUNCTION(Fixed32Constructor), asCALL_CDECL);

// example script usage
Fixed32 fixedValue = 3.14f32;

For the fmt literal:

// registering fmt behavior
engine->RegisterObjectBehaviour("string", asBEHAVE_LITERAL_CONSTRUCT, "void fmt(const string&in)", asFUNCTION(FormatConstructor), asCALL_CDECL);

// example script usage
int val = 42;
string str = "hello";
string result = "val = {val}, str = {str}"fmt;

The FormatConstructor would parse the string, replace placeholders with variable values, and return the resulting string.

-kammes- tag unblocked

Maybe we can have asBEHAVE_LITERAL_CONSTRUCT/FACTORY_PREFIX/SUFFIX for both user-defined prefix / suffix literals. But the user-defined prefix should only accept string, because f123 has ambiguity with an identifier.

In addition, maybe it also needs something like template callback to validate the user-defined literal? For example, if you have a suffix for fixed point number registered as void f32(int&in, uint) with a custom parser, you may want to only accept 3.14f32, while rejecting "str"f32 at compile-time. So, I think maybe there should be new behaviors called asBEHAVE_LITERAL_CALLBACK_PREFIX/SUFFIX too. The parameters are similar to the user-defined literals, but instead returning a Boolean value for validation.

None

I think it might be more elegant to do a solution similar to asBEHAVE_LIST_FACTORY https://angelcode.com/angelscript/sdk/docs/manual/doc_reg_basicref.html#doc_reg_basicref_4

Example “void f(double) {'f32' suffix}”

This will make it easier to support symbols such as $ that are normally not part of identifiers.

Yes, support for a callback is necessary as well to catch errors at compile time.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement