editor side preprocessor

editor side preprocessor

1
NewbieNewbie
1

    Oct 05, 2012#1

    Hi everyone, i am working on a language called MQL and it does not support preprocessor commands such as #ifdef etc. Now i sit front of huge project which would need this because i dont want to split this project to seperate parts because later it will be heavy to update all parts and after a while sources will move away from eachother....

    I thought it would be great to have editor side preprocessor, something like:

    Code: Select all

    //#DEFINE TROMBO2
    
    //#IFDEF TROMBOBB || TROMBO2
    #include <trombobb.mqh>
    #define name "TROMBOBB"
    //#ENDIF
    
    can someone help me to master such this in UE please? Do i need to write macros? If yes can someone help me to start with please? Especially how to deal with || (if this is not supported its not big deal too for now)

    2362
    MasterMaster
    2362

      Oct 05, 2012#2

      My personal opinion...

      Tying the "preprocessing" to UE, in my opinion, is not wise, if this is a language that will ever be used by very many people. You should write a separate program from the compiler to do the preprocessing, which the compiler should call before it compiles. It should make one pass for the preprocessing, then a normal pass.

      Yes, I suppose it can be done with a script using UE's scripting engine, but it would be slower, and not as efficient. If this is a compilable language, people are going to look for efficiency and portability. Requiring it to be done via UE script, while it is feasible, would cause it to fail on both counts.

      If this is just a tinkering language that you use for your own purposes that will never be used by anyone else, then putting it into a script would be just fine. However, a full preprocessor would have to be programmed using UE's JavaScript, and it would be just as easy to do it in C++ (or C#, or Object Pascal, or any number of other languages) and compile it into a "user tool" that can be invoked with an UltraEdit hotkey.

      6,675585
      Grand MasterGrand Master
      6,675585

        Oct 07, 2012#3

        Well, while I agree with rhapdog in general. But there are cases where it makes sense to use UltraEdit as preprocessor using macros or scripts.

        In our company there is such a case. There is a file format which can be only edited with a text editor like UltraEdit. Files with this format are interpreted by an application which produces a binary file from the ASCII file. For some reasons I do not want to explain here it makes sense in once case to have the information of several of those ASCII files in a single file for development while in other cases there are always separate files.

        On releasing a new version, the version string must be edited in this "common" file with UltraEdit and then UltraEdit macros are used to create copies of this common file with different file names containing different blocks from the common file depending on output file and also some other modifications are done depending on output file.

        In this case it was much easier to create a set of UltraEdit macros and a master macro to produce the other ASCII files from the common ASCII file then coding this in the application which interprets the ASCII files and produces the binary files. It is also much easier to handle the ASCII files with the UltraEdit macro set. And we have to archive the produced ASCII files while the common ASCII file must not be archived. Rewriting the application which reads in the ASCII files and outputs the binary files to make additionally this preprocessing and produce additionally also the ASCII files to archive would be definitely much more difficult to code and handle.

        To taskin:

        It is surely no problem to code a macro or perhaps better a script to preprocess the file. Here is a script example for your requirements according to what you have written. On execution from script list it asks you which blocks should become active according to a keyword. For more details read the comments of the script.

        Code: Select all

        if (UltraEdit.document.length > 0) {   // Is any file currently opened?
        
           var sDefine = UltraEdit.getString("Enter the preprocessor definition keyword:",1);
           if (sDefine.length) {
        
              UltraEdit.insertMode();          // Define environment for the script.
              UltraEdit.columnModeOff();
              UltraEdit.activeDocument.hexOff();
              UltraEdit.activeDocument.top();
        
              // Define the parameters for a Perl regular expression search to
              // find lines between a line with //#IFDEF and a line with //#ENDIF.
              UltraEdit.activeDocument.findReplace.mode=0;
              UltraEdit.activeDocument.findReplace.matchCase=true;
              UltraEdit.activeDocument.findReplace.matchWord=false;
              UltraEdit.activeDocument.findReplace.regExp=true;
              UltraEdit.activeDocument.findReplace.searchDown=true;
              if (typeof(UltraEdit.activeDocument.findReplace.searchInColumn) == "boolean") {
                 UltraEdit.activeDocument.findReplace.searchInColumn=false;
              }
              UltraEdit.perlReOn();
        
              // Run a case sensitive Perl regular expression Find to find and select
              // blocks with lines between a line starting with //#IFDEF and a line
              // starting with //#ENDIF.
              while (UltraEdit.activeDocument.findReplace.find("//#IFDEF.*\\r\\n(?:.*\\r\\n)+//#ENDIF")) {
        
                 // Get the selected block into an array of strings
                 var sBlockLines = UltraEdit.activeDocument.selection.split("\r\n");
        
                 var bModified = false;
                 // Check if entered keyword is present in first line of the block.
                 if (sBlockLines[0].indexOf(sDefine) < 0) {
                    // The keyword is not present in first line with //#IFDEF.
                    // Comment all lines of this block if not already commented.
                    for (var nLine = 1; nLine < (sBlockLines.length-1); nLine++) {
                       // Starts the line already with // ?
                       if (sBlockLines[nLine].indexOf("//") != 0) {
                          sBlockLines[nLine] = "//" + sBlockLines[nLine];
                          bModified = true;
                       }
                    }
                 } else {
                    // The keyword is present in first line with //#IFDEF.
                    // Uncomment all lines of this block if currently commented.
                    for (var nLine = 1; nLine < (sBlockLines.length-1); nLine++) {
                       // Starts the line already with // ?
                       if (sBlockLines[nLine].indexOf("//") == 0) {
                          sBlockLines[nLine] = sBlockLines[nLine].substr(2);
                          bModified = true;
                       }
                    }
                 }
                 // If no modification of this block is necessary, just cancel the
                 // current selection. Otherwise join the lines in the string array
                 // back to a block string and write the modified block over the
                 // still selected block in active file.
                 if (!bModified) UltraEdit.activeDocument.cancelSelect();
                 else UltraEdit.activeDocument.write(sBlockLines.join("\r\n"));
              }
              UltraEdit.activeDocument.top();
           }
        }