Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

921 lines (495 sloc) 17.99 kb

Synopsis

This document describes NAM, aka CgOp, the Niecza Abstract Machine. NAM is the language used to connect the portable parts of Niecza to the unportable. It is the last Niecza IR which is shared between all cross-compiler backends. It is used primarily to refer to two things: a computing model suitable for running Niecza output and a representation of abstract operations in the model.

General model

NAM does not define a file format, nor does it handle the details of representing classes or similar things. Those are handled by a separate backend protocol (not yet documented). NAM only handles the executable expressions and statements that make up sub bodies.

Each sub which is created by the frontend is associated with a string of NAM code, and a list of metaobjects referenced by the NAM code. The backend then needs to use this code to make the sub executable; the CLR backend delays this as long as possible because of quirks of the AssemblyBuilder/TypeBuilder interface, but this is not generally required.

NAM code must be statically typable but this may not always be enforced. Different data objects have logical types, which can map many-to-one onto lower-level types, especially in type-poor environments such as Parrot and JavaScript.

NAM is vaguely similar to Lisp, in the sense that NAM code is built out of expressions which have a value and possibly side effects. An example might do well here:

    ["say",["str","Hello, world"]]

Here the "str" expression returns a str, while the "say" expression does not return anything. NAM, like many backends, does not treat void as a runtime type, and in fact has no way to represent the name.

Surface syntax

NAM code is send to the backend in the form of a variant of JSON. Mappings and undefined are not used; only sequences, strings, numbers, null, true, and false will be generated. One additional syntactic item is added, !123, which uses a decimal index to represent a runtime object which the code needs to reference.

Within string literals, the only escape sequence used is \uABCD, with the requirement to use surrogate characters for codepoints outside the BMP. Outside string literals, whitespace is generally not used.

Runtime data objects, by static type

int

A native integer, suitable for loop variables and similar purposes.

num

A native float, suitable for the Perl 6 Num class.

bool

A native bool, as returned by comparison operators.

str

A reference to a native immutable string.

strbuf

A reference to a native mutable string.

var

A Perl 6 variable, with identity, potentially mutable and tied.

obj

A reference to a Perl 6 object; not a variable and cannot be assigned to.

varhash

A hash table mapping strings to Perl 6 variables.

fvarlist

An array of Perl 6 variables fixed in length at creation.

vvarlist

An array of Perl 6 variables supporting O(1) deque operations.

stab

The nexus of HOW, WHAT, WHO, and REPR. Details subject to flux.

treader

A reference to a native text input object.

twriter

A reference to a native text output object.

lad

A node in the LTM Automaton Descriptor metaobject tree.

cc

A reference to a compiled character class.

cursor

A reference to a low-level cursor. Currently a subtype of obj.

frame

A reference to a call frame. Currently a subtype of obj.

Operations

Macros

These do not appear in nam files as they are expanded in src/CgOp.pm6.

cc_expr

construct_lad

getattr

let

newblankhash

newblanklist

noop

rnull(*@arguments)

Evaluates arguments in sequence and returns CORE::Nil. Useful for embedding a sequence of void nam ops in a Perl 6 statement list.

string_var

varattr

Internal to the backend

These should not be used by the frontend. They are used for construction of some internal code fragments, usually in response to _hack settings.

_addmethod

_hintset

_invalidate

_makesub

_newlabel

_parametricrole

Annotations

ann($unused,$line_number,$operation)

Sets the $line_number for the $operation. In the C# backend, line number is only recorded at high-level call sites within the span.

letscope($transparent,{$lexname,$letname}...,$body)

Within $body, any lexical access to a $lexname is remapped into a letvar access to the corresponding $letname. This is used for inlined functions. If $transparent is false, the corresponding scope should be seen by OUTER:: and the like (not yet implemented).

xspan($n1,$n2,$sync,$body,{$class,$name,$goto},..)

Generates the code for $body bracketed by the labels $n1 and $n2. If an exception transfers control to $n2, the exception payload will be returned. Triples of $code, $label, and $goto define exception handling within the block. $sync forces exception handling to be synchronous with respect to the boundaries, allowing an ON_DIE handler to function properly.

For each triple, while execution is within the block, an exception of class $class [1] will cause control to be transferred to $goto. $name is used for targetted control exceptions, possibly paired with the identity of the target frame. A name of the empty string is treated as no name; such handlers can only be reached anonymously.

[1] The following class values are currently defined:

    1   ON_NEXT             &next
    2   ON_LAST             &last
    3   ON_REDO             &redo
    4   ON_RETURN           &return
    5   ON_DIE              General exception, payload usually Str
    6   ON_SUCCEED          &succeed, when{} matched
    7   ON_PROCEED          &proceed
    8   ON_GOTO             &goto
    9   ON_NEXTDISPATCH     &nextsame, &nextwith; payload is a Capture

Operations on numbers

arith

divide

minus

mod

mul

