Introduction to AssemblyScript (Part 2)

declare function printI32(n: i32): void;
declare function printI64(n: i64): void;
declare function printF32(n: f32): void;
declare function printF64(n: f64): void;
declare function randomI32(): i32;

Control Instructions

export function printEven(n: i32): void {
if (n % 2 == 0) {
printI32(1);
} else {
printI32(0);
}
}
(func $printEven (type 0) (param i32)
(if
(i32.rem_s (local.get 0) (i32.const 2))
(then (call $printI32 (i32.const 0)))
(else (call $printI32 (i32.const 1)))
)
)
exportfunctionmax(a: i32, b: i32): i32{
if(a>b) {
returna;
} else{
returnb;
}
}
(func $max (type 2) (param i32 i32) (result i32)
(select
(local.get 0)
(local.get 1)
(i32.gt_s (local.get 0) (local.get 1))
)
)
exportfunctionprintNums(n: i32): void{
for(leti: i32=0; i<n; i++) {
printI32(i);
if(i==100) {
break;
}
}
}
(func $printNums (type 0) (param i32)
(local i32)
(loop ;; label = @1
(if ;; label = @2
(i32.lt_s (local.get 1) (local.get 0))
(then
(block ;; label = @3
(call $printI32 (local.get 1))
(br_if 0 (;@3;)
(i32.eq (local.get 1) (i32.const 100)))
(local.set 1
(i32.add (local.get 1) (i32.const 1)))
(br 2 (;@1;))
) ;; end of block
) ;; end of then
) ;; end of if
) ;; end of loop
)
export function mul100(n: i32): i32 {
switch (n) {
case 1: return 100;
case 2: return 200;
case 3: return 300;
default: return n * 100;
}
}
(func $mul100 (type 1) (param i32) (result i32)
(block ;; label = @1
(block ;; label = @2
(block ;; label = @3
(block ;; label = @4
(br_table 0 (;@4;) 1 (;@3;) 2 (;@2;) 3 (;@1;)
(i32.sub (local.get 0) (i32.const 1))))
(return (i32.const 100)))
(return (i32.const 200)))
(return (i32.const 300)))
(i32.mul (local.get 0) (i32.const 100))
)
type OP = (a: i32, b: i32) => i32;function add(a: i32, b: i32): i32 { return a + b; }
function sub(a: i32, b: i32): i32 { return a - b; }
function mul(a: i32, b: i32): i32 { return a * b; }
function div(a: i32, b: i32): i32 { return a / b; }
export function calc(a: i32, b: i32, op: i32): i32 {
return getOp(op)(a, b);
}
function getOp(op: i32): OP {
switch (op) {
case 1: return add;
case 2: return sub;
case 3: return mul;
case 4: return div;
default: return add;
}
}
(module
(type (;0;) (func (param i32 i32) (result i32)))
(type (;1;) (func (param i32) (result i32)))
(type (;2;) (func (param i32 i32 i32) (result i32)))
(func $add (type 0) (i32.add (local.get 0) (local.get 1)))
(func $sub (type 0) (i32.sub (local.get 0) (local.get 1)))
(func $mul (type 0) (i32.mul (local.get 0) (local.get 1)))
(func $div (type 0) (i32.div_s (local.get 0) (local.get 1)))
(func $getOp (type 1) (param i32) (result i32) (;; ommitted ;;))
(func $calc (type 2) (param i32 i32 i32) (result i32)
(call_indirect (type 0)
(local.get 0)
(local.get 1)
(call $getOp (local.get 2))
)
)
(table (;0;) 5 funcref)
(memory (;0;) 0)
(export "memory" (memory 0))
(export "calc" (func $calc))
(export "getOp" (func $getOp))
(elem (;0;) (i32.const 1) func $add $sub $mul $div)
)
export function crash2(): void {
unreachable();
}
(func $crash2 (type 1)
(unreachable)
)

Parametric Instructions

export function dropRandom(): void {
randomI32();
}
(func $dropRandom (type 0)
(drop (call $randomI32))
)

Variable Instructions

export function addLocals(a: i32, b: i32): i32 {
let c: i32 = a + b;
return c;
}
(func $addLocals (type 1) (param i32 i32) (result i32)
(local i32)
(local.set 2 (i32.add (local.get 0) (local.get 1)))
(local.get 2)
)
let a: i32;
let b: i32;
let c: i32;
export function addGlobals(): void {
c = a + b;
}
(module
(type (;0;) (func))
(func $addGlobals (type 0)
(global.set 2 (i32.add (global.get 0) (global.get 1)))
)
(global (;0;) (mut i32) (i32.const 0))
(global (;1;) (mut i32) (i32.const 0))
(global (;2;) (mut i32) (i32.const 0))
(export "addGlobals" (func $addGlobals))
)

