pub struct Interp<'a> {Show 21 fields
pub metrics: &'a dyn FontMetrics,
pub images: Vec<ImageResource>,
pub hooks: Vec<Value>,
pub math_commands: Vec<Value>,
pub crossrefs: Rc<RefCell<CrossRefs>>,
pub annotations: Vec<Annot>,
pub destinations: Vec<NamedDest>,
pub outline: Vec<OutlineEntry>,
pub page_graphics: Vec<Vec<GraphicsElem>>,
pub doc_info: Option<DocInfo>,
pub current_page: Option<usize>,
pub fire_pass: FirePass,
pub page_break_hooks_fired: bool,
pub current_deco_id: Option<DecoId>,
pub pending_dests: Option<Vec<(String, Point)>>,
pub link_decos: Vec<(DecoId, AnnotAction)>,
pub dest_decos: Vec<(DecoId, String)>,
pub frame_decos: Vec<(DecoId, FrameDecoration)>,
pub decos: Vec<DecoEntry>,
pub outer_graphics: Vec<(Value, RustyfiVersion)>,
pub version: RustyfiVersion,
/* private fields */
}Expand description
Evaluation state threaded through every primitive: font metrics, images, hooks, cross-references, and the per-trial accumulators below.
Fields§
§metrics: &'a dyn FontMetrics§images: Vec<ImageResource>The document-wide image table: load-image decodes eagerly and
pushes here, returning the index as Value::Image;
use-image-by-width looks the resource back up by it. page-break
clones this into DocumentValue::images (a superset of what actually
ends up placed on a page — the PDF writer itself filters down to the
images a placed line actually references).
hooks: Vec<Value>The document-wide page-break-hook closure table: hook-page-break
pushes its closure and returns a HookId index
(PureHorzBox::HookPageBreak) — the images-style seam, but for a
deferred computation. Reset every trial (see crossrefs, the one
exception); read back by fire_hooks once placement is known.
math_commands: Vec<Value>Installed-math-command table (get-initial-context/
set-math-command push here; Context::math_command holds the
index) — needed because the backend Context cannot hold a lang-side
Value. Read back by read_inline’s EmbedMath arm.
crossrefs: Rc<RefCell<CrossRefs>>The cross-reference table, shared with the compile driver across
every trial of the fixpoint loop — unlike hooks/images, this must
not reset per trial, so the driver clones one Rc<RefCell< CrossRefs>> handle into each trial’s fresh Interp.
annotations: Vec<Annot>Accumulators: link annotations / named destinations / outline
entries, plus the per-page deco-graphics overlays. All reset per
trial; the FINAL trial’s contents are moved into
DocumentValue::extras by compile_document_cst_with_trials.
destinations: Vec<NamedDest>§outline: Vec<OutlineEntry>§page_graphics: Vec<Vec<GraphicsElem>>§doc_info: Option<DocInfo>register-document-information’s accumulator — LAST WRITE WINS,
same reset-per-trial policy as outline/annotations/destinations.
current_page: Option<usize>Some(0-based page) only while a placed-geometry walk is on that page
— the port of upstream’s State.during_page_break + “current page”
(annotation.ml:15, namedDest.ml’s notify_pagebreak). Both walks
set it: page_break_core’s per-page hook pass and fire_hooks.
fire_pass: FirePassWhich half of the placed-geometry walk is running right now. The walk
happens TWICE per trial and each pass must fire exactly one half of it
— see FirePass.
page_break_hooks_fired: boolSet by page_break_core once it has finished driving its per-page
FirePass::HooksOnly pass, so the fire_hooks call that follows the
page loop knows to run FirePass::DecosOnly and not fire every
hook-page-break a second time. Stays false for a DocumentValue
assembled by hand (unit tests drive fire_hooks directly), which then
runs the undivided FirePass::All.
current_deco_id: Option<DecoId>Links/metadata: the DecoId of the deco closure currently
being fired by fire_hooks’ two apply_deco call sites, None
outside any such window. This is the STRUCTURAL link between a
placed Annot/NamedDest (page-absolute, known only
post-page-break) and the PureHorzBox::Frame/
VertBox::FrameStart/FrameEnd marker that produced it in the
PRE-page-break DocumentValue::reflow_source — both carry the SAME
DecoId, so recording it here (into link_decos/dest_decos
below) lets the reflow backend resolve “which Frame is this link”
exactly, not by geometry/position.
pending_dests: Option<Vec<(String, Point)>>Some only while an inline-graphics callback is being applied
EAGERLY, outside any page-break window (apply_graphics_callback):
register-destination appends its (key, box-local point) here
instead of erroring, and the caller turns each into a
GraphicsElem::Destination marker riding in the resulting box. Left
None inside a page-break window, so the direct registration wins
there.
link_decos: Vec<(DecoId, AnnotAction)>One (DecoId, action) per register-link-to-uri/-to-location
call made while current_deco_id was Some. Reset per trial,
drained into DocumentValue::reflow_links by eval_document_trials
alongside extras.
dest_decos: Vec<(DecoId, String)>Same idea as link_decos, for register-destination
(annot.satyh’s register-location-frame idiom): (DecoId, name).
Drained into DocumentValue::reflow_dests.
frame_decos: Vec<(DecoId, FrameDecoration)>Each block frame’s own decoration at its natural size, box-local —
see rustyfi_backend::FrameDecoration. Recorded by fire_hooks and
drained into DocumentValue::reflow_frame_decos, so a renderer with
no page grid can draw the frame the document actually asked for
instead of nothing at all. Unread by the PDF path.
decos: Vec<DecoEntry>Deco-closure table (DecoId indexes here) — hooks’ twin for
decorations. Inline holds one deco closure
(point -> length -> length -> length -> graphics list); Block
holds a block frame’s four-closure deco-set + the geometry the
markers can’t carry. Reset per trial.
outer_graphics: Vec<(Value, RustyfiVersion)>Deferred inline-graphics-outer callbacks (length -> point -> graphics list), indexed by GraphicsFnId — the hooks pattern.
Each entry also carries the generation it was registered under, for
the same reason DecoEntry does: the callback’s RESULT shape
(graphics list vs one graphics) is a property of the code that
wrote it, and primitives::resolve_outer_graphics_in_contents runs
long after, from a line-breaking post-pass with no version context
of its own.
version: RustyfiVersionThe target language version this evaluation run is checking against
— consulted only by read_inline’s IText::EmbedMath FALLBACK arm
(no installed math command; unit-test contexts only). Default
V0_0; lib.rs’s eval_document_trials sets this to the real
target version on every Interp it constructs.
Implementations§
Source§impl<'a> Interp<'a>
impl<'a> Interp<'a>
pub fn new(metrics: &'a dyn FontMetrics) -> Self
Sourcepub fn eval(&mut self, base: &BaseEnv, ast: &Ast) -> Result<Value, EvalError>
pub fn eval(&mut self, base: &BaseEnv, ast: &Ast) -> Result<Value, EvalError>
Evaluate ast by compiling it against env and running the result.
A thin shim: ~25 integration tests drive the evaluator through it, and
it is precisely what their compiled counterpart already does — there
is exactly one evaluator, since quoted text is compiled eagerly into
crate::quoted’s name-free form.
base is the COMPILE-time environment ast’s free names resolve
against; the program itself runs in a fresh, empty runtime frame
chain — base is NOT that chain’s root, because nothing resolves a
name at run time.
Sourcepub fn register_math_command(&mut self, cmd: Value) -> MathCmdId
pub fn register_math_command(&mut self, cmd: Value) -> MathCmdId
Intern an installed math command, returning the handle a Context
carries (Context::math_command).
Sourcepub fn dest_name(&mut self, key: &str) -> String
pub fn dest_name(&mut self, key: &str) -> String
namedDest.ml:name_from_hash_table — the stable PDF name for key,
minting nameddest{N} on first sight. Also used by register-outline
(upstream Outline.make_entry calls NamedDest.get, which mints too).
pub fn apply(&mut self, func: Value, arg: Value) -> Result<Value, EvalError>
Sourcepub fn apply_with_opts(
&mut self,
func: Value,
opt_vals: Vec<(String, Value)>,
arg: Value,
) -> Result<Value, EvalError>
pub fn apply_with_opts( &mut self, func: Value, opt_vals: Vec<(String, Value)>, arg: Value, ) -> Result<Value, EvalError>
Beta-reduce func against a positional argument plus a SATySFi 0.1
labeled-optional bundle. For a closure, each of the closure’s declared
optional params binds Some v when the bundle carries its label, else
None; a supplied label the closure does not declare is ignored
(upstream reduce_beta folds over the closure’s map — the
typechecker rejects genuinely-wrong labels first). This
unknown-label-ignore is only sound because typecheck runs first.
Auto Trait Implementations§
impl<'a> !RefUnwindSafe for Interp<'a>
impl<'a> !Send for Interp<'a>
impl<'a> !Sync for Interp<'a>
impl<'a> !UnwindSafe for Interp<'a>
impl<'a> Freeze for Interp<'a>
impl<'a> Unpin for Interp<'a>
impl<'a> UnsafeUnpin for Interp<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more