Esempio n. 1
0
 public override IPStmt VisitPopStmt(PParser.PopStmtContext context)
 {
     method.CanChangeState = true;
     if (method.Role.HasFlag(FunctionRole.TransitionFunction))
     {
         throw handler.ChangedStateMidTransition(context, method);
     }
     return(new PopStmt(context));
 }
Esempio n. 2
0
        public static Scope AnalyzeCompilationUnit(ITranslationErrorHandler handler, params PParser.ProgramContext[] programUnits)
        {
            // Step 1: Build the global scope of declarations
            Scope globalScope = BuildGlobalScope(handler, programUnits);

            // Step 2: Validate machine specifications
            foreach (Machine machine in globalScope.Machines)
            {
                Validator.ValidateMachine(handler, machine);
            }

            // Step 3: Fill function bodies
            List <Function> allFunctions = AllFunctions(globalScope).ToList();

            foreach (Function machineFunction in allFunctions)
            {
                FunctionBodyVisitor.PopulateMethod(handler, machineFunction);
            }

            // Step 4: Propagate purity properties
            ApplyPropagations(allFunctions,
                              CreatePropagation(fn => fn.CanCommunicate, (fn, value) => fn.CanCommunicate = value,
                                                true),
                              CreatePropagation(fn => fn.CanChangeState, (fn, value) => fn.CanChangeState = value,
                                                true));

            // Step 5: Verify purity invariants
            foreach (Function machineFunction in allFunctions)
            {
                if (machineFunction.Owner?.IsSpec == true && machineFunction.IsNondeterministic == true)
                {
                    throw handler.NonDeterministicFunctionInSpecMachine(machineFunction);
                }
                if (machineFunction.CanChangeState == true &&
                    (machineFunction.Role.HasFlag(FunctionRole.TransitionFunction) ||
                     machineFunction.Role.HasFlag(FunctionRole.ExitHandler)))
                {
                    throw handler.ChangedStateMidTransition(machineFunction.SourceLocation, machineFunction);
                }
            }

            // Step 6: Check linear type ownership
            LinearTypeChecker.AnalyzeMethods(handler, allFunctions);

            return(globalScope);
        }
Esempio n. 3
0
        public override IPStmt VisitPopStmt(PParser.PopStmtContext context)
        {
            if (machine?.IsSpec == true)
            {
                throw handler.IllegalMonitorOperation(context, context.POP().Symbol, machine);
            }

            if (!method.Signature.ReturnType.IsSameTypeAs(PrimitiveType.Null))
            {
                throw handler.PopInNonVoidFunction(context);
            }

            method.CanChangeState = true;
            if (method.Role.HasFlag(FunctionRole.TransitionFunction))
            {
                throw handler.ChangedStateMidTransition(context, method);
            }

            return(new PopStmt(context));
        }
Esempio n. 4
0
        public static Scope AnalyzeCompilationUnit(ITranslationErrorHandler handler,
                                                   params PParser.ProgramContext[] programUnits)
        {
            // Step 1: Build the global scope of declarations
            var globalScope = BuildGlobalScope(handler, programUnits);

            // Step 2: Validate machine specifications
            foreach (var machine in globalScope.Machines)
            {
                MachineChecker.Validate(handler, machine);
            }

            // Step 3: Fill function bodies
            var allFunctions = globalScope.GetAllMethods().ToList();

            foreach (var machineFunction in allFunctions)
            {
                FunctionBodyVisitor.PopulateMethod(handler, machineFunction);
                FunctionValidator.CheckAllPathsReturn(handler, machineFunction);
            }

            // Step 2: Validate no static handlers
            foreach (var machine in globalScope.Machines)
            {
                MachineChecker.ValidateNoStaticHandlers(handler, machine);
            }

            // Step 4: Propagate purity properties
            ApplyPropagations(allFunctions,
                              CreatePropagation(fn => fn.CanRaiseEvent, (fn, value) => fn.CanRaiseEvent = value,
                                                true),
                              CreatePropagation(fn => fn.CanReceive, (fn, value) => fn.CanReceive = value,
                                                true),
                              CreatePropagation(fn => fn.CanChangeState, (fn, value) => fn.CanChangeState = value,
                                                true));

            // Step 5: Verify capability restrictions
            foreach (var machineFunction in allFunctions)
            {
                // TODO: is this checked earlier?
                if (machineFunction.Owner?.IsSpec == true && machineFunction.IsNondeterministic == true)
                {
                    throw handler.NonDeterministicFunctionInSpecMachine(machineFunction);
                }

                if ((machineFunction.CanChangeState == true || machineFunction.CanRaiseEvent == true) &&
                    (machineFunction.Role.HasFlag(FunctionRole.TransitionFunction) ||
                     machineFunction.Role.HasFlag(FunctionRole.ExitHandler)))
                {
                    throw handler.ChangedStateMidTransition(machineFunction.SourceLocation, machineFunction);
                }
            }

            // Step 6: Check linear type ownership
            LinearTypeChecker.AnalyzeMethods(handler, allFunctions);

            // Step 7: Check control flow well-formedness
            ControlFlowChecker.AnalyzeMethods(handler, allFunctions);

            // Step 8: Infer the creates set for each machine.
            foreach (var machine in globalScope.Machines)
            {
                InferMachineCreates.Populate(machine, handler);
            }

            // Step 9: Fill the module expressions
            ModuleSystemDeclarations.PopulateAllModuleExprs(handler, globalScope);

            var moduleTypeChecker = new ModuleSystemTypeChecker(handler, globalScope);

            // Step 10: Check that all module expressions are well-formed
            foreach (var moduleExpr in AllModuleExprs(globalScope))
            {
                moduleTypeChecker.CheckWellFormedness(moduleExpr);
            }

            // Step 11: Check the test and implementation declarations
            foreach (var impl in globalScope.Implementations)
            {
                moduleTypeChecker.CheckImplementationDecl(impl);
            }
            foreach (var test in globalScope.SafetyTests)
            {
                moduleTypeChecker.CheckSafetyTest(test);
            }
            foreach (var test in globalScope.RefinementTests)
            {
                moduleTypeChecker.CheckRefinementTest(test);
            }

            return(globalScope);
        }