Advertisement

Adding Support for Custom Literal Constants

Started by December 19, 2024 04:02 PM
3 comments, last by kammes 2 days, 8 hours 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.

Advertisement