G-Machine State Transition Rules

Core Transition Rules

  1. Lookup a global by name and push its value onto the stack

    \gmrule
{ \mathtt{PushGlobal} \; f : i
& s
& d
& h
& m
\begin{bmatrix}
     f : a
\end{bmatrix}
}
{ i
& a : s
& d
& h
& m
}

  2. Allocate an int node on the heap, and push the address of the newly created node onto the stack

    \gmrule
{ \mathtt{PushInt} \; n : i
& s
& d
& h
& m
}
{ i
& a : s
& d
& h
\begin{bmatrix}
     a : \mathtt{NNum} \; n
\end{bmatrix}
& m
}

  3. Allocate an application node on the heap, applying the top of the stack to the address directly below it. The address of the application node is pushed onto the stack.

    \gmrule
{ \mathtt{MkAp} : i
& f : x : s
& d
& h
& m
}
{ i
& a : s
& d
& h
\begin{bmatrix}
     a : \mathtt{NAp} \; f \; x
\end{bmatrix}
& m
}

  4. Push a function’s argument onto the stack

    \gmrule
{ \mathtt{Push} \; n : i
& a_0 : \ldots : a_n : s
& d
& h
& m
}
{ i
& a_n : a_0 : \ldots : a_n : s
& d
& h
& m
}

  5. Tidy up the stack after instantiating a supercombinator

    \gmrule
{ \mathtt{Slide} \; n : i
& a_0 : \ldots : a_n : s
& d
& h
& m
}
{ i
& a_0 : s
& d
& h
& m
}

  6. If the top of the stack is in WHNF (currently this just means a number) is on top of the stack, Unwind considers evaluation complete. In the case where the dump is not empty, the instruction queue and stack is restored from the top.

    \gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& \langle i', s' \rangle : d
& h
\begin{bmatrix}
     a : \mathtt{NNum} \; n
\end{bmatrix}
& m
}
{ i'
& a : s'
& d
& h
& m
}

  7. Bulding on the previous rule, in the case where the dump is empty, leave the machine in a halt state (i.e. with an empty instruction queue).

    \gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& \nillist
& h
\begin{bmatrix}
     a : \mathtt{NNum} \; n
\end{bmatrix}
& m
}
{ \nillist
& a : s
& \nillist
& h
& m
}

  8. Again, building on the previous rules, this rule makes the machine consider unapplied supercombinators to be in WHNF

    \gmrule
{ \mathtt{Unwind} : \nillist
& a_0 : \ldots : a_n : \nillist
& \langle i, s \rangle : d
& h
\begin{bmatrix}
      a_0 : \mathtt{NGlobal} \; k \; c
\end{bmatrix}
& m
}
{ i
& a_n : s
& d
& h
& m \\
\SetCell[c=2]{c}
\text{when $n < k$}
}

  9. If an application is on top of the stack, Unwind continues unwinding

    \gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& d
& h
\begin{bmatrix}
     a : \mathtt{NAp} \; f \; x
\end{bmatrix}
& m
}
{ \mathtt{Unwind} : \nillist
& f : a : s
& d
& h
& m
}

  10. When a supercombinator is on top of the stack (and the correct number of arguments have been provided), Unwind sets up the stack and jumps to the supercombinator’s code (\beta-reduction)

    \gmrule
{ \mathtt{Unwind} : \nillist
& a_0 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
     a_0 : \mathtt{NGlobal} \; n \; c \\
     a_1 : \mathtt{NAp} \; a_0 \; e_1 \\
     \vdots \\
     a_n : \mathtt{NAp} \; a_{n-1} \; e_n \\
\end{bmatrix}
& m
}
{ c
& e_1 : \ldots : e_n : a_n : s
& d
& h
& m
}

  11. Pop the stack, and update the nth node to point to the popped address

    \gmrule
{ \mathtt{Update} \; n : i
& e : f : a_1 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
     a_1 : \mathtt{NAp} \; f \; e \\
     \vdots \\
     a_n : \mathtt{NAp} \; a_{n-1} \; e_n
\end{bmatrix}
& m
}
{ i
& f : a_1 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
     a_n : \mathtt{NInd} \; e
\end{bmatrix}
& m
}

  12. Pop the stack.

    \gmrule
{ \mathtt{Pop} \; n : i
& a_1 : \ldots : a_n : s
& d
& h
& m
}
{ i
& s
& d
& h
& m
}

  13. Follow indirections while unwinding

    \gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& d
