use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{Arc, OnceLock};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use crate::artifact::CompiledModuleContext;
use crate::ast::{
AssignPathStep, AssignTarget, BinaryOp, Expr, LabelMetadata, ProcessStartExpr, Program,
TypeExpr, UnaryOp,
};
use crate::lexer::Span;
use crate::tracking::{LashlangAstPath, LashlangExecutionContext, LashlangExecutionSite};
use super::record::{Symbol, intern_symbol, lookup_symbol, record_with_capacity, symbol_name};
use super::schema::{ValidationPlan, compile_schema_value};
use super::{
Chunk, CompileStats, CompiledAssignPath, CompiledAssignPathStep, CompiledFormatTemplate,
Instruction, IntrinsicOp, LASH_HOST_REQUIREMENTS_REF_KEY, LASH_MODULE_REF_KEY,
LASH_PROCESS_NAME_KEY, LASH_PROCESS_REF_KEY, LASH_PROCESS_VALUE_KEY, LASH_TYPE_KEY, Name,
Value, as_number, compile_format_template, eval_binary_values, execute_integer_div_builtin,
execute_len_direct, execute_range_builtin, is_comparison_binary_op, is_numeric_binary_op,
is_truthy, read_field_direct, read_index_direct, transient_name, unwrap_type_value,
};
pub(crate) struct Compiler {
module_context: Option<CompiledModuleContext>,
lashlang_execution: Option<LashlangExecutionCompileContext>,
code: Vec<Instruction>,
spans: Vec<Option<Span>>,
constants: Vec<Value>,
names: Vec<Name>,
name_lookup: FxHashMap<Symbol, usize>,
slots: Rc<RefCell<SlotTable>>,
key_lists: Vec<Box<[usize]>>,
format_templates: Vec<CompiledFormatTemplate>,
compiled_schemas: Vec<ValidationPlan>,
assign_paths: Vec<CompiledAssignPath>,
compile_stats: Rc<RefCell<CompileStats>>,
const_slots: Vec<Option<Value>>,
loop_contexts: Vec<LoopContext>,
}
struct LashlangExecutionCompileContext {
context: LashlangExecutionContext,
paths: FxHashMap<usize, LashlangAstPath>,
sites: Vec<Option<LashlangExecutionSite>>,
}
struct LoopContext {
continue_target: usize,
break_jumps: SmallVec<[usize; 4]>,
}
#[derive(Default)]
struct SlotTable {
names: Vec<Name>,
lookup: FxHashMap<Symbol, usize>,
}
include!("compiler/entry.rs");
include!("compiler/expr.rs");
include!("compiler/effects.rs");
include!("compiler/helpers.rs");