Stuff at compile time?

BlitzMax Forums/BlitzMax Programming/Stuff at compile time?

Picklesworth(Posted 2007) [#1]
The answer is probably a very big "NO", but I might as well ask.

I am writing a system which has now regrettably resorted to Strings in order to keep track of data for certain objects.
(A better description: It is an Extensions system where Extensions which may or may not exist are linked to Containers which may or may not exist based on key / value combinations that are stored in a TMap - though there is a high chance that said keys do not exist because they are specifically set by different Containers (which as I already said may or may not exist in a manner essentially unknown by the actual program), thus breaking things if the program is compiled as Strict).

This is unfortunate to be using strings, because the whole process of keeping track of data for those objects is hidden away thus rendering their use pointless!
Not too much of a problem for processing speeds because it only happens at particular moments, and memory waste is hardly a problem, but it just looks DUMB!
( And dumb is just not acceptable at this point, since I've now scratched out every bit of wonderful automagic code I previously had :( )

My last hope to make this system actually sane, I suspect, is a precompiler. (That, or I wait for the DLL support to be officially "Usable")
Is it possible to write code in BlitzMax that runs in its precompiler?

Theoretically, it could be quite possible, with the precompiler getting an in-line precompiling program compiled, running that, then finishing compiling the actual program. Of course, there would have to be some pretty creepy stuff going on for that to actually work; I realize that I am simplifying immensely and it would actually be both very difficult and near impossible.

There are unofficial precompilers such as BLIde's, which could work well, but I don't want to have people tethered to a single IDE.

So, thinking before compilation in BlitzMax, in any way at all, no matter how simple: Is it possible?

Even something really simple, like "If some constant is set, compile this code, otherwise remove it!"


Azathoth(Posted 2007) [#2]
Blitzmax has very little in the way of a precompiler, currently you're stuck with ?Win32, ?MacOS, ?Linux, ?LittleEndian, ?BigEndian; maybe more but as far as I know no way to create your own.


JazzieB(Posted 2007) [#3]
Speaking of the If..<constant>..Then thing, I've been meaning to ask this for ages. Anyway, in previous Blitz versions (B3D, for example) you could do this...

Const releaseBuild=True

If releaseBuild Then
  ..full version extra goes here..
Else
  ..nag screen..
EndIf


In B3D it would not compile any code that had absolutely no chance of getting executed because it was bound by a constant.

Is this the same for BlitzMax? I seem to remember someone saying a while ago that BlitzMax just compiled everything, so I now find myself having seperate final sources for release and demo versions, which is not good and a pain if I need to change anything that's present in both.


Azathoth(Posted 2007) [#4]
I did a test awhile ago, it does seem to remove unused variables and maybe strings but doesn't use this conditional compiling like the previous blitzbasics.


SculptureOfSoul(Posted 2007) [#5]
One thing you could do to control what gets compiled and what doesn't is to use a temporary "marker" like so in the following

'Tag-FullVersionBegin
insert full version only code here
'Tag-FullVersionEnd


And then, when you are going to compile your demo version, do a search and replace and replace 'Tag-FullVersionBegin with "?Debug" and 'Tag-FullVersionEnd with "?"

If you build it in release mode then that code won't be compiled.


SculptureOfSoul(Posted 2007) [#6]
It's hard to offer more help without having a better idea of how your extensions actually interface with the main program and such. From your description above I really have no clue what you are trying to do exactly. I don't see how a precompiler is going to help in a situation where you have extensions that may or may not exist. Are these extensions external processes?


Picklesworth(Posted 2007) [#7]
Hm... In that case, I guess a feature request would be in order.
Why doesn't that "?" thing act as an If statement that happens in the precompiler, where Win32, Linux, MacOs, etc. are constants.


Okay, so at the moment every extension is compiled into the program, added by Include. (Yes, I know Include is dumb, blah blah blah).Those Extensions contain a variety of functions.
Outside of those Extensions, there are Extension Containers. The containers store a selection of extensions' functions.
The idea here is that any piece of code can have a Container tossed onto it, thus making it possible to add more code to it. (Rather simplistic, but it seems workable).
With that ugly design, an Extension can be added (some day...), removed, disabled, enabled or reconfigured on the fly!

Adding extension functions to the appropriate containers is where is gets (more) fuddly.

Each Extension Function has a bunch of key/value pairs set to it which help to identify it to certain extension containers. The keys may be set with Extension Containers themselves (as global variables), though there are a few set by the core Extensions system. An example of one of these keys is "FileType", into which one puts the file type that a mesh loader extension loads.
Those sorts of values cannot be hard-coded into the core, because the system should be very generic. (Having a FileType variable hard-coded into every Extension Function object is certainly not a wise move).
Having them as Strings is wasteful, and having them just as straight variable names breaks the ability to compile in Strict; there seems no way to actually check if a variable is set other than expecting the precompiler to define it as 0 for me if it doesn't exist! (And since that seems all the precompiler will do for me in that department, it is a bit stuck).
Feel free to prove me wrong, please!

An Extension Function object has a method which gets it to loop through every container and find the ones that want to use it.
This is done via a callback function set for each extension container; that function looks at an extension function's key / value pairs in order to decide if it is an appropriate extension function for that container.
If it is, it is added to that Container's list of contained functions :)


Yep, it's a bit convoluted, sort of like one of those Rube Goldberg contraptions!


SculptureOfSoul(Posted 2007) [#8]
Well, I'm just about as clueless as before as to exactly what you're doing and why, but that's probably due to me and not your explanation :P.

Anyhow, I'd look into Lua or using hash tables as your container objects. You can define new key pairs on the fly and you won't bomb out if you check for a key that doesn't exist.

Sorry if this isn't much help - I'm sure a more experienced coder can offer better advice.


ImaginaryHuman(Posted 2007) [#9]
I wish max had a full set of precompiler directives that let you create macros like in a macro assembler.


Picklesworth(Posted 2007) [#10]
Ah, LUA!

That's a good idea, SculptureOfSoul!
I'm sure LUA knows how to handle string/value pairs such that they don't slow everything down.
Do you know if there is a way to get its various variable management things going without having to parse a script file?
Although I guess even if it does end up with a script file, I could use it to my advantage somehow... (I guess I'll have to, actually, since LUA is a rather big thing to use for something so tiny).


The reason I don't want to do horrible String comparisons myself: I saw what happened to BlitzUI :(