mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
feat: 支持变量声明与标识符语句编译
This commit is contained in:
@@ -140,6 +140,7 @@ impl Compiler {
|
|||||||
}
|
}
|
||||||
Statement::VariableDeclaration(decl) => {
|
Statement::VariableDeclaration(decl) => {
|
||||||
for d in &decl.declarations {
|
for d in &decl.declarations {
|
||||||
|
ctx.alloc_reg();
|
||||||
if let Some(init) = &d.init {
|
if let Some(init) = &d.init {
|
||||||
self.count_expression(init, ctx);
|
self.count_expression(init, ctx);
|
||||||
}
|
}
|
||||||
@@ -282,8 +283,29 @@ impl Compiler {
|
|||||||
Statement::VariableDeclaration(decl) => {
|
Statement::VariableDeclaration(decl) => {
|
||||||
let mut r = None;
|
let mut r = None;
|
||||||
for d in &decl.declarations {
|
for d in &decl.declarations {
|
||||||
|
let name = match &d.id {
|
||||||
|
oxide_parser::BindingPattern::BindingIdentifier(bi) => bi.name.as_str(),
|
||||||
|
_ => return Err("destructuring not supported".into()),
|
||||||
|
};
|
||||||
|
let var_reg = ctx.alloc_reg();
|
||||||
|
ctx.declare(name, var_reg)?;
|
||||||
if let Some(init) = &d.init {
|
if let Some(init) = &d.init {
|
||||||
r = Some(self.emit_expression(init, ctx)?);
|
let val_reg = self.emit_expression(init, ctx)?;
|
||||||
|
ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, val_reg, 0));
|
||||||
|
ctx.init_var(name);
|
||||||
|
r = Some(val_reg);
|
||||||
|
} else {
|
||||||
|
let idx = ctx.add_constant(Constant::Undefined);
|
||||||
|
let tmp = ctx.alloc_reg();
|
||||||
|
ctx.emit(opcode::encode(
|
||||||
|
OpCode::LOAD_CONST,
|
||||||
|
tmp,
|
||||||
|
(idx & 0xFF) as u8,
|
||||||
|
((idx >> 8) & 0xFF) as u8,
|
||||||
|
));
|
||||||
|
ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, tmp, 0));
|
||||||
|
ctx.init_var(name);
|
||||||
|
r = Some(var_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(r)
|
Ok(r)
|
||||||
@@ -301,12 +323,14 @@ impl Compiler {
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
Statement::BlockStatement(block) => {
|
Statement::BlockStatement(block) => {
|
||||||
|
ctx.push_scope();
|
||||||
let mut r = None;
|
let mut r = None;
|
||||||
for s in &block.body {
|
for s in &block.body {
|
||||||
if let Some(rr) = self.emit_statement(s, ctx)? {
|
if let Some(rr) = self.emit_statement(s, ctx)? {
|
||||||
r = Some(rr);
|
r = Some(rr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ctx.pop_scope();
|
||||||
Ok(r)
|
Ok(r)
|
||||||
}
|
}
|
||||||
_ => Ok(None),
|
_ => Ok(None),
|
||||||
@@ -531,6 +555,12 @@ impl Compiler {
|
|||||||
Err("assignment target not supported".into())
|
Err("assignment target not supported".into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Expression::Identifier(ident) => {
|
||||||
|
let var_reg = ctx.lookup(ident.name.as_str())?;
|
||||||
|
let r = ctx.alloc_reg();
|
||||||
|
ctx.emit(opcode::encode(OpCode::LOAD_VAR, r, var_reg, 0));
|
||||||
|
Ok(r)
|
||||||
|
}
|
||||||
Expression::ParenthesizedExpression(p) => self.emit_expression(&p.expression, ctx),
|
Expression::ParenthesizedExpression(p) => self.emit_expression(&p.expression, ctx),
|
||||||
_ => Err(format!("unsupported expression type: {:?}", expr)),
|
_ => Err(format!("unsupported expression type: {:?}", expr)),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user