refactor: 清除旧代码并展开 crate

This commit is contained in:
2026-07-05 18:43:22 +08:00
parent 9e3ed194e1
commit ea70e3965d
66 changed files with 1413 additions and 2566 deletions
@@ -0,0 +1,56 @@
use crate::compiler::{CompileCtx, Compiler};
use oxide_bytecode::opcode;
impl Compiler {
pub(super) fn count_break_statement(&self, ctx: &mut CompileCtx) {
ctx.projected_pc += 1;
}
pub(super) fn count_continue_statement(&self, ctx: &mut CompileCtx) {
ctx.projected_pc += 1;
}
pub(crate) fn emit_break_statement(
&self, stmt: &oxide_parser::BreakStatement, ctx: &mut CompileCtx,
) -> Result<Option<u8>, String> {
let break_label = if let Some(label) = &stmt.label {
let name = label.name.as_str();
let scope = ctx
.find_label(name)
.ok_or_else(|| format!("SyntaxError: Undefined label '{name}'"))?;
scope.break_label
} else if let Some(sw_label) = ctx.current_switch() {
*sw_label
} else {
let (bl, _) = ctx.current_loop().ok_or("break outside switch or loop".to_string())?;
*bl
};
let break_pos = ctx.resolve_label(break_label)?;
let offset = (break_pos as isize) - (ctx.bytecode.len() as isize);
let offset = ctx.checked_jump_offset(offset);
ctx.emit(opcode::encode_jmp(offset));
Ok(None)
}
pub(crate) fn emit_continue_statement(
&self, stmt: &oxide_parser::ContinueStatement, ctx: &mut CompileCtx,
) -> Result<Option<u8>, String> {
let continue_label = if let Some(label) = &stmt.label {
let name = label.name.as_str();
let scope = ctx
.find_label(name)
.ok_or_else(|| format!("SyntaxError: Undefined label '{name}'"))?;
scope.continue_label.ok_or_else(|| {
format!("SyntaxError: Illegal continue statement: '{name}' does not denote an iteration statement")
})?
} else {
let (_, cl) = ctx.current_loop().ok_or("continue outside loop".to_string())?;
*cl
};
let continue_pos = ctx.resolve_label(continue_label)?;
let offset = (continue_pos as isize) - (ctx.bytecode.len() as isize);
let offset = ctx.checked_jump_offset(offset);
ctx.emit(opcode::encode_jmp(offset));
Ok(None)
}
}
@@ -0,0 +1,21 @@
use crate::compiler::{CompileCtx, Compiler};
use oxide_parser::Statement;
impl Compiler {
pub(super) fn count_expression_statement(
&self, stmt: &oxide_parser::ExpressionStatement<'_>, ctx: &mut CompileCtx,
) {
self.count_expression(&stmt.expression, ctx);
}
fn emit_expression_statement(&self, stmt: &Statement, ctx: &mut CompileCtx) -> Result<Option<u8>, String> {
let Statement::ExpressionStatement(es) = stmt else {
return Ok(None);
};
Ok(Some(self.emit_expression(&es.expression, ctx)?))
}
pub(crate) fn emit_basic_expression(&self, stmt: &Statement, ctx: &mut CompileCtx) -> Result<Option<u8>, String> {
self.emit_expression_statement(stmt, ctx)
}
}
@@ -0,0 +1,49 @@
use crate::compiler::{CompileCtx, Compiler, Label};
use oxide_parser::Statement;
impl Compiler {
pub(super) fn count_labeled_statement(&self, stmt: &oxide_parser::LabeledStatement<'_>, ctx: &mut CompileCtx) {
let body_is_loop = matches!(
stmt.body,
Statement::WhileStatement(_)
| Statement::DoWhileStatement(_)
| Statement::ForStatement(_)
| Statement::ForInStatement(_)
| Statement::ForOfStatement(_)
);
if body_is_loop {
self.count_statement(&stmt.body, ctx);
} else {
let id = ctx.next_label_id();
self.count_statement(&stmt.body, ctx);
ctx.labels.label_map.insert(Label::LabeledEnd(id), ctx.projected_pc);
}
}
fn is_iteration_statement(stmt: &Statement) -> bool {
matches!(
stmt,
Statement::WhileStatement(_)
| Statement::DoWhileStatement(_)
| Statement::ForStatement(_)
| Statement::ForInStatement(_)
| Statement::ForOfStatement(_)
)
}
pub(crate) fn emit_labeled_statement(
&self, stmt: &oxide_parser::LabeledStatement, ctx: &mut CompileCtx,
) -> Result<Option<u8>, String> {
let name = stmt.label.name.as_str();
if Self::is_iteration_statement(&stmt.body) {
ctx.queue_loop_label(name)?;
self.emit_statement(&stmt.body, ctx)?;
} else {
let id = ctx.next_label_id();
ctx.push_label_scope(name, Label::LabeledEnd(id), None)?;
self.emit_statement(&stmt.body, ctx)?;
ctx.pop_label_scope();
}
Ok(None)
}
}
@@ -0,0 +1,29 @@
use crate::compiler::{CompileCtx, Compiler};
use oxide_parser::Statement;
mod break_continue;
mod expression;
mod labeled;
mod return_stmt;
impl Compiler {
pub(crate) fn emit_basic_domain(&self, stmt: &Statement, ctx: &mut CompileCtx) -> Result<Option<u8>, String> {
match stmt {
Statement::ExpressionStatement(_) => self.emit_basic_expression(stmt, ctx),
Statement::ReturnStatement(_) => self.emit_basic_return(stmt, ctx),
Statement::EmptyStatement(_) => Ok(None),
_ => Ok(None),
}
}
pub(crate) fn count_basic(&self, stmt: &Statement, ctx: &mut CompileCtx) {
match stmt {
Statement::ExpressionStatement(es) => self.count_expression_statement(es, ctx),
Statement::ReturnStatement(ret) => self.count_return_statement(ret, ctx),
Statement::BreakStatement(_) => self.count_break_statement(ctx),
Statement::ContinueStatement(_) => self.count_continue_statement(ctx),
Statement::LabeledStatement(ls) => self.count_labeled_statement(ls, ctx),
_ => {}
}
}
}
@@ -0,0 +1,32 @@
use crate::compiler::{CompileCtx, Compiler};
use oxide_bytecode::opcode::{self, OpCode};
use oxide_parser::Statement;
impl Compiler {
pub(super) fn count_return_statement(&self, stmt: &oxide_parser::ReturnStatement<'_>, ctx: &mut CompileCtx) {
if let Some(arg) = &stmt.argument {
self.count_expression(arg, ctx);
}
ctx.projected_pc += 1;
}
fn emit_return_statement(&self, stmt: &Statement, ctx: &mut CompileCtx) -> Result<Option<u8>, String> {
let Statement::ReturnStatement(ret) = stmt else {
return Ok(None);
};
match &ret.argument {
Some(expr) => {
let r = self.emit_expression(expr, ctx)?;
ctx.emit(opcode::encode(OpCode::RETURN, r, 0, 0));
}
None => {
ctx.emit(opcode::encode(OpCode::RETURN, 0, 0, 0));
}
}
Ok(None)
}
pub(crate) fn emit_basic_return(&self, stmt: &Statement, ctx: &mut CompileCtx) -> Result<Option<u8>, String> {
self.emit_return_statement(stmt, ctx)
}
}