"Sometimes an additional storage area is needed to hold objects. The " { $emphasis "retain stack" } " is an auxilliary stack for this purpose. Objects can be moved between the data and retain stacks using the following two words:"
{ $subsection >r }
{ $subsection r> }
"The top of the data stack is ``hidden'' between " { $link >r } " and " { $link r> } ":"
"Words must not leave objects on the retain stack, nor expect values to be there on entry. The retain stack is for local storage within a word only, and occurrences of " { $link >r } " and " { $link r> } " must be balanced inside a single quotation. One exception is the following trick involving " { $link if } "; values may be pushed on the retain stack before the condition value is computed, as long as both branches of the " { $link if } " pop the values off the retain stack before returning:"
"Conceptually, a quotation is a snippet of code which can be passed around and called. Concretely, a quotation is a sequence of objects, some of which may be words. When evaluating a quotation, the interpreter looks at each element in turn, and executes words while pushing other types of objects on the stack. Details can be found in " { $link "interpreter" } "."
"Quotations implement the sequence protocol (" { $link "sequences" } "). Much of the power of Factor comes from the fact that not only can you have literal quotations in your program, but you can also construct new quotations at run time using general sequence words, or the following quotation-specific words:"
"These words are used to implement " { $emphasis "combinators" } ", which are words that take code from the stack. Combinator definitions must be followed by the " { $link POSTPONE: inline } " declaration in order to compile; for example:"
{ $code
": keep ( x quot -- x | quot: x -- )"
" over >r call r> ; inline"
}
"Word inlining is documented in " { $link "declarations" } "."
"The interpreter runs in a loop which repeatedly performs the following steps:"
{ $list
{ "If the end of the current quotation has been reached, the parent quotation is popped from the call stack and execution resumes from the saved location" }
{ "Otherwise, the interpreter performs an action depending on the type of the object at the instruction pointer:"
{ { $emphasis "Compound word" } " - the associated quotation is called. See " { $link "colon-definition" } }
{ { $emphasis "Compiled or primitive word" } " - the interpreter jumps to machine code. See " { $link "primitives" } }
{ { $emphasis "Undefined word" } " - an error is raised. See " { $link "deferred" } }
{ { $emphasis "Wrapper" } " - the wrapped object is pushed on the data stack. Wrappers are used to push word objects directly on the stack when they would otherwise execute. See the " { $link POSTPONE: \ } " parsing word." }
{ "All other types of objects are pushed on the data stack." }
}
}
}
"At each stage, the instruction pointer is advanced by one position."
$terpri
"If the instruction pointer is at the end of a quotation when a nested quotation is called, the quotation which just finished executing is not pushed on the call stack. Therefore the last call in a quotation does not grow the call stack, and tail recursion executes in bounded space."
$terpri
"The compiler generates machine code which perform the steps in a more efficient manner than the interpreter, however the observable semantics remain the same." ;
"At any point in the execution of a program, the " { $emphasis "current continuation" } " represents the future of the computation. This object can be reified with the following two words:"
{ $subsection callcc0 }
{ $subsection callcc1 }
"Another two words resume continuations:"
{ $subsection continue }
{ $subsection continue-with }
"Continuations serve as the building block for a number of higher-level abstractions."
"Support for handling exceptional situations such as bad user input, implementation bugs, and input/output errors is provided by a set of words built using continuations."
$terpri
"Two words raise an error in the innermost error handler for the current dynamic extent:"
{ $subsection throw }
{ $subsection rethrow }
"A set of words establish an error handler:"
{ $subsection cleanup }
{ $subsection recover }
{ $subsection catch }
"Caught errors can be logged in human-readable form:"