From 1ea33e2c4265460cec3f190c4e54576e4c7e4073 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sat, 25 Sep 2021 15:43:56 -0400 Subject: Add SETC opcode to docs --- docs/implementation/vm.html | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/implementation/vm.html b/docs/implementation/vm.html index 676e6548..95c3ce5c 100644 --- a/docs/implementation/vm.html +++ b/docs/implementation/vm.html @@ -320,6 +320,14 @@ Modify variable +33 +SETC +X + + +Monadic modify variable + + 40 FLDO NS @@ -477,6 +485,12 @@ r is a reference +33 +SETC +f r (r F) +r is a reference + + 40 FLDO n n.i @@ -496,12 +510,12 @@

A frame is a mutable list of slots for variable values. It has slots for any special names that are available during the blocks execution followed by the local variables it defines. Special names use the ordering 𝕤𝕩𝕨𝕣𝕗𝕘; the first three of these are available in non-immediate blocks while 𝕣 and 𝕗 are available in modifiers and 𝕘 in 2-modifiers specifically.

When a block is pushed with DFND, an instance of the block is created, with its parent frame set to be the frame of the currently-executing block. Setting the parent frame when the block is first seen, instead of when it's evaluated, is what distinguishes lexical from dynamic scoping. If it's an immediate block, it's evaluated immediately, and otherwise it's pushed onto the stack. When the block is evaluated, its frame is initialized using any arguments passed to it, the next instruction's index is pushed onto the return stack, and execution moves to the first instruction in the block. When the RETN instruction is encountered, an index is popped from the return stack and execution returns to this location. As an alternative to maintaining an explicit return stack, a block can be implemented as a native function that creates a new execution stack and returns the value in it when the RETN instruction is reached. This approach uses the implementation language's call stack for the return stack.

Local variables are manipulated with the VARO (or VARU) and VARM instructions, which load the value of a variable and a reference to it (see the next section) respectively. These instructions reference variables by frame depth and slot index. The frame depth indicates in which frame the variable is found: the current frame has depth 0, its block's parent frame has depth 1, and so on. The slot index is an index within that frame.

-

Slots should be initialized with some indication they are not yet defined. The variable can be defined with SETN only if it hasn't been defined yet, and can be accessed with VARO or VARU or modified with SETU or SETM only if it has been defined.

-

Variable references: ARRM VARM SETN SETU SETM SETH VFYM

+

Slots should be initialized with some indication they are not yet defined. The variable can be defined with SETN only if it hasn't been defined yet, and can be accessed with VARO or VARU or modified with SETU, SETM, or SETC only if it has been defined.

+

Variable references: ARRM VARM SETN SETU SETM SETC SETH VFYM

A variable reference indicates a particular frame slot in a way that's independent of the execution context. For example, it could be a pointer to the slot, or a reference to the frame along with the index of the slot. VARM pushes a variable reference to the stack.

A reference list is a list of variable references or reference lists. It's created with the ARRM instruction. In the Javascript VM there's no difference between a reference list and an ordinary BQN list other than the contents.

-

The SETN, SETU, and SETM instructions set a value for a reference. If the reference is to a variable, they simply set its value. For a reference list, the value needs to be destructured. It must be a list of the same length, and each reference in the reference list is set to the corresponding element of the value list.

-

SETM additionally needs to get the current value of a reference. For a variable reference this is its current value (with an error if it's not defined yet); for a reference list it's a list of the values of each reference in the list.

+

The SETN, SETU, SETM, and SETC instructions set a value for a reference. If the reference is to a variable, they simply set its value. For a reference list, the value needs to be destructured. It must be a list of the same length, and each reference in the reference list is set to the corresponding element of the value list.

+

SETM and SETC additionally need to get the current value of a reference. For a variable reference this is its current value (with an error if it's not defined yet); for a reference list it's a list of the values of each reference in the list.

SETH is a modification of SETN for use in header destructuring. It differs in that it doesn't place its result on the stack (making it more like SETN followed by POPS), and that if the assignment fails because the reference and value don't conform then it moves on to the next eligible body in the block rather than giving an error. VFYM converts a BQN value c to a special reference: assigning a value v to it should check if vc but do no assignment. Only SETH needs to accept these references, and it should treat non-matching values as failing assignment.

Namespaces: FLDO FLDM ALIM RETD

A namespace is the collection of variables in a particular scope, along with an association mapping some exported symbols (case- and underscore-normalized strings) to a subset of these. It can be represented using a frame for the variables, plus the variable name list and mask of exported variables from that block's properties in the bytecode. RETD finishes executing the block and returns the namespace for that execution.

-- cgit v1.2.3