#include <conteval.hpp>
Inheritance diagram for IntelibContinuation:
The InteLib Continuation is a stack-based virtual machine intended to perform Lisp-like evaluations. This class is used as a base for Lisp-specific and Scheme-specific classes.
The machine holds two stacks, the result_stack and the todo_stack. The result_stack contains SReference's to which evaluations result; its fragments are used as argument vectors for functions, therefore avoiding allocations of such vectors. The todo_stack holds records of two elements: an integer instruction code and a param which is an SReference. There can also be debug-related stack information there (see the INTELIB_CONTINUATION_KEEPS_STACK_INFO conditional macro).
Besides that, the continuation object is responsible for switching lexical contexts; the context is stored as a plain SReference, thus its exact type is determined by the specific subclasses of IntelibContinuation. This is because Lisp and Scheme actually use differently organized lexical contexts.
Evaluation is performed step-by-step. On each step, an instruction is fetched from the top of the todo stack and interpreted. The interpretation can lead to adding some more instructions to the stack, to put one (or even more) results to the result stack, and sometimes the instruction fetches uses up some information from the result stack (e.g., if the instruction is a N-ary function call, it uses the last N+1 elements of the result stack and removes them from there).
To start an evaluation, the expression to be evaluated must be put into the todo stack with the just_evaluate instruction. The evaluation is considered finished when the todo stack is empty. Normally there should be exactly one item in the result stack; it should (but not required though) be considered error if there is no result at all and/or there's more than one item.
Should you need to perform an evaluation on an existing machine keeping the existing state as it is, there's also a possibility to 'mark' the todo stack with the GetMark(), add the expression to the todo stack, and then use the mark to determine whether the stack returned to the marked position, which will mean the evaluation of your expression is complete.
A single evaluation step is performed by the Step() method. There's one important thing about it. The function Step() is NEVER EVER reentered, neither directly nor consequentially. This requirement is absolutely obligatory for continuations to work, as the continuation at each and every step must hold the list of all the operations necessary to finish the whole evaluation, and this would be impossible in case we reenter the Step() function because some information we need will reside in the call stack frames (local variables of functions) instead of the continuation object.
A copy of a continuation can be made. Such a copy is not intended to perform any evaluations itself, but any active continuation can replace its entire state with the content of such a copy. That's how the CALL/CC works.
Definition at line 115 of file conteval.hpp.
Public Types | |
enum | Instructions { just_evaluate = -1, evaluate_prepared = -2, evaluate_progn = -3, quote_parameter = -4, drop_result = -5, return_unspecified = -6, end_of_clauses = -7, cond_clause = -8, bail_on_false = -9, set_context = -10, assign_to = -11, assign_location = -12, generic_iteration = -13, iteration_callback = -14, max_command = -14 } |
The instruction set of the machine. More... | |
Public Member Functions | |
IntelibContinuation () | |
Creates an empty continuation, ready to work. | |
IntelibContinuation (const IntelibContinuation &other, bool ignored) | |
Creates a copy to be used later with ReplaceContinuation. | |
virtual | ~IntelibContinuation () |
The destructor. | |
virtual void | JustEvaluate (const SReference &expr)=0 |
The method to perform the just_evaluate instruction. | |
virtual void | CustomCommand (int opcode, const SReference ¶m) |
Extend the instruction set. | |
bool | Step () |
Perform a single step of the evaluation. | |
int | GetMark () const |
Mark the todo stack before starting an evaluation. | |
bool | Ready (int mark=0) const |
Is the evaluation complete? | |
SReference | Get () |
Get the result of the evaluation. | |
void | ReplaceContinuation (const IntelibContinuation &other) |
Replace the entire state of the continuation. | |
void | PushTodo (int opcode, const SReference ¶m) |
Add an instruction to the todo stack. | |
void | PushTodo (int opcode) |
Add a parameterless instruction to the todo stack. | |
bool | PopTodo (int &opcode, SReference ¶m) |
Get (and remove) the top of the todo stack. | |
void | PushResult (const SReference ¶m) |
Put item into the result stack. | |
bool | PopResult (SReference ¶m) |
Get (and remove) the item from top of the result stack. | |
void | RegularReturn (const SReference &ref) |
Return a value from a Lisp function. | |
void | ReferenceReturn (SReference &ref, const SReference &superstruct) |
Return an assignable reference from a Lisp function. | |
void | AgentReturn (const SReference &val, const SExpressionSetfAgent *ag) |
Return a Setf Agent from a Lisp function. | |
void | TailReturn (const SReference &ref) |
Return a tail (to be evaluated) from a Lisp function. | |
void | ReturnUnspecified () |
Return the 'unspecified' value from a Lisp function. | |
SReference | GetContext () const |
Get current lexical context. | |
void | SetContext (const SReference &cont) |
Set current lexical context. | |
Static Public Member Functions | |
static void | InterruptEvaluator () |
Interrupt the evaluation. | |
static void | RemoveInterruption () |
Cances the interruption of the evaluation. | |
static void | SuspendInterruptions () |
Temporaryly disallow interruptions. | |
static void | ResumeInterruptions () |
Allow interruptions again. | |
Protected Member Functions | |
void | PlaceFormToStack (const SExpressionCons *form, int len) |
Place a prepared form to the stack. | |
Protected Attributes | |
SReference * | PTheFalseValue |
Classes | |
class | Interruption |
Evaluator is effectively interrupted throwing object of this class. More... | |
struct | TodoItem |
|
The instruction set of the machine. Zero and positive opcodes stand for "call a function with that many args", in which case the function object and the args are taken from the result stack. The numbers from -1 downto max_command are the special operation codes. The numbers below max_command are for the operations added by subclasses (e.g., Scheme-specific and Lisp-specific instructions).
Definition at line 201 of file conteval.hpp. |
|
Creates an empty continuation, ready to work.
Definition at line 30 of file conteval.cpp. |
|
Creates a copy to be used later with ReplaceContinuation.
Definition at line 42 of file conteval.cpp. |
|
The destructor.
Definition at line 63 of file conteval.cpp. |
|
The method to perform the just_evaluate instruction. In fact, this is the most visible difference between Lisp and Scheme evaluation models. This method is pure virtual so it must be implemented by subclasses. There's no idea on what to do here by default. Referenced by Step(). |
|
Extend the instruction set. If the instruction code is negative and is not mentioned in the Instructions enum, this method is called; by default it throws an exception. Definition at line 194 of file conteval.cpp. Referenced by Step(). |
|
Perform a single step of the evaluation. Returns false in case the todo stack is empty
Definition at line 105 of file conteval.cpp. References assign_location, assign_to, bail_on_false, cond_clause, CustomCommand(), drop_result, end_of_clauses, evaluate_prepared, evaluate_progn, generic_iteration, SReference::GetPtr(), iteration_callback, just_evaluate, JustEvaluate(), PopResult(), PopTodo(), PTheEmptyList, PushResult(), quote_parameter, return_unspecified, ReturnUnspecified(), and set_context. |
|
Mark the todo stack before starting an evaluation.
Definition at line 168 of file conteval.hpp. |
|
Is the evaluation complete?
Definition at line 175 of file conteval.hpp. |
|
Get the result of the evaluation.
Definition at line 96 of file conteval.cpp. |
|
Replace the entire state of the continuation. This is how the CALL/CC feature works.
Definition at line 70 of file conteval.cpp. |
|
Add an instruction to the todo stack.
Definition at line 199 of file conteval.cpp. References set_context. Referenced by PlaceFormToStack(), PushTodo(), and TailReturn(). |
|
Add a parameterless instruction to the todo stack.
Definition at line 229 of file conteval.cpp. References PushTodo(). |
|
Get (and remove) the top of the todo stack.
Definition at line 235 of file conteval.cpp. Referenced by Step(). |
|
Put item into the result stack.
Definition at line 249 of file conteval.cpp. Referenced by AgentReturn(), ReferenceReturn(), RegularReturn(), and Step(). |
|
Get (and remove) the item from top of the result stack.
Definition at line 264 of file conteval.cpp. Referenced by Step(). |
|
Return a value from a Lisp function.
Definition at line 273 of file conteval.cpp. References PushResult(). Referenced by ReturnUnspecified(). |
|
Return an assignable reference from a Lisp function.
Definition at line 290 of file conteval.cpp. References PushResult(). |
|
Return a Setf Agent from a Lisp function.
Definition at line 300 of file conteval.cpp. References PushResult(). |
|
Return a tail (to be evaluated) from a Lisp function.
Definition at line 310 of file conteval.cpp. References just_evaluate, and PushTodo(). |
|
Return the 'unspecified' value from a Lisp function.
Definition at line 315 of file conteval.cpp. References RegularReturn(). Referenced by Step(). |
|
Get current lexical context.
Reimplemented in LispContinuation, and SchemeContinuation. Definition at line 286 of file conteval.hpp. Referenced by SchemeContinuation::GetContext(), and LispContinuation::GetContext(). |
|
Set current lexical context.
Definition at line 288 of file conteval.hpp. Referenced by SchemeContinuation::SetContext(), and LispContinuation::SetContext(). |
|
Interrupt the evaluation.
Definition at line 296 of file conteval.hpp. |
|
Cances the interruption of the evaluation.
Definition at line 298 of file conteval.hpp. |
|
Temporaryly disallow interruptions.
Definition at line 300 of file conteval.hpp. |
|
Allow interruptions again.
Definition at line 302 of file conteval.hpp. |
|
Place a prepared form to the stack.
Definition at line 452 of file conteval.cpp. References just_evaluate, and PushTodo(). |
|
Definition at line 134 of file conteval.hpp. |