Skip to main content

DeviceScript Language

DeviceScript generally works just like TypeScript, unless the compiler tells you something is not supported.

The TypeScript sources are compiled to a bytecode that is then executed on the DeviceScript runtime.

TypeScript subset

DeviceScript is a subset of TypeScript. TypeScript itself follows semantics of ECMAScript also known as JavaScript (JS). DeviceScript generally also follows JavaScript semantics, and the DeviceScript compiler will give you an error if you're using an unsupported feature.

Otherwise, there are some semantic differences stemming from the limited resources available to the DeviceScript runtime:

Below we list supported and unsupported language features.

Supported language features

  • variable declarations with let, const
  • functions with lexical scoping and recursion
  • top-level code in the file; hello world really is console.log("Hello world")
  • if ... else if ... else statements
  • while and do ... while loops
  • for(;;) loops
  • for ... of statements
  • for ... in statements (though they behave the same as for ... of Object.keys(...))
  • break/continue; also with labeled loops
  • switch statement (on numbers, strings, and arbitrary types - the last one isn't very useful)
  • debugger statement for breakpoints
  • conditional operator ? :; lazy boolean operators
  • all arithmetic operators (including bitwise operators)
  • strings (with a few common methods)
  • string templates (`x is ${x}`)
  • arrow functions () => ...; passing functions as values
  • classes with inheritance, instance fields, methods and constructors; new keyword
  • public/private annotations on constructor arguments (syntactic sugar to make them into fields); initializers for class fields
  • enumerations (enum)
  • generic classes, methods, and functions
  • typeof expression
  • binding with arrays or objects: let [a, b] = ...; let { x, y } = ...
  • exceptions (throw, try ... catch, try ... finally)
  • union or intersection types
  • delete statement
  • array literals [1, 2, 3], [1, ...x, ...y, 2]
  • object literals { foo: 1, bar: "two" }
  • shorthand properties ({a, b: 1} parsed as {a: a, b: 1})
  • computed property names ({[foo()]: 1, bar: 2})
  • spread and rest operators (in certain places)
  • file-based modules (import * from ..., import { foo } from ... etc)
  • array/object destructuring in parameters and definitions (not in assignments yet)
  • optional chaining (a?.b.c, foo.bar?.(), foo?.[1], etc)
  • nullish coalescing operator (width ?? 240)
  • static fields and methods in classes
  • JSX is supported (though experimental) if you feel like developing an MCU-React!

Unsupported language features

Things you may miss and we may implement:

  • support of enums as run-time arrays
  • initializer for static fields
  • method-like properties (get/set accessors)
  • tagged templates tag `text ${expression} more text` are limited to special compiler features like buffer literals; regular templates are supported

Things that we are not very likely to implement due to the scope of the project or other constraints (note that if you don't know what a given feature is, you're unlikely to miss it):

  • yield expression and function*
  • with statement
  • eval
  • namespaces (we do support ES modules)
  • arguments keyword; .apply method (modern spread operator is supported)
  • marking properties as non-enumerable etc
  • == and != operators (other than == null/undefined); please use === and !==