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]

  • Where in drawSunRise do you see a new array being created

    orbXY = [] as Array<Float>;

    How else could the values being calculated by polar be getting into orbXY if not being put there in that function

    As its written, they couldn't. I said you could rewrite it to use a local orbXY, and if you did that you would pass the local to polar.

    Actually I do need the class variable orbXY

    Perhaps you do; but nothing you've shown us so far requires that. Also nothing you've shown us demonstrates that arrays are copied on assignment - quite the opposite in fact.

  • Experimenting with weak references, I got this working

    Again, you're not providing enough context to really understand what your requirements are. But the use of weak references here seems (from what you've told us so far) to be completely pointless.

    Why not just pass the array itself, rather than wrapping it in a weak ref, passing that, and unwrapping it?

    You're probably going to say "because I need it to be passed by reference". But as you've been told multiple times already, Arrays are passed by reference. The code you just posted would work exactly the same without the weak references (of course, you may have *other* code that depends on having weak references - but if so, why are you showing us *this* code)

  • orbXY = [] as Array<Float>;

    This is an array defined in the class. This statement sets the class variable to a null array. Per the memory viewer, the object number NEVER changes, but it's value updates whenever it's called. If what you say is true, that b = a and c = a are both references and not copies, then why are b and c different, and why does changing a not affect b and c?

  • This is an array defined in the class

    I'm not really sure what you're trying to say there. This is an assignment expression. It assigns the thing on the right to the thing on the left. Yes, the thing on the left is a member variable belonging to the class - but what's your point?

    This statement sets the class variable to a null array

    No. The expression on the right creates a new array, which is then assigned to the variable orbXY.

  • b = a and c = a are both references and not copies, then why are b and c different

    because, in the code you showed us you did:

    a = [];

    // fill-a-with-stuff

    b = a;

    a = [];

    // fill-a-with-stuff

    c = a;

    why does changing a not affect b and c?

    Well, clearly changing the contents of a doesn't affect b because they're different objects (a new array was assigned to a right after a was assigned to b). At this point changing the contents of a will change the contents of c - because they are literally the same object.

    if you mean why does assigning a new value to a not affect b and c its because even after "b=a;c=a;" a, b and c all refer to the same array; but they're not references to each other. They each contain a reference to the same object. But if you assign to any of a, b and c it will only affect the one you assigned to.

    eg

    var a = [1,2,3];

    var b = a;

    var c = a;

    c[1] = 42; // now a[1] == 42 and b[1] == 42 too

    c = [4,5,6]; // a and b are still [1,42,3], a == b, but c != a and c != b

    Does that make it clearer?

  • v2.0.86 is out:

    - Include ConditionalExpression and LogicalExpression in evaluateFunction
    - Fix personality search path
    - Use fully qualified names for enum typedefs
    - Fix auto-inlining of protected functions
  • WARNING: release.jungle:6: Personality path '/Users/me/garmin/Foo/lang/heb/bin/optimized/../../../../../../../Library/ApplicationSupport/Garmin/ConnectIQ/Devices/fr255' cannot be resolved to a valid path.

    For some reason the space is missing in: "Application Support"

    line 6 is:

    fr255.personality = ../../../../../../../Library/Application Support/Garmin/ConnectIQ/Devices/fr255
    So I guess you'll need to add quotes, at least when there's a space in there

    I'll add that this doesn't happen when I do a "regular" build in /Users/me/garmin/Foo/, only when I build in /Users/me/garmin/Foo/lang/heb/ which is a generated directory with a generated monkey.jungle and manifest.xml, however it does work without the optimizer, so there's no reason it shouldn't work with it as well.

    Line 6 looks line this in the "regular" build:
    fr255.personality = ../../resources

    So it is possible there are 2 bugs: 1. non-escaped space, and 2. I wonder why the ../../personality was replaced by the default device folder in the "generated" build. BTW my original monkey.jungle doesn't include the word personality in neither build. (Well it does, but only as an excludeAnnotation).
    Update: actually there's an even bigger bug: when I Run optimized version of the "generated" version on non system7 devices (both simulator and real fenix6, both sdk 6.4.2, 7.1.1) then I get now strange errors:
    this is the optimized code (looks good to me):
    using Rez;
    using Toybox.Time;
    using Toybox.Math;
    import Toybox.Application;
    import Toybox.Lang;
    import Toybox.WatchUi;
    
    (:no_test)
    class MyApp extends Application.AppBase {
      hidden var myModel as MyModel?;
    
      function initialize() {
        AppBase.initialize();
        Math.srand(Time.now().value());
      }
    
      function onStart(state as Dictionary?) as Void {
        self.myModel = new MyModel();
      }
    
    //...
    }
    
    Error: Symbol Not Found Error
    Details: Could not find symbol 'myModel'
    Stack:
      - onStart() at /Users/me/MyApp/lang/hun/bin/optimized/group001-debug/source/__dotdot__/source/MyApp.mc:18 0x10000f9a
  • What's not clear is when at the beginning a = c, then I say c = []; a has the old values of c which is what I want, but according to Garmin the values of c were being copied to a before c is set to []. This seems to be reflected in what they said they changed in CIQ 5 about the bulk copy and what I see in the code being 6k smaller. Why it needed to be copied isn't clear when I wonder why they couldn't just repoint the old array. Regardless, I think for our purposes what would be helpful is if it is possible to identifiy those statements where this is happening so maybe we could rewrite it in a way that doesn't incur this penalty?

  • What's not clear is when at the beginning a = c, then I say c = []; a has the old values of c which is what I want, but according to Garmin the values of c were being copied to a before c is set to [].

    Where did they say that? Why do you not believe 3 separate people who are telling you this is not the case? Why haven’t you been able to demonstrate your case with some code which behaves the way you say it does?

    Simple example of what you said.

    var c = [4, 5, 6]; // 1) create an array [4, 5, 6] (let’s call it array X). 2) make c point to X
    var a = c; // 3) make a point to X
    var c = [ ]; // 4) create an empty array [ ] (call it array Y). 5) make c point to Y

    After this code is run, a points to X / [4, 5, 6] and c points to Y / [ ]. No copying involved. Note that in a sense, a and c are not arrays, they only ever point to arrays. Some goes for any variable that receives an assignment to a non-primitive object. 

    Run the following code and tell us what it prints, please. Try an older SDK where you think arrays are being copied on assignment, and a newer SDK where you think arrays are no longer being copied.

    var a = [1, 2, 3];
    var b = a; 
    b[0] = 42;
    System.println(a);
    System.println(b);

    If the same thing is printed twice in both cases, please explain how that lines up with what you said above.

    If there’s any optimization involving “bulk copy” of arrays, it has to be related to array initialization/construction. One optimization I saw in the release notes was that constant arrays were moved into the data section, which sounds like a big win to me. Previously, constant arrays would take up space in the code section iirc.

    This seems to be reflected in what they said they changed in CIQ 5 about the bulk copy and what I see in the code being 6k smaller. Why it needed to be copied isn't clear when I wonder why they couldn't just repoint the old array.

    Why would your code be 6k smaller just because arrays were (allegedly) being copied on every assignment and that’s now no longer the case? You think that the size of the code for a copy operation is proportional to the size of the data being copied or something? If you were to write a simple for loop to copy an array of data, would the amount of code vary based on how many elements you had to copy? Otoh, if you could write fixed-size code that would copy an array of any size, wouldn’t you just make that a function which could be reused over and over again without wasting a ton of code? Even if Garmin *were* copying arrays on assignment (they weren’t), wouldn’t they just do something like that?

  • Why would your code be 6k smaller just because arrays were (allegedly) being copied on every assignment and that’s now no longer the case?

    Fenix 7X watch app using SDK 6.4.2:

    Same app, SDK 7.1.1 (changing 4 lines to work with 7+ syntax):

    I've made a few changes since I said 6K, now it's 7k. I went with what Garmin said they changed. Whatever they changed to make CIQ 5 much smaller while CIQ 4 and below are still the same size is seems significant. What op codes did they implement that aren't copying that would make such a difference?