& h
\begin{bmatrix}
     a : \mathtt{NInd} \; a'
\end{bmatrix}
& m
}
{ \mathtt{Unwind} : \nillist
& a' : s
& d
& h
& m
}

  14. Allocate uninitialised heap space

    \gmrule
{ \mathtt{Alloc} \; n : i
& s
& d
& h
& m
}
{ i
& a_1 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
     a_1 : \mathtt{NUninitialised} \\
     \vdots \\
     a_n : \mathtt{NUninitialised} \\
\end{bmatrix}
& m
}

  15. Evaluate the top of the stack to WHNF

    \gmrule
{ \mathtt{Eval} : i
& a : s
& d
& h
& m
}
{ \mathtt{Unwind} : \nillist
& a : \nillist
& \langle i, s \rangle : d
& h
& m
}

  16. Reduce a primitive binary operator *.

    \gmrule
{ * : i
& a_1 : a_2 : s
& d
& h
\begin{bmatrix}
      a_1 : x \\
      a_2 : y
\end{bmatrix}
& m
}
{ i
& a' : s
& d
& h
\begin{bmatrix}
     a' : (x * y)
\end{bmatrix}
& m
}

  17. Reduce a primitive unary operator \neg.

    \gmrule
{ \neg : i
& a : s
& d
& h
\begin{bmatrix}
      a : x
\end{bmatrix}
& m
}
{ i
& a' : s
& d
& h
\begin{bmatrix}
     a' : (\neg x)
\end{bmatrix}
& m
}

  18. Pack a constructor if there are sufficient arguments

    \gmrule
{ \mathtt{Pack} \; t \; n : i
& a_1 : \ldots : a_n : s
& d
& h
& m
}
{ i
& a : s
& d
& h
\begin{bmatrix}
      a : \mathtt{NConstr} \; t \; [a_1,\ldots,a_n]
\end{bmatrix}
 & m
}

  19. Evaluate a case

    \gmrule
{ \mathtt{CaseJump} \begin{bmatrix} t \to c \end{bmatrix} : i
& a : s
& d
& h
\begin{bmatrix}
      a : \mathtt{NConstr} \; t \; v
\end{bmatrix}
& m
}
{ c \concat i
& d
& h
& m
}

Extension Rules

  1. A sneaky trick to enable sharing of NNum nodes. We note that the global environment is a mapping of plain old strings to heap addresses. Strings of digits are not considered valid identifiers, so putting them on the global environment will never conflict with a supercombinator! We abuse this by modifying Core Rule 2 to update the global environment with the new node’s address. Consider how this rule might impact garbage collection (remember that the environment is intended for globals).

    \gmrule
{ \mathtt{PushInt} \; n : i
& s
& d
& h
& m
}
{ i
& a : s
& d
& h
\begin{bmatrix}
     a : \mathtt{NNum} \; n
\end{bmatrix}
& m
\begin{bmatrix}
     n' : a
\end{bmatrix}
\\
\SetCell[c=5]{c}
\text{where $n'$ is the base-10 string rep. of $n$}
}

  2. In order for the previous rule to be effective, we are also required to take action when a number already exists in the environment:

    \gmrule
{ \mathtt{PushInt} \; n : i
& s
& d
& h
& m
\begin{bmatrix}
     n' : a
\end{bmatrix}
}
{ i
& a : s
& d
& h
& m
\\
\SetCell[c=5]{c}
\text{where $n'$ is the base-10 string rep. of $n$}
}