negate

numand

numcompl

numeq

numge

numgt

numle

numlshift

numlt

numne

numor

numrshift

numxor

plus(var $left,var $right) is pure

Adds $left and $right together.

postinc

double

int

num_to_string

Operations on variables

assign($lhs,$rhs)

The basic polymorphic assignment operator. Depending on the list status of the left variable, either generates a basic store, or a LISTSTORE method call.

fetch($var)

Extracts the value stored in a variable.

newblankrwscalar()

Creates a new scalar variable of type Any containing Any.

newboundvar($ro,$list,$var)

Used for binding parameters in beta-eliminated subs, used to be the heart of the binder but this is no longer so.

newrwlistvar($obj)

Wraps $obj in a read-only variable with the list nature.

newrwscalar($obj)

Creates a new variable of type Any containing $obj.

newscalar($obj)

Wraps $obj in a read-only variable.

newvarrayvar

newvhashvar

newvnewarrayvar

newvnewhashvar

Were used for autovivification; currently unused.

newvsubvar($type,$sub,$obj)

Creates an autovivifiable variable which will call $sub when written to or bound rw, and otherwise functions as ordinary rw.

var_get_var($var)

Returns the object backing $var (will be a fake proxy if not tied).

var_islist($var)

True if $var has the list nature.

var_new_tied($type,$bind,$fetch,$store)

Creates a new variable of type $type which delegates access to $fetch and $store. If $bind is defined, it will be called on the first rw binding, per the autovivification protocol.

Operations on strings

chars

chr

ord

streq

strge

strgt

strle

strlt

strne

substr3

char

str

strbuf_append

strbuf_new

strbuf_seal

str_chr

strcmp

str_length

str_substring

str_tolower

str_tonum

str_toupper

Regex engine operations

make

cursor_ast

cursor_backing

cursor_butpos

cursor_dows

cursor_fresh

cursor_from

cursor_item

cursor_O

cursor_pos

cursor_reduced

cursor_start

cursor_synthetic

cursor_unmatch

cursor_unpackcaps

fcclist_new

get_lexer

ladconstruct

mrl_count

mrl_index

newcc

popcut

pushcut

run_protoregex

rxbacktrack

rxbprim

rxcall

rxclosequant

rxcommitgroup

rxend

rxfinalend

rxframe

rxgetpos

rxgetquant

rxincquant

rxinit

rxopenquant

rxpushb

rxpushcapture

rxsetcapsfrom

rxsetclass

rxsetpos

rxsetquant

rxstripcaps

Operations on Perl 6 lists

array_constructor

cross($usefun,$fvarlist)

Implements X or Xop; if $usefun is true, the first item in $fvarlist is taken as a function reference.

grep

map

zip($usefun,$fvarlist)

Implements Z or Zop; if $usefun is true, the first item in $fvarlist is taken as a function reference.

get_first($list)

iter_to_list($iter)

promote_to_list($var)

Operations on low-level lists

A fvarlist is a fixed sized object like a C# or Java Variable[] array. A vvarlist is an O(1) deque like a C++ std::deque<var>. Most operations on these types are fairly straightforward. vvarlist also does duty as the most fundamental type of iterator; several operations are designed to do essential iterator tasks. vvarlist_ operations are not cognizant of iterator structure and should not be used on iterators without careful consideration of the effect.

fvarlist_item($index,$fvl)

Extracts a single element. BUG: Currently evaluates its arguements in the wrong order.

fvarlist_length($fvl)

Return the number of elements in the argument as an int.

fvarlist_new(*@elements)

Construct a new fvarlist of compile-time length, like a C# array literal.

iter_copy_elems($iter)

Creates a new iterator which iterates over the same values, but all copied into fresh read-write variables. Mostly eager.

iter_flatten($iter)

Creates a new iterator which mostly-eagerly presents the same values with sublists flattened.

iter_hasarg($iter)

Attempts to extract a value from an iterator without flattening sublists. Returns bool; if true, the value may be returned by vvarlist_shift.

iter_hasflat($iter)

See iter_hasarg.

vvarlist_append($onto,$new)

Adds all elements (non-destructively) from a source list onto the end of a destination list in order.

vvarlist_clone($old)

Creates a new non-aliasing list with all elements aliases of the elements of an old list.

vvarlist_count($list)

Returns the number of items in a list.

vvarlist_from_fvarlist($fv)

vvarlist_item($index,$list)

vvarlist_new_empty()

vvarlist_new_singleton($var)

Creates a new list with exactly one initial element. Useful for bootstrapping iterations.

vvarlist_pop($list)

Removes and returns the last element of a nonempty list.

vvarlist_push($list,$item)

Adds a new element to the end of a list.

vvarlist_shift($list)

Removes and returns the first element of a nonempty list.

vvarlist_sort($cb_obj,$list)

Sorts a list (not in place). $cb_obj must be an invocable object which functions as a two-argument sort routine, returning Num.

