From dcf2b4443e0b1c8b4d2f14384ef2a14a1f17b8c7 Mon Sep 17 00:00:00 2001 From: Aman Goel Date: Wed, 8 May 2024 23:29:02 +0000 Subject: [PATCH] [PEx] Experimenting with while and receive in IR --- .../Backend/PExplicit/TransformASTPass.cs | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/Src/PCompiler/CompilerCore/Backend/PExplicit/TransformASTPass.cs b/Src/PCompiler/CompilerCore/Backend/PExplicit/TransformASTPass.cs index 5c699dd2c..65b3f7304 100644 --- a/Src/PCompiler/CompilerCore/Backend/PExplicit/TransformASTPass.cs +++ b/Src/PCompiler/CompilerCore/Backend/PExplicit/TransformASTPass.cs @@ -720,59 +720,59 @@ static private IPStmt HandleReceives(IPStmt statement, Function function, Machin case WhileStmt loop: if (CanReceive(loop.Body)) { - throw new NotImplementedException($"Receive in a while statement is not yet supported, found in {machine.Name}"); - // // turn the while statement into a recursive function - // var whileName = $"while_{whileNumber}"; - // whileNumber++; - // var rec = new WhileFunction(whileName, loop.SourceLocation); - // rec.Owner = function.Owner; - // rec.ParentFunction = function; - // foreach (var param in function.Signature.Parameters) rec.AddParameter(param); - // var newVarMap = new Dictionary(); - // foreach (var local in function.LocalVariables) - // { - // var machineVar = new Variable($"{whileName}_{local.Name}", local.SourceLocation, local.Role); - // machineVar.Type = local.Type; - // machine.AddField(machineVar); - // newVarMap.Add(local, machineVar); - // } - // foreach (var i in function.CreatesInterfaces) rec.AddCreatesInterface(i); - // rec.CanChangeState = function.CanChangeState; - // rec.CanRaiseEvent = function.CanRaiseEvent; - // rec.CanReceive = function.CanReceive; - // rec.IsNondeterministic = function.IsNondeterministic; - // // make while loop body - // var loopBody = new List(); - // var bodyEnumerator = loop.Body.Statements.GetEnumerator(); - // while (bodyEnumerator.MoveNext()) - // { - // var stmt = bodyEnumerator.Current; - // var replaceBreak = ReplaceBreaks(stmt, afterStmts); - // if (replaceBreak != null) { - // loopBody.Add(ReplaceVars(replaceBreak, newVarMap)); - // } - // } - // var recArgs = new List(); - // foreach (var param in rec.Signature.Parameters) - // { - // recArgs.Add(new VariableAccessExpr(rec.SourceLocation, param)); - // } - // // call the function - // var recCall = new FunCallStmt(loop.SourceLocation, rec, recArgs); - // loopBody.Add(recCall); - // rec.AddCallee(rec); - // loopBody = new List(((CompoundStmt) HandleReceives(new CompoundStmt(rec.SourceLocation, loopBody), rec, machine)).Statements); - // rec.Body = new CompoundStmt(rec.SourceLocation, loopBody); - // if (machine != null) machine.AddMethod(rec); - // // assign local variables - // foreach (var local in function.LocalVariables) - // { - // result.Add(new AssignStmt(local.SourceLocation, new VariableAccessExpr(local.SourceLocation, newVarMap[local]), new VariableAccessExpr(local.SourceLocation, local))); - // } - // // replace the while statement with a function call - // result.Add(recCall); - // result.Add(new ReturnStmt(loop.SourceLocation, null)); - // function.AddCallee(rec); + // throw new NotImplementedException($"Receive in a while statement is not yet supported, found in {machine.Name}"); + // turn the while statement into a recursive function + var whileName = $"while_{whileNumber}"; + whileNumber++; + var rec = new WhileFunction(whileName, loop.SourceLocation); + rec.Owner = function.Owner; + rec.ParentFunction = function; + foreach (var param in function.Signature.Parameters) rec.AddParameter(param); + var newVarMap = new Dictionary(); + foreach (var local in function.LocalVariables) + { + var machineVar = new Variable($"{whileName}_{local.Name}", local.SourceLocation, local.Role); + machineVar.Type = local.Type; + machine.AddField(machineVar); + newVarMap.Add(local, machineVar); + } + foreach (var i in function.CreatesInterfaces) rec.AddCreatesInterface(i); + rec.CanChangeState = function.CanChangeState; + rec.CanRaiseEvent = function.CanRaiseEvent; + rec.CanReceive = function.CanReceive; + rec.IsNondeterministic = function.IsNondeterministic; + // make while loop body + var loopBody = new List(); + var bodyEnumerator = loop.Body.Statements.GetEnumerator(); + while (bodyEnumerator.MoveNext()) + { + var stmt = bodyEnumerator.Current; + var replaceBreak = ReplaceBreaks(stmt, afterStmts); + if (replaceBreak != null) { + loopBody.Add(ReplaceVars(replaceBreak, newVarMap)); + } + } + var recArgs = new List(); + foreach (var param in rec.Signature.Parameters) + { + recArgs.Add(new VariableAccessExpr(rec.SourceLocation, param)); + } + // call the function + var recCall = new FunCallStmt(loop.SourceLocation, rec, recArgs); + loopBody.Add(recCall); + rec.AddCallee(rec); + loopBody = new List(((CompoundStmt) HandleReceives(new CompoundStmt(rec.SourceLocation, loopBody), rec, machine)).Statements); + rec.Body = new CompoundStmt(rec.SourceLocation, loopBody); + if (machine != null) machine.AddMethod(rec); + // assign local variables + foreach (var local in function.LocalVariables) + { + result.Add(new AssignStmt(local.SourceLocation, new VariableAccessExpr(local.SourceLocation, newVarMap[local]), new VariableAccessExpr(local.SourceLocation, local))); + } + // replace the while statement with a function call + result.Add(recCall); + result.Add(new ReturnStmt(loop.SourceLocation, null)); + function.AddCallee(rec); } else {