Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

"Local" libraries

2011-05-05
2013-04-25
  • Since java code inlining is not supported (with no serious reason to expect that to ever happen), and I often happen to write small Lib's for that one project (normally featuring a dynamic array of image processor). Since all of these have to go into MP\Libs, the folder becomes pretty flooded over time.
    So what I'm asking for, could compiler be updated search for libraries in '/classes' or '/src' folders of current project directory? (maybe with possible 'overriding' - so if there is a library in local folder, it would be used instead of Libs\ version). While this should take a small amount of time to implement, this would

    (and one other small thing) sometimes when firing the compiler, 3rd and 4th symbols in one of source code lines (normally somewhere at the start of file) are getting replaced by random junk (normally G-like letters). This is not very frequent, but a bit annoying. What could cause this?

     
  • 1) What do you mean by "java code inlining"? The compiler supports java bytecode inlining, in a jasmin-like fashion, may be you are referring to it, if so, remember to use the compiler magic inline() procedure. And btw, do not hesitate to ask why I do this or that, I have serious reasons for everything :)

    2) I have an item in my TODO list since a lot of time: to add a local Libs directory in the project structure. It is useful in many ways. Never coded it since there were always other features more important, but now that you ask for something like that, I will raise it's priority. If you are lucky you may see it in MP 3.4.
    SPECIAL NOTE: In any case, I would like to explain a little more this kind of tasks so everybody reading this gets noticed about the procedure. It is not that easy, look: to achieve that behaviour, I have to modify the compiler way it look for external libraries (the simpler part: add a new variables, add the related logic, etc), add a command line switch to handle the local Libs directory for the project, modify the IDE too to load the external libraries from the right place (remember the JAR is built by the IDE not the compiler), and many other tasks like that to make it work. After all that, another task takes place: a new menu item "Open Libraries Folder" has to be added to the Project menu so it's reachable easily for your convenience, and that means that the translators will have work too (and that may imply a few weeks, sometimes they don't have the time to translate the strings in the moment). Finally, it is the turn of the community: this kind of changes should be inserted in an ALPHA (or BETA as much) version since they impact in the most important module of the project, and that may take months now (the almost death community of MP has growed a lot, from near 100 downloads in the first versions I have released, now you see 1,200 downloads for the 3.3 ALPHA), since it allows everyone to check the new behaviour is working as they expect (if not, they can report me an error or suggest me a modification). All this shows why I prefer to modify the compiler as little as possible, only in the very needed parts, specially taking account that the MP3 project will be dropped when MP4 (the full pascal implementation) comes to life (whenever that happen).

    3) That small thing you mention is, may be, one of the worst news I could receive as feedback heh, but thanks for reporting it out. It means SynEdit continues to corrupt the displayed data (source code in this case), even with the very last changes I made to it (you can check other threads in this forum for the history of this issue). All this means I will have to replace it with other editor, may be Scintilla just like Jordan made in InnoSetup, and that will take time (it's not a "component switch", it involves customizing Scintilla to fit MP needs, the very same way I did with SynEdit in fact). So, everybody reading this, be aware of that.

    Thanks for your report.

     
  • 1) I mean like

    public static int keystates()
        {
            return M.T.getKeyStates();
        }
    

    I am aware of inline(), but that uses bytecodes, which I am not similar with (yet).

    I've discovered javap -c %1 a few minutes ago, but currently cannot find a way to inline a variable (specifically, a int or Object).
    And I assume that it wished form will not appear any time soon, because it requires javac, which requires JRE, which requires installing (and partially ruins the magic of MP compilation), and will as well require lots of changes to compiler, and so on.

    2) Hmm, did not knew that JAR is 'compiled' by IDE. I may only hope that it will not take a while.

    3) Scintilla sounds like a good choice. Nice, fast, and includes code folding (happiness!). However, I have heard that it causes certain incompatibilities with Wine. Could you check that?

    And one note about things that might have been done wrong. Do you know that "float" type is supported by all phones running MIDP2.0 \ CLDC1.1? That means that it is possible to simply use it in 2.0-type programs instead of MP's (nicely done, but slow) float classes.

     
  • Hello again. I've got to working with inline() a bit, however, I cannot figure out how to add label into inline() block.
    Both "labelname:" (jasmin-style) and ":labelname" (seen in prototype examples from boolean.name community) give compiler error "<inline>')' expected, '' found" or crash the compiler. What is the right syntax?
    Passing parameters into 'invokevirtual' seems impossible as well.
    Without these, use of inline is limited to… adding values and returning value from function? That's not very fun.
    Could you provide some information or code examples on this?

     
  • An example to invokevirtual:

    program TestInline;
    var x: integer;
    begin
      inline(
        getstatic   field   'M', 'I', 'Ljavax/microedition/lcdui/Image;';
        invokevirtual   method  'javax/microedition/lcdui/Image', 'getWidth', '()I';
        putstatic   field   'M','x','I'
      );
      DrawText(IntegerToString(x),0,0);
      Repaint;
      Delay(2000);
    end.
    

    About the labels currently they are not supported. Why? Well, it's a large story, but basically when I started coding in the project, Artem was working on a separated fashion (don't know why) for about a month before that. In short, and not to drop his work, I based the MPC 3.0 compiler on his 009 version, but he continued releasing without any kind of communication with me. In that 009 version, the inline() support did not included labels. He supported labels, and other stuff on later versions of his compiler (for example labels are present in the last version I have from him: 011), but it was too late to integrate those changes to my version (I have fixed a big amount of bugs, added my own new features, and stuff), and since the inline() feature is not very used by the community, I never gave priority to try to include those improvements to it. Now you seem to use it, I will take note. In any case the syntax seems not to be very well defined, and it's not documented at all except for some short samples, so I always wondered if it wasn't better to remove it heh. And more, the MPC generated code is fairly efficient if you ask me, so using inline() makes not much sense in this case, it's not like the difference you gain in the native field with well crafted asm. Anyway, I will take note of this and when coding 3.4, if I have time, I'll check how much work it takes to include those improvements in the 011 version to the inline() feature.

     
  • Thanks!
    MP generates fairly efficient code (however, I totally don't get why the <boolean> values are stored and compared as <int>'s), but does not necessarily include all functions from classes that it uses. For example, there is second Graphics.setColor procedure, which takes a single parameter (hex colour, like $FF0000, thanks for including that in MP by the way), which is not accessible from MP itself, but can come handy, because you can store colours in single <integer>'s this way.

    From what I've seen in parser.c source, <inline> functions are stored in a identified code block, starting with 'JAVA - ASM' and ending at 'END JAVA - ASM' comments. So it might be an easy fix, really. Adding to that… maybe you could surround main inline function with try-catch? It crashes compiler quite often, if unexpected argument was found in inline code.

    Currently, found it crashing because of line 'astore_1' in the following code:

    function SwapCanvasImage(img: image): image;
    begin inline(
    getstatic field 'M','I','Ljavax/microedition/lcdui/Image;';
    astore_1;
    putstatic field 'M','I','Ljavax/microedition/lcdui/Image;';
    aload_0;
    invokevirtual method 'javax/microedition/lcdui/Image','getGraphics','()Ljavax/microedition/lcdui/Graphics;';
    putstatic field 'M','G','Ljavax/microedition/lcdui/Graphics;';
    aload_1;
    areturn;
    ); end;
    

    I've re-checked the code and compared to what javac makes - the line must be there, and is valid.

    By the way, from what it seems, 'inline' procedures & functions can be easily added to compiler? (so, MP could be made to support more functions by itself)

     
  • Yeah, I'm aware about the comments marking the block in parser.c but this is not a copy/paste replace hehe. I'm modifying a compiler so before integrating external code to it, I must be sure of what the code does and what's expected. Basically I have to read the code, be sure it works as expected, integrate it in the official release carefully and do all the tests needed to be sure nothing is broken in the middle, and all that takes time. As I told you in the last message, don't worry, I will see if in the 3.4 version I can integrate it. But in any case I repeat, I'm not pretty sure that having an inline() feature is good for MP since a really low amount of programmers use it.

    About the bug you report, yes and in fact, seems all the *store_* opcodes fail, even if entering them as hexadecimal. I'll take note of that.

    About the request of adding more magic compiler functions to MP, as I stated in other forum replies, I do not agree with that. It's not convenient to add too much magic functions to a compiler, it's better to extend the external RTL (as Delphi, FreePascal and other compilers do). The compiler is a translator that should be the smallest, quickest and simplest possible. And, the most important thing in this case, MP3 compiler is just suppossed to be mantained only until a full pascal MP4 got released, so extending it too much is pointless.

    Thanks for your report

     
  • I believe that some functions and procedures could be included into compiler - good examples are array handling functions and DrawTriangle (from forum I know that a lot of people would like that one).
    For sample, here is array resizing implemented.
    Code is rather long to lack of astore and labels, but that's it - dream of far not one user without using any external libs:

    // Temp variables:
    var _ta:array[0..1] of integer; _t:integer;
    // Creates temp array of given size:
    procedure _tm(size: integer);
    begin inline(iload_0; newarray 10; putstatic field 'M','_ta','[I';); end;
    // Array to support resizing:
    var myarray:array[0..1] of integer;
    // Gets array length:
    function myarray_size: integer;
    begin inline(getstatic field 'M','myarray','[I'; arraylength; ireturn;); end;
    // Changes array length:
    procedure myarray_resize(size: integer); begin _tm(size);
    if myarray_size > size then
    for _t := 0 to size-1 do _ta[_t] := myarray[_t];
    else if myarray_size > 0 then
    for _t := 0 to myarray_size-1 do _ta[_t] := myarray[_t];
    inline(getstatic field 'M','_ta','[I';putstatic field 'M','myarray','[I';); end;
    

    I'm really looking forward the update with working labels, or at least astore - then it will be possible to replace Pascal for-loop with java.lang.System.arraycopy, and get rid of additional functions :)
    Talking of this… you could add special 'inline'\'bytecode' keyword, that could be placed before function names, and would indicate that one will contain only bytecodes, thus does not need 'result' variable to be defined and ireturn\areturn'ed.