private void GenerateVarHidingPCMapForBlocks(string methodName, ArmadaStatement blockLow, ArmadaStatement blockHigh) { if (blockLow == null) { return; } if (blockHigh == null) { AH.PrintError(pgp.prog, $"No block in high level corresponding to block at {AH.TokenToString(blockLow.Stmt.Tok)} in low level."); return; } var pcLow = blockLow.StartPC; var pcHigh = blockHigh.StartPC; pcMap[pcLow] = pcHigh; var stmtsHigh = blockHigh.GetStatementsInBody().ToArray(); int whichStmtHigh = 0; foreach (var stmtLow in blockLow.GetStatementsInBody()) { if (IsHiddenStatement(methodName, stmtLow)) { pcMap[stmtLow.EndPC] = pcHigh; continue; } if (whichStmtHigh >= stmtsHigh.Length) { AH.PrintError(pgp.prog, $"Could not figure out how the low-level statement at {AH.TokenToString(stmtLow.Stmt.Tok)} is a hidden-variable assignment, but it doesn't seem to correspond to any high-level statement."); pcMap[stmtLow.EndPC] = pcHigh; continue; } var stmtHigh = stmtsHigh[whichStmtHigh]; if (stmtLow.RoughlyMatches(stmtHigh)) { if (stmtLow is ArmadaIfStatement ifLow) { var ifHigh = (ArmadaIfStatement)stmtHigh; GenerateVarHidingPCMapForBlocks(methodName, ifLow.ThenClause, ifHigh.ThenClause); GenerateVarHidingPCMapForBlocks(methodName, ifLow.ElseClause, ifHigh.ElseClause); } else if (stmtLow is ArmadaWhileStatement whileLow) { var whileHigh = (ArmadaWhileStatement)stmtHigh; GenerateVarHidingPCMapForBlocks(methodName, whileLow.Body, whileHigh.Body); } } else { AH.PrintError(pgp.prog, $"Could not figure out how the low-level statement at {AH.TokenToString(stmtLow.Stmt.Tok)} correponds to the high-level statement at {AH.TokenToString(stmtHigh.Stmt.Tok)}."); } pcHigh = stmtHigh.EndPC; pcMap[stmtLow.EndPC] = pcHigh; ++whichStmtHigh; } }