Memory Instructions

class S {
a: i8; b: u8; c: i16; d: u16; e: i32; f: u32; g: i64; h: u64;
i: f32; j: f64;
}
export function loadI32(s: S): void {
printI32(s.a as i32); // i32.load8_s
printI32(s.b as i32); // i32.load8_u
printI32(s.c as i32); // i32.load16_s
printI32(s.d as i32); // i32.load16_u
printI32(s.e as i32); // i32.load
printI32(s.f as i32); // i32.load
}
(func $loadI32 (type 0) (param i32)
(call $printI32 (i32.load8_s (local.get 0)))
(call $printI32 (i32.load8_u offset=1 (local.get 0)))
(call $printI32 (i32.load16_s offset=2 (local.get 0)))
(call $printI32 (i32.load16_u offset=4 (local.get 0)))
(call $printI32 (i32.load offset=8 (local.get 0)))
(call $printI32 (i32.load offset=12 (local.get 0)))
)
export function loadI64(s: S): void {
printI64(s.a as i64); // i64.load8_s?
printI64(s.b as i64); // i64.load8_u?
printI64(s.c as i64); // i64.load16_s?
printI64(s.d as i64); // i64.load16_u?
printI64(s.e as i64); // i64.load32_s?
printI64(s.f as i64); // i64.load32_u?
printI64(s.g as i64); // i64.load
printI64(s.h as i64); // i64.load
}
(func $loadI64 (type 0) (param i32)
(call $printI64 (i64.extend_i32_s (i32.load8_s (local.get 0))))
(call $printI64 (i64.extend_i32_u (i32.load8_u offset=1 (local.get 0))))
(call $printI64 (i64.extend_i32_s (i32.load16_s offset=2 (local.get 0))))
(call $printI64 (i64.extend_i32_u (i32.load16_u offset=4 (local.get 0))))
(call $printI64 (i64.extend_i32_s (i32.load offset=8 (local.get 0))))
(call $printI64 (i64.extend_i32_u (i32.load offset=12 (local.get 0))))
(call $printI64 (i64.load offset=16 (local.get 0)))
(call $printI64 (i64.load offset=24 (local.get 0)))
)
export function loadF(s: S): void {
printF32(s.i); // f32.load
printF64(s.j); // f64.load
}
(func $loadF (type 0) (param i32)
(call $printF32 (f32.load offset=32 (local.get 0)))
(call $printF64 (f64.load offset=40 (local.get 0)))
)
export function store(s: S, v: i64): void {
s.a = v as i8; // i32.store8
s.b = v as u8; // i32.store8
s.c = v as i16; // i32.store16
s.d = v as u16; // i32.store16
s.e = v as i32; // i32.store
s.f = v as u32; // i32.store
s.g = v as i64; // i64.store
s.h = v as u64; // i64.store
s.i = v as f32; // f32.store
s.j = v as f64; // f64.store
}
(func $store (type 1) (param i32 i64)
(i32.store8 (local.get 0) (i32.wrap_i64 (local.get 1)))
(i32.store8 offset=1 (local.get 0) (i32.wrap_i64 (local.get 1)))
(i32.store16 offset=2 (local.get 0) (i32.wrap_i64 (local.get 1)))
(i32.store16 offset=4 (local.get 0) (i32.wrap_i64 (local.get 1)))
(i32.store offset=8 (local.get 0) (i32.wrap_i64 (local.get 1)))
(i32.store offset=12 (local.get 0) (i32.wrap_i64 (local.get 1)))
(i64.store offset=16 (local.get 0) (local.get 1))
(i64.store offset=24 (local.get 0) (local.get 1))
(f32.store offset=32 (local.get 0) (f32.convert_i64_s (local.get 1)))
(f64.store offset=40 (local.get 0) (f64.convert_i64_s (local.get 1)))
)
export function sizeAndGrow(n: i32): void {
printI32(memory.size());
printI32(memory.grow(n));
}
(func $sizeAndGrow (type 0) (param i32)
(call $printI32 (memory.size))
(call $printI32 (memory.grow (local.get 0)))
)

Numeric Instructions