vvarlist_to_fvarlist($list)

vvarlist_unshift($list,$item)

Adds a new element to the beginning of a list.

vvarlist_unshiftn($list,$fvl)

Adds the contents of a fixed list to the beginning of a variable list in order.

Operations involving the operating system

gettimeofday

exit

getargv

note

path_any_exists

path_change_ext

path_combine

path_dir_exists

path_file_exists

path_modified

path_realpath

print

say

slurp

spew

treader_getc

treader_getline

treader_open

treader_slurp

treader_stdin

Operations invoking the context system

at_key

at_pos

asbool

defined

delete_key

exists_key

hash

item

list

num

asstr

obj_asbool

obj_asdef

obj_asnum

obj_asstr

obj_at_key

obj_at_pos

obj_delete_key

obj_exists_key

obj_getbool

obj_getdef

obj_getnum

obj_getstr

Operations on hashes

hash_keys

hash_kv

hash_pairs

hash_values

varhash_clear

varhash_contains_key

varhash_delete_key

varhash_dup

varhash_getindex

varhash_new

varhash_setindex

Operations on activation frames

callframe

frame_caller

frame_file

frame_hint

frame_line

Sequence control operations

callnext($capture)

cgoto($name,$if)

Go to label named $name (must be a literal string) if $if is true.

control($type,$target,$unused,$name,$payload)

The most general interface to the exception generator.

cotake($cont)

Passes control to a coroutine identified by the continuation frame $cont. When said coroutine uses take, the new continuation frame is stored in the $*nextframe lexical and the value passed is returned.

die($exception)

Throws a basic non-resumable exception. $exception may be a raw string and it will DWIM.

do_require($module)

goto($label)

label($name)

label_table

methodcall($name,$sig,*@args)

Calls method $name on the first argument. The interpretation of the rest of the arguments is controlled by $sig; for each argument, there is a token in $sig consisting of a length and a sequence of characters. A zero-length sequence represents an ordinary positional, a string like ":name" represents a named parameter, and "flatcap" represents a | parameter. Note that in the last case, the argument should have type obj.

ncgoto($to,$if)

See cgoto.

prog(*@arguments)

Evaluates arguments in sequence and returns the result of the last one.

return($value)

Low-level return from a body; does NOT use the control exception mechanism. Probably best regarded as a backend-internal operator.

startgather($sub)

Creates a new coroutine to invoke $sub without arguments, and returns the initial continuation frame.

subcall($sig,*@args)

Identical to methodcall, except that the method name is considered forced to INVOKE.

take($thing)

Passes $thing to the coroutine which caused the current coroutine to be invoked. When this coroutine is restarted, take returns the value unchanged.

ternary($cond,$true,$false)

The basic branching operator.

whileloop($until,$once,$cond,$body)

The basic repetition operator. If $once is passed, the loop is treated as repeat..while. If $until is passed, the condition is inverted.

Operations supporting modules

from_json

from_jsync

to_json

to_jsync

Operations on booleans

not

bool

compare

Data control operations

cast

const($value)

The const op causes its argument to be evaluated once and stored in the constant table; it should only be used in cases where the identity will have the same effect, and backends are not required to honor it.

context_get

corelex

letn

letvar

null($type)

Produces a null value of type $type, suitable for initializing a variable or other similar usage.

scopedlex

set_status

sink($argument)

Evaluates and ignores $argument.

status_get

Object model operations

box($proto,$value)

Creates a boxing object of a given type. $proto may be a CORE:: name.

class_ref("mo",$corename) | class_ref("mo",$unit,$xix,$name)

Returns the raw stab for a class, by CORE:: name or xref node fields.

default_new(obj $proto, varhash $args)

Implements Mu.new.

getslot($name,$type,$object)

Fetches a named slot from an object. $type must be used consistantly.

how($obj)

Returns the ClassHOW or similar instance for an object.

instrole(fvarlist $parcel)

Instantiates a parameterized role (first argument) with arguments (rest).

llhow_name(stab $stb)

obj_does(obj $obj, stab $role)

obj_isa(obj $obj, stab $super)

obj_is_defined(obj $obj)

Checks REPR-level definedness, not .defined.

obj_llhow(obj $obj)

obj_newblank(stab $stab)

Fastest way to create an object. Does not set up variables for attributes.

obj_typename(obj $obj)

obj_what(obj $obj)

role_apply(stab $base, stab $role)

Implements the but operator for type objects.

setbox(obj $obj, ::T $value)

Mutates a boxed value in place. Use carefully!

setslot($name, obj $obj, ::T $value)

Binds a slot, possibly to a native value.

stab_privatemethod(stab $stab, str $name)

Obtains a reference to the Sub implementing a private method.

stab_what(stab $stab)

unbox($typename, obj $obj)

CLR interface operations

rawcall

rawscall

Jump to Line
Something went wrong with that request. Please try again.