public override void Visit(While @while) { var expr = new ExpressionSimplifierVisitor().Visit(@while.Expr); if (expr is Bool b && b.Value == false) { return; } _state.ConsolidateVariables(); _state.GoToNextLabel(out var startWhileLabel); _llvmGenerator.Emit($"br label %{startWhileLabel}"); _state.DetachVarEnv(); _state.DetachVarEnv(); var reservedRegisters = _state.ReserveRegisterForCurrentVars(startWhileLabel); _state.GoToNextLabel(out var whileLabel); _llvmGenerator.Emit($"{whileLabel}:"); var startLength = _llvmGenerator.GetCurrentLength(); VisitBlock(@while.Block); _state.ConsolidateVariables(); _state.RestorePreviousVarEnvWithMerge(); _llvmGenerator.Emit($"br label %{startWhileLabel}"); _state.CurrentLabel = startWhileLabel; _llvmGenerator.Emit($"{startWhileLabel}:"); _state.RestorePreviousVarEnvWithMerge(); _state.RemoveReservedRegisters(reservedRegisters, out var removedRegisters); _state.ConsolidateVariables(reservedRegisters); var removedRegs = removedRegisters.ToHashSet(); var reservedToReplace = reservedRegisters.ToList().Where(reg => removedRegs.Contains(reg.Value.Register)).ToList(); _llvmGenerator.ReplaceRegisters(startLength, reservedToReplace.Select(res => (res.Value.Register, _state.VarToLabelToRegister[res.Key][_state.CurrentLabel].Register)).ToList()); var exprResult = new ExpressionGeneratorVisitor(_state).Visit(expr); var endWhileLabel = _state.NewLabel; _llvmGenerator.Emit($"br i1 {exprResult.Register}, label %{whileLabel}, label %{endWhileLabel}"); _state.CurrentLabel = endWhileLabel; _llvmGenerator.Emit($"{endWhileLabel}:"); }
private void VisitBlockWithoutRestore(Block block) { _state.DetachVarEnv(); block.Stmts.ToList().ForEach(Visit); }