export function consts(): void {
printI32(1234); // i32.const
printI64(5678); // i64.const
printF32(3.14); // f32.const
printF64(2.71); // f64.const
}
(func consts (type 1)
(call $printI32 (i32.const 1234))
(call $printI64 (i64.const 5678))
(call $printF32 (f32.const 0x1.91eb86p+1 (;=3.14;)))
(call $printF64 (f64.const 0x1.5ae147ae147aep+1 (;=2.71;)))
)
export function testOps(a: i32): void {
if (a == 0) { // i32.eqz
printI32(123);
}
}
(func $testOps (type 0) (param i32)
(if (i32.eqz (local.get 0))
(then (call $printI32 (i32.const 123)))
)
)
export function relOps(a: i32, b: i32, c: u32, d:  u32): void {
if (a == b) { printI32(0); } // i32.eq
if (a != b) { printI32(1); } // i32.ne
if (a < b) { printI32(2); } // i32.lt_s
if (c < d) { printI32(3); } // i32.lt_u
if (a > b) { printI32(4); } // i32.gt_s
if (c > d) { printI32(5); } // i32.gt_u
if (a <= b) { printI32(6); } // i32.le_s
if (c <= d) { printI32(7); } // i32.le_u
if (a >= b) { printI32(8); } // i32.ge_s
if (c >= d) { printI32(9); } // i32.ge_u
}
(func relOps (type 2) (param i32 i32 i32 i32)
(if (i32.eq (local.get 0) (local.get 1))
(then (call $printI32 (i32.const 0))))
(if (i32.ne (local.get 0) (local.get 1))
(then (call $printI32 (i32.const 1))))
(if (i32.lt_s (local.get 0) (local.get 1))
(then (call $printI32 (i32.const 2))))
(if (i32.lt_u (local.get 2) (local.get 3))
(then (call $printI32 (i32.const 3))))
(if (i32.gt_s (local.get 0) (local.get 1))
(then (call $printI32 (i32.const 4))))
(if (i32.gt_u (local.get 2) (local.get 3))
(then (call $printI32 (i32.const 5))))
(if (i32.le_s (local.get 0) (local.get 1))
(then (call $printI32 (i32.const 6))))
(if (i32.le_u (local.get 2) (local.get 3))
(then (call $printI32 (i32.const 7))))
(if (i32.ge_s (local.get 0) (local.get 1))
(then (call $printI32 (i32.const 8))))
(if (i32.ge_u (local.get 2) (local.get 3))
(then (call $printI32 (i32.const 9))))
)
export function unOps(a: i32, b: f32): void {
printI32(clz<i32>(a)); // i32.clz
printI32(ctz<i32>(a)); // i32.ctz
printI32(popcnt<i32>(a)); // i32.popcnt
printF32(abs<f32>(b)); // f32.abs
printF32(-b); // f32.neg
printF32(sqrt<f32>(b)); // f32.sqrt
printF32(floor<f32>(b)); // f32.floor
printF32(trunc<f32>(b)); // f32.trunc
printF32(nearest<f32>(b)); // f32.nearest
}
(func unOps (type 3) (param i32 f32 f32)
(call $printI32 (i32.clz (local.get 0)))
(call $printI32 (i32.ctz (local.get 0)))
(call $printI32 (i32.popcnt (local.get 0)))
(call $printF32 (f32.abs (local.get 1)))
(call $printF32 (f32.neg (local.get 1)))
(call $printF32 (f32.sqrt (local.get 1)))
(call $printF32 (f32.floor (local.get 1)))
(call $printF32 (f32.trunc (local.get 1)))
(call $printF32 (f32.nearest (local.get 1)))
)
export function binOps(a: i32, b: i32, c: u32, d: u32, e: f32, f: f32): void {
printI32(a + b); // i32.add
printI32(a - b); // i32.sub
printI32(a * b); // i32.mul
printI32(a / b); // i32.div_s
printI32(c / d); // i32.div_u
printI32(a % b); // i32.rem_s
printI32(c % d); // i32.rem_u
printI32(a & b); // i32.and
printI32(a | b); // i32.or
printI32(a ^ b); // i32.xor
printI32(a << b); // i32.shl
printI32(a >> b); // i32.shr_s
printI32(a >>> b); // i32.shr_u
printI32(rotl<i32>(a, b)); // i32.rotl
printI32(rotr<i32>(a, b)); // i32.rotr
}
(func binOps (type 3) (param i32 i32 i32 i32 f32 f32)
(call $printI32 (i32.add (local.get 0) (local.get 1)))
(call $printI32 (i32.sub (local.get 0) (local.get 1)))
(call $printI32 (i32.mul (local.get 0) (local.get 1)))
(call $printI32 (i32.div_s (local.get 0) (local.get 1)))
(call $printI32 (i32.div_s (local.get 2) (local.get 3)))
(call $printI32 (i32.rem_s (local.get 0) (local.get 1)))
(call $printI32 (i32.rem_s (local.get 2) (local.get 3)))
(call $printI32 (i32.and (local.get 0) (local.get 1)))
(call $printI32 (i32.or (local.get 0) (local.get 1)))
(call $printI32 (i32.xor (local.get 0) (local.get 1)))
(call $printI32 (i32.shl (local.get 0) (local.get 1)))
(call $printI32 (i32.shr_s (local.get 0) (local.get 1)))
(call $printI32 (i32.shr_u (local.get 0) (local.get 1)))
(call $printI32 (i32.rotl (local.get 0) (local.get 1)))
(call $printI32 (i32.rotr (local.get 0) (local.get 1)))
)
export function cvtOps(a: i32, b: i64, c: u32, d: u64, e: f32, f: f64): void {
printI32(b as i32); // i32.wrap_i64
printI32(e as i32); // i32.trunc_f32_s
printI32(e as u32); // i32.trunc_f32_u
printI32(f as i32); // i32.trunc_f64_s
printI32(f as u32); // i32.trunc_f64_u
printI64(a); // i64.extend_i32_s
printI64(a as u32); // i64.extend_i32_u
printI64(e as i64); // i64.trunc_f32_s
printI64(e as u64); // i64.trunc_f32_u
printI64(f as i64); // i64.trunc_f64_s
printI64(f as u64); // i64.trunc_f64_u
printF32(a as f32); // f32.convert_i32_s
printF32(c as f32); // f32.convert_i32_u
printF32(b as f32); // f32.convert_i64_s
printF32(d as f32); // f32.convert_i64_u
printF32(f as f32); // f32.demote_f64
printF64(a as f64); // f64.convert_i32_s
printF64(c as f64); // f64.convert_i32_u
printF64(b as f64); // f64.convert_i64_s
printF64(d as f64); // f64.convert_i64_u
printF64(e); // f64.promote_f32
printI32(reinterpret<i32>(e)); // i32.reinterpret_f32
printI64(reinterpret<i64>(f)); // i64.reinterpret_f64
printF32(reinterpret<f32>(a)); // f32.reinterpret_i32
printF64(reinterpret<f64>(b)); // f64.reinterpret_i64
}
(func cvtOps (type 4) (param i32 i64 i32 i64 f32 f64)
(call $printI32 (i32.wrap_i64 (local.get 1)))
(call $printI32 (i32.trunc_f32_s (local.get 4)))
(call $printI32 (i32.trunc_f32_u (local.get 4)))
(call $printI32 (i32.trunc_f64_s (local.get 5)))
(call $printI32 (i32.trunc_f64_u (local.get 5)))
(call $printI64 (i64.extend_i32_s (local.get 0)))
(call $printI64 (i64.extend_i32_u (local.get 0)))
(call $printI64 (i64.trunc_f32_s (local.get 4)))
(call $printI64 (i64.trunc_f32_u (local.get 4)))
(call $printI64 (i64.trunc_f64_s (local.get 5)))
(call $printI64 (i64.trunc_f64_u (local.get 5)))
(call $printF32 (f32.convert_i32_s (local.get 0)))
(call $printF32 (f32.convert_i32_u (local.get 2)))
(call $printF32 (f32.convert_i64_s (local.get 1)))
(call $printF32 (f32.convert_i64_u (local.get 3)))
(call $printF32 (f32.demote_f64 (local.get 5)))
(call $printF64 (f64.convert_i32_s (local.get 0)))
(call $printF64 (f64.convert_i32_u (local.get 2)))
(call $printF64 (f64.convert_i64_s (local.get 1)))
(call $printF64 (f64.convert_i64_u (local.get 3)))
(call $printF64 (f64.promote_f32 (local.get 4)))
(call $printI32 (i32.reinterpret_f32 (local.get 4)))
(call $printI64 (i64.reinterpret_f64 (local.get 5)))
(call $printF32 (f32.reinterpret_i32 (local.get 0)))
(call $printF64 (f64.reinterpret_i64 (local.get 1)))
)

Summary

exportfunctionunOps(a: i32, b: f32): void{
printI32(clz<i32>(a)); // i32.clz
printI32(ctz<i32>(a)); // i32.ctz
printI32(popcnt<i32>(a)); // i32.popcnt
printF32(abs<f32>(b)); // f32.abs
printF32(-b); // f32.neg
printF32(sqrt<f32>(b)); // f32.sqrt
printF32(floor<f32>(b)); // f32.floor
printF32(trunc<f32>(b)); // f32.trunc
printF32(nearest<f32>(b)); // f32.nearest
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store