Skip to main content

Interp

Struct Interp 

Source
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: FirePass

Which 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: bool

Set 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: RustyfiVersion

The 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>

Source

pub fn new(metrics: &'a dyn FontMetrics) -> Self

Source

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.

Source

pub fn register_math_command(&mut self, cmd: Value) -> MathCmdId

Intern an installed math command, returning the handle a Context carries (Context::math_command).

Source

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).

Source

pub fn apply(&mut self, func: Value, arg: Value) -> Result<Value, EvalError>

Source

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V