mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
feat: 支持复合运算符
This commit is contained in:
@@ -223,7 +223,7 @@ impl Compiler {
|
||||
} else {
|
||||
self.count_expression(&assign.right, ctx);
|
||||
ctx.alloc_reg();
|
||||
ctx.projected_pc += 1; // STORE_VAR
|
||||
ctx.projected_pc += 1;
|
||||
}
|
||||
}
|
||||
Expression::ConditionalExpression(cond) => {
|
||||
|
||||
@@ -630,13 +630,27 @@ impl Compiler {
|
||||
&assign.left
|
||||
{
|
||||
if assign.operator != AssignmentOperator::Assign {
|
||||
return Err("compound assignment not yet supported".into());
|
||||
let rhs = self.emit_expression(&assign.right, ctx)?;
|
||||
let name = id_ref.name.as_str();
|
||||
let var_reg = ctx.lookup_or_global(name);
|
||||
let op = match assign.operator {
|
||||
AssignmentOperator::Addition => OpCode::COMPOUND_ADD,
|
||||
AssignmentOperator::Subtraction => OpCode::COMPOUND_SUB,
|
||||
AssignmentOperator::Multiplication => OpCode::COMPOUND_MUL,
|
||||
AssignmentOperator::Division => OpCode::COMPOUND_DIV,
|
||||
AssignmentOperator::Remainder => OpCode::COMPOUND_MOD,
|
||||
AssignmentOperator::Exponential => OpCode::COMPOUND_EXP,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
ctx.emit(opcode::encode(op, var_reg, rhs, 0));
|
||||
Ok(var_reg)
|
||||
} else {
|
||||
let val_reg = self.emit_expression(&assign.right, ctx)?;
|
||||
let name = id_ref.name.as_str();
|
||||
let var_reg = ctx.lookup_or_global(name);
|
||||
ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, val_reg, 0));
|
||||
Ok(val_reg)
|
||||
}
|
||||
let val_reg = self.emit_expression(&assign.right, ctx)?;
|
||||
let name = id_ref.name.as_str();
|
||||
let var_reg = ctx.lookup_or_global(name);
|
||||
ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, val_reg, 0));
|
||||
Ok(val_reg)
|
||||
} else {
|
||||
Err("assignment target not supported".into())
|
||||
}
|
||||
|
||||
@@ -155,6 +155,11 @@ fn hash_expression(expr: &Expression, h: &mut rustc_hash::FxHasher) {
|
||||
8u8.hash(h);
|
||||
b.value.hash(h);
|
||||
}
|
||||
Expression::AssignmentExpression(assign) => {
|
||||
11u8.hash(h);
|
||||
std::mem::discriminant(&assign.operator).hash(h);
|
||||
hash_expression(&assign.right, h);
|
||||
}
|
||||
_ => {
|
||||
std::mem::discriminant(expr).hash(h);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,14 @@ pub enum OpCode {
|
||||
DIV = 0x03,
|
||||
MOD = 0x04,
|
||||
NEG = 0x05,
|
||||
COMPOUND_ADD = 0x06,
|
||||
COMPOUND_SUB = 0x07,
|
||||
COMPOUND_MUL = 0x08,
|
||||
COMPOUND_DIV = 0x09,
|
||||
COMPOUND_MOD = 0x0A,
|
||||
COMPOUND_EXP = 0x0B,
|
||||
|
||||
// ── Comparison (0x10-0x1F) ──
|
||||
// -- Comparison (0x10-0x1F) --
|
||||
EQ = 0x10,
|
||||
NEQ = 0x11,
|
||||
LT = 0x12,
|
||||
@@ -104,6 +110,12 @@ impl TryFrom<u8> for OpCode {
|
||||
0x03 => Ok(OpCode::DIV),
|
||||
0x04 => Ok(OpCode::MOD),
|
||||
0x05 => Ok(OpCode::NEG),
|
||||
0x06 => Ok(OpCode::COMPOUND_ADD),
|
||||
0x07 => Ok(OpCode::COMPOUND_SUB),
|
||||
0x08 => Ok(OpCode::COMPOUND_MUL),
|
||||
0x09 => Ok(OpCode::COMPOUND_DIV),
|
||||
0x0A => Ok(OpCode::COMPOUND_MOD),
|
||||
0x0B => Ok(OpCode::COMPOUND_EXP),
|
||||
0x10 => Ok(OpCode::EQ),
|
||||
0x11 => Ok(OpCode::NEQ),
|
||||
0x12 => Ok(OpCode::LT),
|
||||
@@ -163,6 +175,12 @@ impl fmt::Display for OpCode {
|
||||
OpCode::DIV => "DIV",
|
||||
OpCode::MOD => "MOD",
|
||||
OpCode::NEG => "NEG",
|
||||
OpCode::COMPOUND_ADD => "COMPOUND_ADD",
|
||||
OpCode::COMPOUND_SUB => "COMPOUND_SUB",
|
||||
OpCode::COMPOUND_MUL => "COMPOUND_MUL",
|
||||
OpCode::COMPOUND_DIV => "COMPOUND_DIV",
|
||||
OpCode::COMPOUND_MOD => "COMPOUND_MOD",
|
||||
OpCode::COMPOUND_EXP => "COMPOUND_EXP",
|
||||
OpCode::EQ => "EQ",
|
||||
OpCode::NEQ => "NEQ",
|
||||
OpCode::LT => "LT",
|
||||
|
||||
Reference in New Issue
Block a user