@flybywiresim/rnp

RNP is a language which compiles to RPN, a scripting language used by MSFS.

Usage no npm install needed!

<script type="module">
  import flybywiresimRnp from 'https://cdn.skypack.dev/@flybywiresim/rnp';
</script>

README

RNP

RNP is a language which compiles to RPN, a scripting language used by MSFS.

RNP provides a familiar and expressive environment with strict types. In the future it may also perform optimization.

API

const { Type, translate } = require('@flybywiresim/rnp');

// function to resolve imports
function getSource(
  referrer,  // specifier of importing module
  specifier, // specifier of module to be imported
) {
  // return `null` if module can't be resolved.
  return {
    source,    // source of imported module
    specifier, // resolved specifier, e.g. `dirname(referrer).join(specifier)`
  };
}

const {
  output,    // string RPN output
  messages,  // [{ level, message, location }]
} = translate(source, {
  specifier,   // defaults to '(anonymous)'
  returnType,  // defaults to `Type.VOID`
  getSource,   // defaults to resolution error
});

Types

  • boolean - true or false.
  • number - IEEE-754 double precision floating point number.
  • string - A string type.
  • any - Used for unknown types. No builtin in the language allows this type, but some expressions may be valid with it, for example (L:X) = (L:Y).
  • void - The absence of a value. An example of an expression which produces void is if true {}.

Syntax

Comments

Line Comments

Comment out a single line.

// this is a line comment

Block Comments

Comment out multiple lines. Nesting is allowed.

/* this
comment
is
longer
*/
/*

/*
comment doesn't end here
*/

comment ends here
*/

Declarations

Locals

Declare a local.

let a = 1;

Aliases

SimVars can be aliased to local names.

alias x = (L:X, bool);

x = true; // set L:X to true
if x {    // if L:X is true
}

Macros

Declare a macro. Macros may be exported using export. Macros are "hygienic", meaning that identifiers may not be implicitly leaked into or out of a macro scope. Macros parameters use $ to avoid being confused with normal variables.

macro add($a, $b) {
  $a + $b
}
export macro sub($a, $b) {
  $a - $b
}
macro assign($a) {
  $a = 1;
}

let b = 0;
// does not break hygiene rules because `b` was explicitly passed
assign(b);

Imports

Macros can be imported from other files using import.

import { sub } from './file.rnp';

Assignments

Locals

Assign a value to a local.

a = 1;

SimVars

Assign a value to a SimVar.

(X:Y) = 1;
(X:Y, unit) = 1;

Expressions

Literals

// booleans
true;
false;

// numbers
1.0;
0x10;
0b101010;

// strings
'hello';

Locals

Reference a local.

a

SimVars

Reference a SimVar.

(X:Y)
(X:Y, unit)

Inserts

Allows XML substitutions. Expressions must be typed.

let x = #X, bool#;
#Y#;

Macro Expansion

Expand a macro.

add(1, 2);

Blocks

{
  1
}

If Expressions

Conditional evaluation, may be used as an expression.

if x {
}
if x {
} else {
}
if x {
} else if y {
} else {
}
let a = if x { 1 } else { 2 };

Binary and Unary Operators

Mathematical and relational operations.

1 + 1;
1 / 1;
'hello' == 'hello';
// etc...

!true
~1
// etc...

Method Operations

RPN provides several standard operations. These operations are available in RNP as method-ish syntax.

8.log(2);
'hello'.toUpperCase();