AssemblyScript

Личный сайт Go-разработчика из Казани

AssemblyScript compiles a variant of TypeScript (basically JavaScript with types) to WebAssembly using Binaryen. It generates lean and mean WebAssembly modules while being just an npm install away.

This article will focus only on AssemblyScript extra syntax, as opposed to TypeScript and JavaScript.

To test AssemblyScript’s compiler, head to the Playground where you will be able to type code, have auto completion and directly see the emitted WebAssembly.

1// There are many basic types in AssemblyScript, 2let isDone: boolean = false; 3let name: string = "Anders"; 4 5// but integer type come as signed (sized from 8 to 64 bits) 6let lines8: i8 = 42; 7let lines16: i16 = 42; 8let lines32: i32 = 42; 9let lines64: i64 = 42; 10 11// and unsigned (sized from 8 to 64 bits), 12let ulines8: u8 = 42; 13let ulines16: u16 = 42; 14let ulines32: u32 = 42; 15let ulines64: u64 = 42; 16 17// and float has two sizes possible (32/64). 18let rate32: f32 = 1.0 19let rate64: f64 = 1.0 20 21// But you can omit the type annotation if the variables are derived 22// from explicit literals 23let _isDone = false; 24let _lines = 42; 25let _name = "Anders"; 26 27// Use const keyword for constants 28const numLivesForCat = 9; 29numLivesForCat = 1; // Error 30 31// For collections, there are typed arrays and generic arrays 32let list1: i8[] = [1, 2, 3]; 33// Alternatively, using the generic array type 34let list2: Array<i8> = [1, 2, 3]; 35 36// For enumerations: 37enum Color { Red, Green, Blue }; 38let c: Color = Color.Green; 39 40// Functions imported from JavaScript need to be declared as external 41// @ts-ignore decorator 42@external("alert") 43declare function alert(message: string): void; 44 45// and you can also import JS functions in a namespace 46declare namespace window { 47 // @ts-ignore decorator 48 @external("window", "alert") 49 function alert(message: string): void; 50} 51 52// Lastly, "void" is used in the special case of a function returning nothing 53export function bigHorribleAlert(): void { 54 alert("I'm a little annoying box!"); // calling JS function here 55} 56 57// Functions are first class citizens, support the lambda "fat arrow" syntax 58 59// The following are equivalent, the compiler does not offer any type 60// inference for functions yet, and same WebAssembly will be emitted. 61export function f1 (i: i32): i32 { return i * i; } 62// "Fat arrow" syntax 63let f2 = (i: i32): i32 => { return i * i; } 64// "Fat arrow" syntax, braceless means no return keyword needed 65let f3 = (i: i32): i32 => i * i; 66 67// Classes - members are public by default 68export class Point { 69 // Properties 70 x: f64; 71 72 // Constructor - the public/private keywords in this context will generate 73 // the boiler plate code for the property and the initialization in the 74 // constructor. 75 // In this example, "y" will be defined just like "x" is, but with less code 76 // Default values are also supported 77 78 constructor(x: f64, public y: f64 = 0) { 79 this.x = x; 80 } 81 82 // Functions 83 dist(): f64 { return Math.sqrt(this.x * this.x + this.y * this.y); } 84 85 // Static members 86 static origin: Point = new Point(0, 0); 87} 88 89// Classes can be explicitly marked as extending a parent class. 90// Any missing properties will then cause an error at compile-time. 91export class PointPerson extends Point { 92 constructor(x: f64, y: f64, public name: string) { 93 super(x, y); 94 } 95 move(): void {} 96} 97 98let p1 = new Point(10, 20); 99let p2 = new Point(25); //y will be 0 100 101// Inheritance 102export class Point3D extends Point { 103 constructor(x: f64, y: f64, public z: f64 = 0) { 104 super(x, y); // Explicit call to the super class constructor is mandatory 105 } 106 107 // Overwrite 108 dist(): f64 { 109 let d = super.dist(); 110 return Math.sqrt(d * d + this.z * this.z); 111 } 112} 113 114// Namespaces, "." can be used as separator for sub namespaces 115export namespace Geometry { 116 class Square { 117 constructor(public sideLength: f64 = 0) { 118 } 119 area(): f64 { 120 return Math.pow(this.sideLength, 2); 121 } 122 } 123} 124 125let s1 = new Geometry.Square(5); 126 127// Generics 128// AssemblyScript compiles generics to one concrete method or function per set 129// of unique contextual type arguments, also known as [monomorphisation]. 130// Implications are that a module only includes and exports concrete functions 131// for sets of type arguments actually used and that concrete functions can be 132// shortcutted with [static type checks] at compile time, which turned out to 133// be quite useful. 134// Classes 135export class Tuple<T1, T2> { 136 constructor(public item1: T1, public item2: T2) { 137 } 138} 139 140export class Pair<T> { 141 item1: T; 142 item2: T; 143} 144 145// And functions 146export function pairToTuple <T>(p: Pair<T>): Tuple<T, T> { 147 return new Tuple(p.item1, p.item2); 148}; 149 150let tuple = pairToTuple<string>({ item1: "hello", item2: "world" }); 151 152// Including references to a TypeScript-only definition file: 153/// <reference path="jquery.d.ts" /> 154 155// Template Strings (strings that use backticks) 156// String Interpolation with Template Strings 157let name = 'Tyrone'; 158let greeting = `Hi ${name}, how are you?` 159// Multiline Strings with Template Strings 160let multiline = `This is an example 161of a multiline string`; 162 163let numbers: Array<i8> = [0, 1, 2, 3, 4]; 164let moreNumbers: Array<i8> = numbers; 165moreNumbers[5] = 5; // Error, elements are read-only 166moreNumbers.push(5); // Error, no push method (because it mutates array) 167moreNumbers.length = 3; // Error, length is read-only 168numbers = moreNumbers; // Error, mutating methods are missing 169 170// Type inference in Arrays 171let ints = [0, 1, 2, 3, 4] // will infer as Array<i32> 172let floats: f32[] = [0, 1, 2, 3, 4] // will infer as Array<f32> 173let doubles = [0.0, 1.0, 2, 3, 4] // will infer as Array<f64> 174let bytes1 = [0 as u8, 1, 2, 3, 4] // will infer as Array<u8> 175let bytes2 = [0, 1, 2, 3, 4] as u8[] // will infer as Array<u8> 176let bytes3: u8[] = [0, 1, 2, 3, 4] // will infer as Array<u8>

Further Reading