Ramblings on the Toy Language Part 2Posted on March, 24 2016
In the last installment of Ramblings on the Toy Language, I talked about the definition of an instruction interpreter. Beyond interpreting instructions, providing an environment where instruction subroutines can manipulate various components of the runtime is a key factor in providing a turing-complete architecture. In this installment, I will be going over the basic components of a runtime context.
Much like how various components are connected together on a main bus inside a CPU, the runtime context provides references to various objects (along with their interfaces) that need to be exposed for a runtime to function. Refer to the diagram below:
In this diagram, the entry point initiates the runtime which, in turn, initiates a series of objects such as a Namespace instance, a Runtime stack, an Argument stack, and a Program counter. When a program is run, a Runtime context is then passed as the context to any instruction subroutine. Referring to the instruction specifications, an instruction like
POP S<n> would manipulate the Runtime stack, while an instruction like
GOTO A<addr> would manipulate the program counter.
Each one of these objects under the runtime context have a specific interface where they are manipulated through. The idea of having opcodes as subroutines is to provide abstract wrappers around these interfaces. For example, if there were no runtime context, binary operators wouldn't have a stack to push/pop to. The interface would exist, but the contextual data of specific instances of stacks are needed for a chain of instructions to properly achieve turing-completeness.