/Src/PCompiler/CompilerCore/TypeChecker/InferMachineCreates.cs

https://github.com/p-org/P · C# · 194 lines · 148 code · 46 blank · 0 comment · 3 complexity · a7a217596504002abdab9a2057d79c71 MD5 · raw file

  1. using Plang.Compiler.Backend.ASTExt;
  2. using Plang.Compiler.TypeChecker.AST;
  3. using Plang.Compiler.TypeChecker.AST.Declarations;
  4. using Plang.Compiler.TypeChecker.AST.Expressions;
  5. using Plang.Compiler.TypeChecker.AST.Statements;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. namespace Plang.Compiler.TypeChecker
  10. {
  11. public static class InferMachineCreates
  12. {
  13. public static void Populate(Machine machine, ITranslationErrorHandler handler)
  14. {
  15. InterfaceSet interfaces = new InterfaceSet();
  16. foreach (Function function in machine.Methods)
  17. {
  18. interfaces.AddInterfaces(InferCreates(function, handler));
  19. }
  20. machine.Creates = interfaces;
  21. }
  22. private static IEnumerable<Interface> InferCreates(IPAST tree, ITranslationErrorHandler handler)
  23. {
  24. #pragma warning disable CCN0002 // Non exhaustive patterns in switch block
  25. switch (tree)
  26. {
  27. case Function function:
  28. if (function.IsForeign)
  29. {
  30. return function.CreatesInterfaces;
  31. }
  32. return InferCreates(function.Body, handler);
  33. case AddStmt addStmt:
  34. return InferCreatesForExpr(addStmt.Variable, handler)
  35. .Union(InferCreatesForExpr(addStmt.Value, handler));
  36. case AnnounceStmt announce:
  37. return InferCreatesForExpr(announce.PEvent, handler)
  38. .Union(InferCreatesForExpr(announce.Payload, handler));
  39. case AssertStmt assertStmt:
  40. return InferCreatesForExpr(assertStmt.Assertion, handler)
  41. .Union(InferCreatesForExpr(assertStmt.Message, handler));
  42. case AssignStmt assignStmt:
  43. return InferCreatesForExpr(assignStmt.Location, handler)
  44. .Union(InferCreatesForExpr(assignStmt.Value, handler));
  45. case CompoundStmt compoundStmt:
  46. return compoundStmt.Statements.SelectMany(tree1 => InferCreates(tree1, handler));
  47. case CtorStmt ctorStmt:
  48. Interface[] res = new[] { ctorStmt.Interface };
  49. return res.Union(ctorStmt.Arguments.SelectMany(expr => InferCreatesForExpr(expr, handler)));
  50. case FunCallStmt funCallStmt:
  51. return InferCreates(funCallStmt.Function, handler)
  52. .Union(funCallStmt.ArgsList.SelectMany(expr => InferCreatesForExpr(expr, handler)));
  53. case GotoStmt gotoStmt:
  54. return InferCreatesForExpr(gotoStmt.Payload, handler);
  55. case IfStmt ifStmt:
  56. return InferCreatesForExpr(ifStmt.Condition, handler)
  57. .Union(InferCreates(ifStmt.ThenBranch, handler))
  58. .Union(InferCreates(ifStmt.ElseBranch, handler));
  59. case InsertStmt insertStmt:
  60. return InferCreatesForExpr(insertStmt.Variable, handler)
  61. .Union(InferCreatesForExpr(insertStmt.Index, handler))
  62. .Union(InferCreatesForExpr(insertStmt.Value, handler));
  63. case MoveAssignStmt moveAssignStmt:
  64. return InferCreatesForExpr(moveAssignStmt.ToLocation, handler);
  65. case NoStmt _:
  66. return Enumerable.Empty<Interface>();
  67. case PopStmt _:
  68. return Enumerable.Empty<Interface>();
  69. case PrintStmt printStmt:
  70. return InferCreatesForExpr(printStmt.Message, handler);
  71. case RaiseStmt raiseStmt:
  72. return InferCreatesForExpr(raiseStmt.PEvent, handler)
  73. .Union(raiseStmt.Payload.SelectMany(expr => InferCreatesForExpr(expr, handler)));
  74. case ReceiveStmt receiveStmt:
  75. return receiveStmt.Cases.SelectMany(x => InferCreates(x.Value, handler));
  76. case RemoveStmt removeStmt:
  77. return InferCreatesForExpr(removeStmt.Variable, handler)
  78. .Union(InferCreatesForExpr(removeStmt.Value, handler));
  79. case ReturnStmt returnStmt:
  80. return InferCreatesForExpr(returnStmt.ReturnValue, handler);
  81. case BreakStmt breakStmt:
  82. return Enumerable.Empty<Interface>();
  83. case ContinueStmt continueStmt:
  84. return Enumerable.Empty<Interface>();
  85. case SendStmt sendStmt:
  86. return InferCreatesForExpr(sendStmt.MachineExpr, handler)
  87. .Union(InferCreatesForExpr(sendStmt.Evt, handler))
  88. .Union(sendStmt.Arguments.SelectMany(expr => InferCreatesForExpr(expr, handler)));
  89. case SwapAssignStmt swapAssignStmt:
  90. return InferCreatesForExpr(swapAssignStmt.NewLocation, handler);
  91. case WhileStmt whileStmt:
  92. return InferCreatesForExpr(whileStmt.Condition, handler)
  93. .Union(InferCreates(whileStmt.Body, handler));
  94. default:
  95. throw handler.InternalError(tree.SourceLocation, new ArgumentOutOfRangeException(nameof(tree)));
  96. }
  97. #pragma warning restore CCN0002 // Non exhaustive patterns in switch block
  98. }
  99. private static IEnumerable<Interface> InferCreatesForExpr(IPExpr expr, ITranslationErrorHandler handler)
  100. {
  101. switch (expr)
  102. {
  103. case BinOpExpr binOpExpr:
  104. return InferCreatesForExpr(binOpExpr.Lhs, handler)
  105. .Union(InferCreatesForExpr(binOpExpr.Rhs, handler));
  106. case CastExpr castExpr:
  107. return InferCreatesForExpr(castExpr.SubExpr, handler);
  108. case CoerceExpr coerceExpr:
  109. return InferCreatesForExpr(coerceExpr.SubExpr, handler);
  110. case ContainsExpr containsKeyExpr:
  111. return InferCreatesForExpr(containsKeyExpr.Item, handler)
  112. .Union(InferCreatesForExpr(containsKeyExpr.Collection, handler));
  113. case CloneExpr cloneExpr:
  114. return InferCreatesForExpr(cloneExpr.Term, handler);
  115. case CtorExpr ctorExpr:
  116. Interface[] res = new[] { ctorExpr.Interface };
  117. return res.Union(ctorExpr.Arguments.SelectMany(expr1 => InferCreatesForExpr(expr1, handler)));
  118. case FunCallExpr funCallExpr:
  119. return InferCreates(funCallExpr.Function, handler)
  120. .Union(funCallExpr.Arguments.SelectMany(expr1 => InferCreatesForExpr(expr1, handler)));
  121. case KeysExpr keysExpr:
  122. return InferCreatesForExpr(keysExpr.Expr, handler);
  123. case MapAccessExpr mapAccessExpr:
  124. return InferCreatesForExpr(mapAccessExpr.MapExpr, handler)
  125. .Union(InferCreatesForExpr(mapAccessExpr.IndexExpr, handler));
  126. case NamedTupleAccessExpr namedTupleAccessExpr:
  127. return InferCreatesForExpr(namedTupleAccessExpr.SubExpr, handler);
  128. case NamedTupleExpr namedTupleExpr:
  129. return namedTupleExpr.TupleFields.SelectMany(expr1 => InferCreatesForExpr(expr1, handler));
  130. case SeqAccessExpr seqAccessExpr:
  131. return InferCreatesForExpr(seqAccessExpr.SeqExpr, handler)
  132. .Union(InferCreatesForExpr(seqAccessExpr.IndexExpr, handler));
  133. case SizeofExpr sizeofExpr:
  134. return InferCreatesForExpr(sizeofExpr.Expr, handler);
  135. case TupleAccessExpr tupleAccessExpr:
  136. return InferCreatesForExpr(tupleAccessExpr.SubExpr, handler);
  137. case UnaryOpExpr unaryOpExpr:
  138. return InferCreatesForExpr(unaryOpExpr.SubExpr, handler);
  139. case UnnamedTupleExpr unnamedTupleExpr:
  140. return unnamedTupleExpr.TupleFields.SelectMany(expr1 => InferCreatesForExpr(expr1, handler));
  141. case ValuesExpr valuesExpr:
  142. return InferCreatesForExpr(valuesExpr.Expr, handler);
  143. default:
  144. return Enumerable.Empty<Interface>();
  145. }
  146. }
  147. }
  148. }