"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:"
"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."
{ "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:"
{ $list
{ { $emphasis "Symbol word" } " - pushed on the datastack. See " { $link "symbols" } }
{ { $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."
"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."
"The compiler generates machine code which perform the steps in a more efficient manner than the interpreter, however the observable semantics remain the same." ;
ARTICLE: "combinators" "Combinators"
"The following pair of words invoke the interpreter reflectively:"
"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" } "."
"Sometimes instead of executing one of two quotations, you just need to pick one of two values:"
{ $subsection ? }
"There are some logical operations on booleans:"
{ $subsection >boolean }
{ $subsection and }
{ $subsection or } ;
ARTICLE: "continuations" "Continuations"
"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:"