asmscript

Statements

You might've heard of expression-oriended programming languages, in which every or nearly every statement is also an expression. asmscript is the exact opposite: everything is a statement and there aren't really any expressions.

Assignment

Assignment statement lets you assign a source operand to a destination operand.

DEST = SOURCE;

Examples:

rax = rbx;
rcx = 42;
rdx = -100;

Shorthand

Shorthands (as in shorthand assignment) let you do calculations.

DEST += SOURCE;
DEST -= SOURCE;
DEST *= SOURCE;
DEST /= SOURCE;
DEST %= SOURCE;
DEST &= SOURCE;
DEST |= SOURCE;
DEST ^= SOURCE;

These statements perform (from top to bottom): addition, subtraction, multiplication, division, modulo, bitwise and, bitwise or, bitwise xor. Numbers are assumed to be 64-bit signed integers.

Branch

Branch takes a condition, a block of statements and an optional else block.

branch (CONDITION) {
     STATEMENTS
}

branch (CONDITION) {
    STATEMENTS
} else {
    STATEMENTS
}

Note that braces are mandatory. Branch by its nature contains a condition, so it cannot be combined with a conditional.

Loop

Loop takes an optional condition and a block of statements. Loop without a condition is an infinite loop.

loop {
     STATEMENTS
}

loop (CONDITION) {
    STATEMENTS
}

Note that braces are mandatory. Loop by its nature contains a condition, so it cannot be combined with a conditional.

Push and pop

You can push and pop registers on the stack. Note that this instruction supports only registers.

push REGISTER;
pop REGISTER;

Continue, break and return

You can use continue and break from inside a loop and return from anywhere inside a procedure. There are no labeled breaks or continues.

continue;
break;
return;

Note that return never takes any operands. You return values by setting registers appropriately according to your own calling convention.

Call

You call a procedure by just stating its name followed by a semicolon.

NAME;

stdout

You can output operands and constant strings to stdout through a special statement.

<< SOURCE;
<< STRING;

This statement emits a call to a function implemented in the JIT compiler, which performs the actual printing. All registers are saved before the call and restored afterwards, such that the calling convention in the JIT compiler won't interfere with any values in your registers.

A string is a special token used only for this statement. The string is contained in double quotes and supports the following escape sequences:

Note that when you output a string, the string is placed in memory right beside the instruction that prints that string and a jump instruction is emitted that jumps over the string literal. This can confuse disassemblers when you try to decode generated machine code.