xsharp.eu • Accessing globals/defines from MCompile
Page 1 of 1

Accessing globals/defines from MCompile

Posted: Thu Dec 01, 2022 11:21 am
by fxm
Hi,

Is there a way to compile a codeblock from a string at runtime that can access globals and defines?

I've tried MCompile and creating an instance of XSharp.Runtime.MacroCompiler but can't seem to get it to work.

Thanks,
Fergus

Code: Select all

GLOBAL cGlobal := "Global" AS STRING
DEFINE cDefine := "Define" AS STRING

FUNCTION Start() AS VOID STRICT

LOCAL compileTimeCodeblock AS CODEBLOCK
LOCAL cbStr  AS STRING
LOCAL runTimeCodeblock AS CODEBLOCK

compileTimeCodeblock := {|| cGlobal } 
Console.WriteLine(Eval(compileTimeCodeblock)) //Global

cbStr := "{|| GetGlobal() }"
runTimeCodeblock := MCompile(cbStr)
Console.WriteLine(Eval(runTimeCodeblock)) //Global

cbStr := "{|| cGlobal }" 
runTimeCodeblock := MCompile(cbStr)  
Console.WriteLine(Eval(runTimeCodeblock)) //Error - Variable does not exist

Console.ReadKey()

FUNCTION GetGlobal() AS STRING
RETURN cGlobal


Accessing globals/defines from MCompile

Posted: Thu Dec 01, 2022 11:53 am
by robert
Fergus,

At this moment globals are not supported.
We found some problems when we did this because there could be conflicts between field names in index expressions and global names.
For example in a customer application there was a global "Test" and also a string field "Test" in a DBF.
The DBF had an index expression "UPPER(TEST)" and the macro compiler was picking up the Test global (which was not a string in this case).
This resulted in runtime errors that were very difficult to diagnose.

Robert

Accessing globals/defines from MCompile

Posted: Thu Dec 01, 2022 2:11 pm
by fxm
Ok, thanks for the explanation Robert!

Accessing globals/defines from MCompile

Posted: Thu Dec 08, 2022 8:44 am
by robert
Fergus,
I think I may have found a way to support this.
I will include that in the next build.
The way it works is this:
- The macrocompiler itself does not include support for Globals, to make sure that a global cannot interfere with field names during macro compilation
- instead it sees the name and adds a call to __VarGet(), a runtime function that is used to find the value of either a field or a (private or public) memvar.
- I have changed __VarGet() to check for a field first and when that does not exist then check for a global in the app
- if the global does not exist then the original behavior is executed and the runtime checks for a memory variable

This seems to work as intended.

Robert

Accessing globals/defines from MCompile

Posted: Sat Dec 10, 2022 7:49 am
by fxm
Fastastic, thanks Robert.

I look forward to trying it whenever it's ready.

Fergus