#define equivalent
BlitzMax Forums/BlitzMax Programming/#define equivalent
| ||
Comming from a C/C++ environment, I miss the #define directive. I know there's "?Win32", "?Debug", "?Threaded" and so on... but is there any way to define my own? What I'd like to do is stick "?[something]" around my code and have a single define switch from my editor to the game itself. This way I make sure that any updates to the engine are instantly visible in both the editor and game. There is a way to do this... if I split the editor and game code entirely and keep some core code in includes. But that is really hacky, especially when I have something like: Type MyType Method New() ?Editor myTreeView.AddTreeViewNode(myInstanceName) ? 'fill in the fields values, etc. EndMethod EndType Is there any way to define my own precompiler constants? If not (very likely) how would you go about doing this? |
| ||
If not (very likely) how would you go about doing this? You'd need to write your own pre-compiler, which processes your .bmx files and creates a "processed" version of the source which you could then pass to the standard build process. Not sure if it's been mentioned around here, but I think someone made a pre-processor on the German forum. |
| ||
Hm... sound like a good idea. I'll give this a try and post my results :) |
| ||
This gets complicated when it comes to debugging. The debugger will be giving line numbers that correspond to the file that was sent to the compiler, but if you edit the version that came out of your pre-compiler, the changes don't make it in to the original source. I am not saying it can't be done, but it will take a lot of work. |
| ||
According to this thread http://www.blitzbasic.com/Community/posts.php?topic=41598#467399 from several years ago you can sort of conditional compile if you use a const as the test in an if statement. I dont know if it still works but might be worth trying. a #define #if #endif request has been made afew times but not happened it seems. |
| ||
I've occasionally wished for a ?Custom thing too! |
| ||
Consts won't work. In my above example, there's no "myTreeView" declared inside the "game". The debugging issue is interesting. However, I can temporarily output some sources and use those to do the debugging. After that, move on to fixing stuff in the original code. However, I am not too concerned about this as I rarely use the debugger for stepping through the program in bmax. I use it often in C++, but since the bmax debugger is vastly inferior, I just stick to "DebugLog", "DrawText" and "Notify" to do the debugging :) |
| ||
If someone adds a pre-processor to the IDE that would do it... Thats like regions... the IDE could add folding to those as well |
| ||
Could you not just write a simple app to Rem and 'Rem any lines within a ?<Custom> block, as a one click 'pre-compile' process? Or does the IDE have hooks for pre/post compile processing? |
| ||
That's a good idea Merx. Then the debugging would line up... But another nice feature to have in a pre-compiler would be a macro/inline type functionality, which you could not do with Rem statements. Though you could do it with includes. |
| ||
That's a very nice idea, Merx. There might be issues if you have a "Rem..EndRem" inside a "?Custom..?", but those can be easily eliminated (replaced with anything else but not erased completely because they'll mess up line numbers). I'm quite eager to try this... must find time! |
| ||
You don't have to Rem - End Rem them. Just put an apostrophe in front of the lines in the ?Custom block. Then the line numbers don't change, and there is no way there can be a conflict with other rem statements. |
| ||
That kind of defeats the purpose if you have to manually comment out each line, if we could use are own ?define it saves time and is the point ;) |
| ||
@joncom2000 That's what TaskMaster was talking about: AUTOMAGICALLY put an apostrophe in front of every line. |
| ||
Yes, you could have a preprocessor that looked through your source file and commented out the user defines that got defined away. You could even make the user defines a special comment that only the preprocessor would recognize, so they didn't mess up anything else. Like: 'define MyTest And '?MyTest Then just run through the source files. Remember the 'define lines you find. If you see a '? directive and haven't found a define for it, then put apostrophes in front of all the lines. Would be fairly easy and unobtrusive. I wonder if Blide is capable of allowing a preprocessor. Maybe using the BLide SDK... |
| ||
Well, if you convert boredom at work into a productive period of time, you get this:SuperStrict Global compiler_args:String = " " Global compiled_file:String Global compiler_path:String = "C:\Program Files\BlitzMax\bin\bmk" Global temp_files:TList = New TList Type Definition Global DefList:TList = New TList Field n:String 'name Field v:String 'value Method New() DefList.AddLast(Self) End Method Function Find:Definition(n:String) For Local d:Definition = EachIn DefList If (d.n = n) Return d End If Next End Function End Type Local arg:String AppArgs[0] = "" For arg = EachIn AppArgs Local ext:String If arg.Length > 4 ext = Right(arg, 4) If Lower(ext) = ".bmx" ProcessFile(arg) compiled_file = arg Else compiler_args:+arg + " " End If Else compiler_args:+arg + " " End If Next system_(compiler_path + " " + compiler_args + " " + Replace(AppDir, "/", "\") + "\" + compiled_file + "_out.bmx") Function ProcessFile(f:String) If (FileType(f) <> 1) Notify ("Cannot find file: " + f, True) End If temp_files.AddLast(f + "_out.bmx") Local fs:TStream = ReadFile(f) Local fo:TStream = WriteFile(f + "_out.bmx") While Not Eof(fs) Process(fs, fo, f) Wend CloseFile(fs) CloseFile(fo) End Function Function Process(s:TStream, os:TStream, crtfile:String = "") Local processed_line:String Local out_line:String Local indent:String While Not Eof(s) indent = ReadLine(s) processed_line = Trim(indent) indent = Replace(indent, processed_line, "") out_line = processed_line Select True Case (Lower(Left(processed_line, 8)) = "'#define") Local def:String[] def = processed_line.Split(" ") Local d:Definition = New Definition d.n = def[1] If (def.Length > 2) d.v = def[2] End If WriteLine(os, indent + out_line) Case (Lower(Left(processed_line, 7)) = "'#ifdef") Local cond:String[] cond = processed_line.Split(" ") Local d:Definition = Definition.Find(cond[1]) If (d <> Null) WriteLine(os, indent + out_line) Process(s, os) Else WriteLine(os, out_line) While (Not (Lower(Left(processed_line, 7)) = "'#endif")) processed_line = ReadLine(s) out_line = "'" + processed_line WriteLine(os, out_line) Wend End If Case (Lower(Left(processed_line, 7)) = "include") Local inc:String[] inc = processed_line.Split(" ") inc[1] = Replace(inc[1], "~q", "") ProcessFile(ExtractDir(crtfile) + inc[1]) WriteLine(os, "Include ~q" + inc[1] + "_out.bmx~q") Default WriteLine(os, indent + out_line) End Select Wend EndFunction For Local fl:String = EachIn temp_files DeleteFile(fl) Next End The basics are there. The code's a bit messy but does the job for now. Features: - supports definitions through: '#define - supports checking definitions through '#ifdef .. '#endif - supports included files - supports nested checks One thing that I didn't test yet (but will do when I get home): set the compiler path to "bmk_old", rename bmk.exe, then compile this preprocessor as bmk.exe. It should be working as it passes the arguments right through. EDIT: This doesn't work yet. It's fairly simple atm... feel free to bring modifications and improvements before I do :) EDIT2: It's driving me crazy not being able to place this between BLIde and bmk.exe. Anyone happen to have the preprocessor mentioned here: http://www.blitzbasic.com/Community/posts.php?topic=56393#627200 ? |
| ||
I don't understand why this isn't implemented in BLIde ;) This compiler directives are very useful. |
| ||
I made (long time ago) a similar thing: as I dont' like wasting my time typing something likeLocal window:tgadget,btn_add:tgadget,btn_remove:tgadget,btn_close:tgadget (note the :tgadget repeated 4 times...) I would like something like Local window,btn_add,btn_remove,btn_close as Tgadget (Tgadget is typed 1 time) So I wrote an application that 'read' and 'translated' the source code (I dont' remember where it is now...) like the one of _Jim (without Include support): the only problem is that my 'source code' (the one with the AS keyword) was/is not compatible with standard Blitzmax code...I can't use the 'hack' of the REM (') solution. To come back on topic, I would like some 'directive' support from Bmax (or standard IDE). |
| ||
Well, I managed to plug this in bmk.exe :) Still testing and fixing as its not fully working yet. It compiles my application just fine (including defines support) but it doesn't compile bmk itself. |