SMOP Mold


(Mold is currently under implementation)
SMOP Mold is a register based interpreter implementation
A DSL called m0ld is used to represent mold opcodes in text form

A Mold block(?) is composed of three parts

The registers 1,2,3 are initialised with

Mold accepts following directives

my $register_name;
declares an empty register

my $register_name = <value>;
with <value> being either an integer, c string literal, or a C var with a ¢prefix
which declares an register which is set to <value> at frame creation time

Bytecode format

The bytecode ends with a 0

  1. Call - 1,<reg> target,<reg> invocant,<reg> identifier,<int> number_of_positionals,(<reg> positional)**{number_of_positionals},<int> number_of_named_arguments,(<reg> name,<reg> value) ** {number_of_named_arguments}
  2. Call2 - 2,<reg> target,<reg> responder_interface,<reg> identifier,<reg> capture
  3. Goto - 3, <absolute offset> where
  4. Br - 4,<reg> condition,<absolute offset> iftrue,<absolute offset> iffalse

Opcodes

Call

$target = $invocant.$method_name($pos1,$pos2,:$named1($named1_value)...)

Creates a capture and calls method whose name is stored in $method_name using the responder interface of $invocant

Call2

$target = $invocant.$method_name(|$catpure)

Goto

goto label

Jumps to label

Br

if $condition {goto iftrue} else {goto iffalse}

Jumps to iiftrue if $condition is equal to a native True, to iffalse if it's equal to False, aborts executions and prints out an error otherwise (TODO throw an exception)

Example

$*OUT.print("hello world\n") is translated to

# register declarations
my $r10;
my $r11;
my $r12; # we have to store even unused return values somewhere

# constants
my $r4 = $SMOP__S1P__RootNamespace;
my $r5 = "postcircumfix:{ }";
my $r6 = "$*OUT";
my $r7 = "FETCH";
my $r8 = "print";
my $r9 = "hello world\n";


#opcodes
$r10 = $r4.$r5($r6);
$r11 = $r10.$r7();
$r12 = $r11.$r8($r9);

The opcodes part ultimatly compiles to such byte code

10 4 5 1 6 0
11 10 7 0 0
12 11 8 1 9 0
0

Syntax Sugar

my $foo = $bar.$baz(...);

is treated like

my $foo;
$foo = $baz.$baz(...);