use crate::compiler::{CompileCtx, Compiler}; use oxide_bytecode::{ module::Constant, opcode::{self, OpCode}, }; impl Compiler { pub(crate) fn emit_template_literal_expression( &self, tl: &oxide_parser::TemplateLiteral, ctx: &mut CompileCtx, ) -> Result { let r = ctx.alloc_reg(); let quasis = &tl.quasis; let expressions = &tl.expressions; let segment_count = quasis.len() + expressions.len(); let expr_regs: Vec = expressions .iter() .map(|e| self.emit_expression(e, ctx)) .collect::, _>>()?; let quasi_const_idxs: Vec = quasis .iter() .map(|q| { let s = q.value.cooked.as_ref().map(|c| c.to_string()).unwrap_or_default(); ctx.add_constant(Constant::String(s)) }) .collect(); let total_len_hint: usize = quasis .iter() .map(|q| q.value.cooked.as_ref().map(|c| c.len()).unwrap_or(0)) .sum(); ctx.emit(opcode::encode(OpCode::TEMPLATE_STR, r, 0, 0)); ctx.emit(((segment_count as u32) << 16) | (total_len_hint as u32 & 0xFFFF)); let mut expr_iter = expr_regs.iter(); for const_idx in quasi_const_idxs.iter() { ctx.emit(*const_idx as u32 & 0x7FFF_FFFF); if let Some(expr_reg) = expr_iter.next() { ctx.emit(0x8000_0000u32 | (*expr_reg as u32)); } } Ok(r) } }