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:
- programs run in multiple fibers;
async
/await
are supported generalPromise
is not - user-defined .toString() method is limited
- strings are Unicode, not UTF-16, and some features are missing
- some objects, including functions, are static or otherwise special, and cannot have random properties attached
- tree shaking is quite aggressive
- hex string template compiles hex string into flash-stored buffers
- other differences include lack of subnormals
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
statementswhile
anddo ... while
loopsfor(;;)
loopsfor ... of
statementsfor ... in
statements (though they behave the same asfor ... of Object.keys(...)
)break/continue
; also with labeled loopsswitch
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
orintersection
typesdelete
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 andfunction*
with
statementeval
- 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!==