Big update to prettier-extension-monkeyc

I've posted about prettier-extension-monkeyc before, but I've added a bunch of new features that developers will probably like (well, I've been missing them, so maybe you have too).

The new features it implements for VSCode include:

  • Goto Definition. Point at a symbol, Ctrl/Cmd click, and it will take you to the definition. Or F12
  • Goto References. Right click on a symbol and select "Goto References". It will show you all the references. Or Shift-F12
  • Peek Definition/Peek References. Same as above, but in a popup window so you don't lose your place in the original document.
  • Rename Symbol. Right click on a local, function, class or module name, and select "Rename Symbol". It will rename all the references. It doesn't yet work for class members/methods.
  • Goto Symbol. Type Ctrl/Cmd-Shift-O and pick a symbol from the drop down (which has a hierarchical view of all symbols in the current file). This also appears as an outline across the top of the file.
  • Open Symbol By Name. Type Ctrl/Cmd-T, then start typing letters from a symbol name. A drop down will be populated with all matching symbols from anywhere in your project.

Older features include a prettier based formatter for monkeyc, and a monkeyc optimizer that will build/run/export an optimized version of your project.

[edit: My last couple of replies seem to have just disappeared, and the whole conversation seems to be in a jumbled order, so tldr: there's a new test-release at https://github.com/markw65/prettier-extension-monkeyc/releases/tag/v2.0.9 which seems to work for me on linux. I'll do more verification tomorrow, and push a proper update to the vscode store once I'm sure everything is working]

  • v2.0.85 is out

    Fixes an issue introduced by v2.0.84 that could cause incorrect warnings.

    Fixes an issue with the post build optimizer operating on .prg files for System7 devices that could result in broken binaries

  • I just hit this one myself. I think it was a temporary state while I was typing which caused an unexpected exception from somewhere, which then left the extension in a bad state.

    I'm going to try to add better debugging and figure out what happened; but "Developer Reload Window" should fix it if it happens again.

  • I have this "macro":

    (:inline)
    function max(a as Number, b as Number) as Number {
        return a > b ? a : b;
    }
    

    I use it in a few places in the code and it works as expected.

    Now I tried something new:

    const A = 3;
    const B = 4;
    const C = max(A, B);

    Without the optimizer this fails unfortunately (though to my surprise in run-time only, not during compilation):

    Error: Circular Dependency Error
    Details: Failed invoking <symbol>
    Stack:
        - max() at Utils.mc:27

    When I tried with the optimizer I was lucky:

    Although there's this warning:
    INFO> fenix6: Utils.mc:27:1: The inline function max was not removed from the program

    but at least it doesn't crash run-time.

    However I wonder why is this warning, and if this is something that could be improved?

    The optimized code is:

    const C = max(3, 4);

    However if I manually inline, then it works (both with and without the optimizer BTW):

    const C = A > B ? A : B;

  • However I wonder why is this warning, and if this is something that could be improved

    Initializers like this get special handling, so it doesn't go through the normal optimization path, and I guess it's not trying to inline. This would count as an "expression" context, so inlining would be fairly limited - but this case should work. I can take a look.

  • Details: Failed invoking <symbol>
    Stack:
        - max() at Utils.mc:27

    Monkey C is a strange language:

    import Toybox.Application;
    import Toybox.System;
    
    class TestApp extends AppBase {
        private static const VALUE_FULL = 4;
        private static const VALUE_HALF = VALUE_FULL / 2;
    
        function initialize() {
            AppBase.initialize();
    
            System.println(VALUE_HALF);
        }
    }
    

    Error: Symbol Not Found Error
    Details: "Could not find symbol '<globals/TestApp/<statics>/<>VALUE_FULL>'"

    The reason is in wrong constants order in MIR:

        [ @file = ".../TessApp.mc"; @line = 4; ]
        static
        <init> {
    [ ".../TessApp.mc" 6 25 ]
            %tmp.2 = getv ? :VALUE_FULL;
            %tmp.3 = 2;
            %tmp.4 = div %tmp.2 %tmp.3;
            putv self :VALUE_HALF %tmp.4;
        }
        [ @file = ".../TessApp.mc"; @line = 5; @position = 25; ]
        private static
        const VALUE_FULL = 4;

    Is it even declared in language specification that const that references another const should work as we expect it?

    Glad we have prettier-extension-monkeyc to inline this stuff.

  • Is this related to prettier optimizer?

    There are bugs related to consts in SDK 7.1.0. I haven't test 7.1.1 yet, but from what Kyle posted to the forum it is supposed to fix them.

  • Is this related to prettier optimizer?

    No, it is a regular build in 6.4.2.

    And even this compiles without error (no prettier-monkeyc involved):

    private static const VALUE_HALF = VALUE_FULL / 2;
    private static const VALUE_FULL = 4;

    I'm just saying that consts that are using consts may not work as we expect them in other languages, and I'm not sure that this way of using them is guaranteed to work in Monkey C by language specs.

  • Actually, it's even simpler. Before I wrote the inliner, I wrote an evaluator that tries to determine if the result of a function (with given arguments) is a literal.

    It first checks for a shortlist of allowed nodes (eg we don't want to allow calls, even if the final result is known - eg `foo() ? 0 : 0` always evaluates to zero, but its not safe to replace that expression with 0). And I didn't include conditional or logical expressions in the list of allowed nodes.

    I'd never noticed because the inliner generally subsumes this kind of thing - but in this case, the inliner doesn't get to run.

    Anyway - 2 line fix :-)

  • I don't know why you have the static. I don't think it makes any sense or difference. I never used it with const. If you remove it then I think it works. Order of lines does matter! But it's oof-topic in this thread :)