pub(crate) mod call;
pub(crate) mod compr;
pub(crate) mod def;
pub(crate) mod expr;
pub(crate) mod expr_bool;
pub(crate) mod known;
pub(crate) mod module;
pub(crate) mod scope;
pub(crate) mod small_vec_1;
pub(crate) mod span;
pub(crate) mod stmt;
use std::fmt::Debug;
use gazebo::prelude::*;
use once_cell::sync::Lazy;
use crate::{
codemap::CodeMap,
environment::Globals,
errors::Diagnostic,
eval::{
compiler::scope::{ScopeData, ScopeId, ScopeNames},
runtime::call_stack::FrozenFileSpan,
Evaluator,
},
values::{FrozenRef, FrozenValue},
};
#[derive(Debug)]
pub(crate) struct EvalException(pub(crate) anyhow::Error);
#[cold]
#[inline(never)]
fn add_span_to_error(e: anyhow::Error, span: FrozenFileSpan, eval: &Evaluator) -> anyhow::Error {
Diagnostic::modify(e, |d: &mut Diagnostic| {
d.set_span(span.span(), &span.file());
d.set_call_stack(|| eval.call_stack.to_diagnostic_frames());
})
}
#[cold]
#[inline(never)]
pub(crate) fn add_span_to_expr_error(
e: anyhow::Error,
span: FrozenFileSpan,
eval: &Evaluator,
) -> EvalException {
EvalException(add_span_to_error(e, span, eval))
}
#[inline(always)]
pub(crate) fn expr_throw<'v, T>(
r: anyhow::Result<T>,
span: FrozenFileSpan,
eval: &Evaluator<'v, '_>,
) -> Result<T, EvalException> {
match r {
Ok(v) => Ok(v),
Err(e) => Err(add_span_to_expr_error(e, span, eval)),
}
}
pub(crate) struct Compiler<'v, 'a, 'e> {
pub(crate) eval: &'e mut Evaluator<'v, 'a>,
pub(crate) scope_data: ScopeData,
pub(crate) locals: Vec<ScopeId>,
pub(crate) globals: FrozenRef<'static, Globals>,
pub(crate) codemap: FrozenRef<'static, CodeMap>,
pub(crate) constants: Constants,
pub(crate) has_before_stmt: bool,
pub(crate) bc_profile: bool,
}
impl Compiler<'_, '_, '_> {
pub(crate) fn enter_scope(&mut self, scope_id: ScopeId) {
self.locals.push(scope_id);
}
pub(crate) fn exit_scope(&mut self) -> &mut ScopeNames {
let scope_id = self.locals.pop().unwrap();
self.scope_data.mut_scope(scope_id)
}
}
#[derive(Clone, Copy, Dupe)]
pub(crate) struct Constants {
pub(crate) fn_len: FrozenValue,
pub(crate) fn_type: FrozenValue,
}
impl Constants {
pub fn new() -> Self {
static RES: Lazy<Constants> = Lazy::new(|| {
let g = Globals::standard();
Constants {
fn_len: g.get_frozen("len").unwrap(),
fn_type: g.get_frozen("type").unwrap(),
}
});
*Lazy::force(&RES)
}
}