This package provides a set of utilities for working with Garmin Monkey-C projects.
Its primary purpose is to serve as the optimization and analysis engine behind prettier-extension-monkeyc, but it's API can also be used to optimize code directly.
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
See Change Log
First you will need to install nodejs/npm. 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:
npm install -D @markw65/monkeyc-optimizer
Then you need some javascript (or typescript) to invoke it. Here's a sample
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