Data Types

The available data types in mJS are similar to those in JavaScript, with some small differences. The following data types are supported:

  • Boolean: true or false. Example: let b = true;

  • Number: 64-bit floating point number. Example: let n = 3.14;

  • String: A sequence of characters. Example: let s = "Hello";

  • Object: A collection of unordered key-value pairs. Example: let obj = {key1: "value1", key2: 2};

  • Array: An ordered list of values. Example: let arr = [1, 2, 3];

  • Function: A block of code that can be called. Example: let f = function() { return 1; };

  • Undefined: A special value representing an uninitialized variable. Example: let u;

  • Null: A special value meaning “no value”. Example: let n = null;

To check the data type of a variable, use the typeof operator. Example: typeof 3.14 returns "number".

To check is a variable is defined, use the isdef() function. Example: isdef(n) returns false if n is undefined or null.

Numbers can also hold the special value NaN (Not a Number). See the section on Numbers for more details.

Implicit type conversions from one type to another are not allowed. For example, the following code will throw an error: let n = 3.14 + "2";
Instead, explicitly convert types. Example: let n = 3.14 + JSON.parse("2");

Strings

Strings are sequences of characters enclosed in single or double quotes. They can contain letters, numbers, symbols, and whitespace.

To create a string, use the following syntax:

let s = "Hello, world!";

Concatenate (join) strings using the + operator:

let s1 = "Hello, ";
let s2 = "world!";
let s = s1 + s2; // "Hello, world!"

Access individual characters in a string using square brackets:

let s = "Hello";
let firstChar = s[0]; // 'H'
let secondChar = s[1]; // 'e'

Use the length property to get the number of characters in a string:

let s = "Hello, world!";
let length = s.length; // 13

Use escape sequences to include special characters in a string such as:

  • a newline character: \n

  • a tab character: \t

  • a backslash: \\

  • a double quote: \"

  • or any raw byte value in hexadecimal: \xHH (where HH is the hexadecimal value of the character)

let s = "Hello,\nworld! This is a string with a tab:\tand a backslash: \\ and a double quote: \" and a raw byte: \x41";

Numbers

Numbers in mJS are 64-bit floating point numbers. This means that they can represent integers and floating point numbers. The following are examples of numbers:

let n;
n = 3.14;
n = 42;
n = 1.0e-6;
n = 1.0e6;
n = 0x10; // Hexadecimal format (16 in decimal)

If a number cannot be represented it will hold the value NaN (Not a Number). This can happen in cases such as division by zero, invalid mathematical operations or an error.

If you try and print NaN you will get 9223372036854775807.

To check if a number is NaN, use the isNaN() function. Example: isNaN(3.14) returns false, while isNaN(53/0) returns true (divide by zero error).

Please note that unlike regular JavaScript Infinity is not supported in mJS.

Objects

Objects are collections of key-value pairs. The key is a string, and the value can be any data type. To create an object, use the following syntax:

let data_object = {
  '0': 'This is a string',
  'two': 8.7820,
  '3': true,
  'four': [5, 7, 'string value'],
  '5': { 'a': 'Nested object' },
  'times6': function(x) { return x * 6; },
  '7': null,
  '8': NaN
};

You can access the values in an object using either dot notation or square bracket notation. Continuing with the example above, you can access the values like this:

data_object[0]          // Returns string: 'This is a string'

data_object.two         // Returns number: 8.7820

data_object[3]          // Returns boolean: true

data_object['four'][1]  // Returns number: 7

data_object[5].a        // Returns string 'Nested object'

data_object.times6(5)   // Returns number: 30

let key_test = '7';     // The key can also be a variable
data_object[key_test]   // Returns null

data_object['8']        // Returns a special number that means 'Not a Number'

isNaN(data_object[8])   // Returns boolean: true

Note that dot notation can only be used with keys that are valid JavaScript identifiers (e.g., no spaces, special characters, or starting with a number). For keys that do not meet these criteria, use square bracket notation.

Arrays

Arrays are ordered lists of values. They can contain any data type, including other arrays and objects. To create an array, use the following syntax:

let data_array = [1, 2, 'three', true, { 'key': 'value' }, [6, 7]];

