MCPcopy Index your code
hub / github.com/endbasic/endbasic / compile_for

Function compile_for

core/src/compiler/top.rs:606–676  ·  view source on GitHub ↗

Compiles a `FOR` loop and emits bytecode into `ctx`.

(ctx: &mut Context, symtable: &mut LocalSymtable<'_>, span: ForSpan)

Source from the content-addressed store, hash-verified

604
605/// Compiles a `FOR` loop and emits bytecode into `ctx`.
606fn compile_for(ctx: &mut Context, symtable: &mut LocalSymtable<'_>, span: ForSpan) -> Result<()> {
607 if span.iter_double && span.iter.ref_type.is_none() {
608 match symtable.get_local_or_global(&span.iter) {
609 Ok(..) => {
610 // Keep existing iterators as-is. This mirrors core behavior where implicit
611 // widening to DOUBLE only happens when the iterator does not exist yet.
612 }
613
614 Err(syms::Error::UndefinedSymbol(..)) => {
615 let key = SymbolKey::from(&span.iter.name);
616 if symtable.get_callable(&key).is_some() {
617 return Err(Error::from_syms(
618 syms::Error::AlreadyDefined(span.iter.clone()),
619 span.iter_pos,
620 ));
621 }
622 symtable
623 .put_local(key, SymbolPrototype::Scalar(ExprType::Double))
624 .map_err(|e| Error::from_syms(e, span.iter_pos))?;
625 }
626
627 Err(e) => return Err(Error::from_syms(e, span.iter_pos)),
628 }
629 }
630
631 compile_assignment(
632 &mut ctx.codegen,
633 symtable,
634 AssignmentSpan { vref: span.iter.clone(), vref_pos: span.iter_pos, expr: span.start },
635 )?;
636
637 let start_pc = ctx.codegen.next_pc();
638 let (jump_end_pc, cond_reg, cond_pos) = {
639 let cond_pos = span.end.start_pos();
640 let mut frozen = symtable.frozen();
641 let mut scope = frozen.temp_scope();
642 let reg = scope.alloc().map_err(|e| Error::from_syms(e, cond_pos))?;
643 compile_expr_as_type(&mut ctx.codegen, &mut frozen, reg, span.end, ExprType::Boolean)?;
644 (ctx.codegen.emit(bytecode::make_nop(), cond_pos), reg, cond_pos)
645 };
646 ctx.codegen.mark_statement_start(start_pc);
647
648 ctx.for_exit_stack.push(vec![]);
649
650 for stmt in span.body {
651 compile_stmt(ctx, symtable, stmt)?;
652 }
653
654 compile_assignment(
655 &mut ctx.codegen,
656 symtable,
657 AssignmentSpan { vref: span.iter, vref_pos: span.iter_pos, expr: span.next },
658 )?;
659
660 let start_target =
661 u16::try_from(start_pc).map_err(|_| Error::TargetTooFar(cond_pos, start_pc))?;
662 ctx.codegen.emit(bytecode::make_jump(start_target), cond_pos);
663

Callers 1

compile_stmtFunction · 0.85

Calls 15

compile_assignmentFunction · 0.85
compile_expr_as_typeFunction · 0.85
compile_stmtFunction · 0.85
get_local_or_globalMethod · 0.80
get_callableMethod · 0.80
put_localMethod · 0.80
next_pcMethod · 0.80
start_posMethod · 0.80
frozenMethod · 0.80
temp_scopeMethod · 0.80
allocMethod · 0.80
emitMethod · 0.80

Tested by

no test coverage detected