mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
48 lines
1.7 KiB
Rust
48 lines
1.7 KiB
Rust
use crate::compiler::{CompileCtx, Compiler};
|
|
use oxide_bytecode::{
|
|
module::Constant,
|
|
opcode::{self, OpCode},
|
|
};
|
|
use oxide_parser::Expression;
|
|
|
|
impl Compiler {
|
|
pub(crate) fn count_array_expression(&self, expr: &Expression, ctx: &mut CompileCtx) {
|
|
let Expression::ArrayExpression(arr) = expr else {
|
|
return;
|
|
};
|
|
ctx.alloc_reg();
|
|
ctx.projected_pc += 1;
|
|
let elem_checkpoint = ctx.reg_checkpoint();
|
|
for elem in &arr.elements {
|
|
if let Some(e) = elem.as_expression() {
|
|
self.count_expression(e, ctx);
|
|
ctx.alloc_reg();
|
|
ctx.projected_pc += 1;
|
|
ctx.projected_pc += 1;
|
|
ctx.restore_reg_checkpoint(elem_checkpoint);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(crate) fn emit_array_expression(
|
|
&self, arr: &oxide_parser::ArrayExpression, ctx: &mut CompileCtx,
|
|
) -> Result<u8, String> {
|
|
let arr_reg = ctx.alloc_reg();
|
|
let n = arr.elements.len() as u16;
|
|
ctx.emit(opcode::encode(OpCode::NEW_ARRAY, arr_reg, (n & 0xFF) as u8, ((n >> 8) & 0xFF) as u8));
|
|
let elem_checkpoint = ctx.reg_checkpoint();
|
|
for (i, elem) in arr.elements.iter().enumerate() {
|
|
let Some(e) = elem.as_expression() else {
|
|
return Err("spread not supported".into());
|
|
};
|
|
let val_reg = self.emit_expression(e, ctx)?;
|
|
let idx_reg = ctx.alloc_reg();
|
|
let idx = ctx.add_constant(Constant::Int(i as i32));
|
|
ctx.emit_load_const(idx_reg, idx);
|
|
ctx.emit(opcode::encode(OpCode::SET_ELEM, arr_reg, idx_reg, val_reg));
|
|
ctx.restore_reg_checkpoint(elem_checkpoint);
|
|
}
|
|
Ok(arr_reg)
|
|
}
|
|
}
|