feat: support bare name assignments in interactive and function scopes

This commit is contained in:
2026-10-20 18:16:54 +08:00
parent 6281e58647
commit df1b77fc1a
17 changed files with 259 additions and 37 deletions
+20 -14
View File
@@ -179,22 +179,28 @@ impl<'a> Emitter<'a> {
self.emit(Opcode::StoreGlobal, self.name_index(&function.name.text))
}
fn store_binding(&mut self, name: &str, value: &Expr) -> Result<(), Diagnostic> {
self.expression(value)?;
if self.scope.kind == ScopeKind::Function {
let index = self
.scope
.layout
.locals
.iter()
.position(|local| local == name)
.expect("analysis allocates binding and assignment targets");
self.emit(Opcode::StoreFast, index)?;
} else {
self.emit(Opcode::StoreGlobal, self.name_index(name))?;
}
Ok(())
}
fn statement(&mut self, statement: &Stmt, symbols: &SymbolTable) -> Result<(), Diagnostic> {
match &statement.kind {
StmtKind::Binding(binding) => {
self.expression(&binding.value)?;
if self.scope.kind == ScopeKind::Function {
let index = self
.scope
.layout
.locals
.iter()
.position(|name| name == &binding.name.text)
.expect("analysis allocates each local");
self.emit(Opcode::StoreFast, index)?;
} else {
self.emit(Opcode::StoreGlobal, self.name_index(&binding.name.text))?;
}
StmtKind::Binding(binding) => self.store_binding(&binding.name.text, &binding.value)?,
StmtKind::Assignment(assignment) => {
self.store_binding(&assignment.name.text, &assignment.value)?
}
StmtKind::Return(statement) => {
if let Some(value) = &statement.value {