You can access the values in an array using square brackets and the index of the value. The index starts at 0. For example, to access the different values in the array:

data_array[0]     // Returns number: 1
data_array[2]     // Returns string: 'three'
data_array[3]     // Returns boolean: true
data_array[4].key // Returns string: 'value'
data_array[5][1]  // Returns number: 7

Parsing Data

Once of the most confusing topics is parsing data from one format to another. This is especially true when dealing with binary data, or when converting between different number formats. The SQ.parse() function provides a way to help with this task.

Data can often arrive from sensors as a string that needs to be interpreted as a number. The data string could be in raw binary, hexadecimal, or decimal format. The SQ.parse() function can help you convert between these formats.

Examples of data formats in strings:

  • Raw Data: A string containing raw binary data. Example string with 4 bytes of information: "\xE0\x7F\xF6\xCE"

  • Hexadecimal: A string containing hexadecimal numbers. Example string with 4 bytes of information, 8 characters: "E07FF6CE"

  • Decimal: A string containing decimal numbers. Example: "-37.235"

Parsing Hexadecimal Strings

For parsing hexadecimal strings, we specify the starting position, number of characters to parse from the string, base (16 for hexadecimal), and the output data type.

let str = '05000000';

// In: '0'
SQ.parse(str, 0, 1, 16);
// Out: 0

// In: '05'
SQ.parse(str, 0, 2, 16);
// Out: 5

// In: '05000000'
SQ.parse(str, 0, 8, 16);
// Out: 83886080

// In: '00000005'
SQ.parse(str, 0, 8, -16);
// Out: 5

// In: '05000000'
SQ.parse(str, 0, 8, 16, SQ.FLOAT);
// Out: 0.00000 (6.01e-36)

// In: '00000005'
SQ.parse(str, 0, 8, -16, SQ.FLOAT);
// Out: 0.00000 (1.12e-43)

Parsing Raw Data Strings

For parsing raw data strings, we specify the starting position, number of characters to parse from the string, base (0 for raw bytes), and the output data type.

// String containting raw data
// In HEX this string would be: '41 4A 52 F7 47 FF'
let str = 'A\x4a\x52\xf7\x47\xff';

// In: '\xF7' (4th byte)
SQ.parse(str, 3, 1, 0, SQ.U8);
// Out: 247

// In: '\xF7'
SQ.parse(str, 3, 1, 0, SQ.S8);
// Out: -9

// In: '\xf7\x47' (4th and 5th bytes)
SQ.parse(str, 3, 2, 0, SQ.U16);
// Out: 63303

// In: '\xf7\x47'
SQ.parse(str, 3, 2, 0, SQ.S16);
// Out: -2233

// In: '\x4a\x52\xf7\x47' (2nd to 5th bytes)
SQ.parse(str, 1, 4, 0, SQ.U32);
// Out: 1246951239

// In: '\x4a\x52\xf7\x47'
SQ.parse(str, 1, 4, 0, SQ.FLOAT);
// Out: 3456465.75

// In: '\x47\xF7\x52\x4A' (5th to 2nd bytes, reversed)
SQ.parse(str, 1, 4, 0, -SQ.FLOAT);
// Out: 126628.578125

Parsing Decimal Strings

For parsing decimal strings into numbers we specify the starting position, number of characters to parse from the string, base (10 for decimal), and optionally the output data type.

let str = '05000000';

// In: '05' (first two characters)
SQ.parse(str, 0, 2, 10);
// Out: 5

// In: '05000000' (first 8 characters)
SQ.parse(str, 0, 8, 10);
// Out: 5000000

str = "015.73235";

// In: '015.73235' (first 9 characters)
SQ.parse(str, 0, 9, 10);
// Out: 15 (defaults to integer)

// In: '015.73235'
SQ.parse(str, 0, 9, 10, SQ.FLOAT);
// Out: 15.73235

str = "-8723.14586";
SQ.parse(str, 0, 8, 10, SQ.FLOAT);
// Out: -8723.14

Alternatively for parsing decimal strings into numbers, you can use the JSON.parse() function. Example: let n = JSON.parse("3.14");