Since my early days as a C++ developer I wanted to use C++ code snippets as a standalone script file.
Like just type the following C++20 code snippet (see my previous blog post) in a file and then execute it:
auto value( auto v )
{
// unnamed concept in constexpr if branch!
if constexpr ( requires { v.value; } ) { // if type of v has a .value use this branch.
return v.value;
} else {
return v;
}
}
long long x = 33;
value( x );
But how can this be made possible??
Develop an interpreter which supports the complete set and features of C++ is not really an option because the work, which has to be done, is a way more too big for a single developer and also even for a small group of developers.
What else could be done?
The script host application, which will execute the script, could compile the script on the fly with a regular compiler and immediately execute the compiled binary and then catch and return the result.
But a C++ program needs a main function as an entry point!
One idea is that the script code will be injected in a temporary skeleton file which is containing a main function, which will then execute the code.
But there are a lot of limitations and pitfalls. For example, it is impossible to define a function inside the main function (more precisely: inside any other function).
So, with the code snippet from above, the function definition must be placed outside the main function but the function call must be placed inside the main function. The variable x however can be placed inside or outside the main function, but each of it will lead to a different visibility and lifetime.
A result of the code injection might look like this:
auto value( auto v )
{
// unamed concept in constexpr if branch!!!
if constexpr ( requires { v.value; } ) { // if type of v has a .value use this branch.
return v.value;
} else {
return v;
}
}
long long x = 33; // could be here as a GLOBAL variable.
int main()
{
long long x = 33; // or here as a LOCAL variable.
return value( x ); // please note the prepended 'return'
}
Can this be achieved and how?
Well, before think about it, let’s check the next script example …
int a = 2;
int foo( int x ) // must be placed outside main
{
return x * a; // using 'a', so 'a' must be global
}
// a freestanding if-statement is not possible!
// so it must be placed in main
if( a <= 2 ) {
a += 2; // NOTE: changing 'a'
}
int b = foo( 4 ); // foo uses 'a'!
// if 'b' is outside main (global), then this line gets invoked
// before the if-statement above is executed and thus 'b' will
// have a different value than expected!
void bar( int y ) // must be placed outside main
{
//using 'b' in function, so 'b' must be global.
printf( "y * b = %d", y * b );
}
bar( 3 ); // inside main
//when invoke the script shall print "y * b = 48"
Even with this small (of course nonsense, but valid!) code snippet, you get an idea already how difficult and even impossible(?) it might become.
You do not only need to parse and understand the code first for decide for each statement/block if it must/should be part of the main function or not. No, there might be also decisions which depends of other statements/blocks!
And finally it is even worst. As you can see above, the if-statement (line 9) must be executed before the assignment of ‘b’ in line 13 (because it might change ‘a’ on which ‘b’ depends on), but the if-statement must be placed in main while on the same time ‘b’ must be placed outside main (because it must be accessible in function bar), which will then lead to a wrong execution order!
So with this approach the code snippet above is impossible to implement!
At his point I gave up to think more about that solution.
The only left idea which came to my mind was to maybe use some part of LLVM (the frontend) and then shuffle around the produced intermediate result to make it executable and then use LLVM again to create a binary executable. But for that I actually know too less about the internals of LLVM. So, I put this task back for a “small exercise” somewhen in the future… 😉
During my research the idea of TeaScript came up and I started to focus on that project.