npm package: @markw65/monkeyc-optimizer
Description: Source to source optimizer for Garmin Monkey C code
Author: markw65
Latest version: 1.1.97

# monkeyc-optimizer README

This package provides a set of utilities for working with Garmin Monkey-C projects.

#### Optimization and analysis

Its primary purpose is to serve as the optimization and analysis engine behind [prettier-extension-monkeyc](https://marketplace.visualstudio.com/items?itemName=markw65.prettier-extension-monkeyc), but it's [API](#api) can also be used to optimize code directly.

#### Font analysis

It also provides a tool to report information about the builtin fonts on a device. This can be used to compute layouts, or make decisions about whether a given string would fit in a given screen region at build time, rather than at runtime. [More details](https://github.com/markw65/monkeyc-optimizer/wiki/Garmin-Font-Analyzer)

## Release Notes

See [Change Log](CHANGELOG.md)

## API

First you will need to [install nodejs/npm](https://nodejs.org/en/download). Note that you need node 16.17.1 or later, preferably 18.20.3 or later

Then you can install the package. From the directory where you want to use it:

```sh
npm install -D @markw65/monkeyc-optimizer
```

Then you need some javascript (or typescript) to invoke it. Here's a sample

```js
import { buildOptimizedProject, getConfig } from "@markw65/monkeyc-optimizer";
import { optimizeProgram } from "@markw65/monkeyc-optimizer/sdk-util.js";
import * as path from "node:path";

const cwd = process.cwd();
const jungleFiles = path.resolve(cwd, process.argv[2]);
const workspace = path.dirname(jungleFiles);

getConfig({
  // These are largely the same options that can be passed to tasks in
  // @markw65/prettier-extension-monkeyc (see the descriptions there)
  // getConfig will read a number of options (such as developerKeyPath)
  // from the vscode user settings, and the project settings, but anything
  // passed in here will override those values.
  //
  // The root that output paths are relative to
  // Defaults to the current directory
  workspace,
  // Where to put the files built by MonkeyC.
  // Defaults to bin. Relative paths are relative to workspace
  buildDir: "bin",
  // Where to put the files generated by the source-to-source optimizer
  // Defaults to `${buildDir}/optimized`. Relative paths are relative to workspace
  outputPath: "bin/optimized",
  // Semi-colon separated list of jungle files
  jungleFiles,
  // If true, don't actually run the MonkeyC compiler, just return the
  // command to do so.
  returnCommand: false,
}).then((options) =>
  // Passing null instead of a device id will build an .iq file
  buildOptimizedProject("fr955", options)
    .then((result) => {
      // The return value includes:
      //
      // exe - the executable to run to build the generated code ('java')
      // args - the arguments to pass to exe
      // diagnostics - collection of diagnostics raised by monkeyc-optimizer
      // program - the program that was generated by monkeyc (or that would
      //           be generated, if returnCommand is true)
      // product - the device that was targeted.
      // hasTests - true if any functions marked by (:test) were found

      // If you passed `returnCommand: true` above, you would want
      // to execute (exe, args) here
      console.log(`Built: ${result.program}`);
      return result;
    })
    .then((result) =>
      optimizeProgram(
        // program to optimize
        result.program,
        options.developerKeyPath,
        // output program. default will insert ".opt" before the input's extension
        // so foo.prg => foo.opt.prg, and foo.iq => foo.opt.iq
        undefined,
        // A few of the BuildConfig options apply to the post build optimizer
        options
      )
    )
    .then(({ output }) => console.log(`Optimized: ${output}`))
);
```

If you save the above as `optimize.mjs`, you can then optimize a project via:

```
node optimize.mjs path-to-my-project-monkey.jungle
```