예제 #1
0
        public override IPStmt VisitPrintStmt(PParser.PrintStmtContext context)
        {
            string message = context.StringLiteral().GetText();

            message = message.Substring(1, message.Length - 2); // strip beginning / end double quote
            int numNecessaryArgs = TypeCheckingUtils.PrintStmtNumArgs(message);

            if (numNecessaryArgs == -1)
            {
                throw handler.InvalidPrintFormat(context, context.StringLiteral().Symbol);
            }

            List <IPExpr> args = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToList();

            foreach (IPExpr arg in args)
            {
                if (arg is LinearAccessRefExpr)
                {
                    throw handler.PrintStmtLinearArgument(arg.SourceLocation);
                }
            }

            if (args.Count != numNecessaryArgs)
            {
                throw handler.IncorrectArgumentCount(context, args.Count, numNecessaryArgs);
            }

            return(new PrintStmt(context, message, args));
        }
예제 #2
0
        public override IPExpr VisitFormatedString([NotNull] PParser.FormatedStringContext context)
        {
            string baseString = context.StringLiteral().GetText();

            baseString = baseString.Substring(1, baseString.Length - 2); // strip beginning / end double quote
            int numNecessaryArgs = TypeCheckingUtils.PrintStmtNumArgs(baseString);

            if (numNecessaryArgs == -1)
            {
                throw handler.InvalidStringExprFormat(context, context.StringLiteral().Symbol);
            }

            List <IPExpr> args = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), this).ToList();

            foreach (IPExpr arg in args)
            {
                if (arg is LinearAccessRefExpr)
                {
                    throw handler.StringAssignStmtLinearArgument(arg.SourceLocation);
                }
            }

            if (args.Count != numNecessaryArgs)
            {
                throw handler.IncorrectArgumentCount(context, args.Count, numNecessaryArgs);
            }

            return(new StringExpr(context, baseString, args));
        }
예제 #3
0
        public override IPStmt VisitSendStmt(PParser.SendStmtContext context)
        {
            if (machine?.IsSpec == true)
            {
                throw handler.IllegalMonitorOperation(context, context.SEND().Symbol, machine);
            }

            IPExpr machineExpr = exprVisitor.Visit(context.machine);

            if (!PrimitiveType.Machine.IsAssignableFrom(machineExpr.Type))
            {
                throw handler.TypeMismatch(context.machine, machineExpr.Type, PrimitiveType.Machine);
            }

            IPExpr evtExpr = exprVisitor.Visit(context.@event);

            if (IsDefinitelyNullEvent(evtExpr))
            {
                throw handler.EmittedNullEvent(evtExpr);
            }

            if (!PrimitiveType.Event.IsAssignableFrom(evtExpr.Type))
            {
                throw handler.TypeMismatch(context.@event, evtExpr.Type, PrimitiveType.Event);
            }

            IPExpr[] args = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToArray();

            if (evtExpr is EventRefExpr eventRef)
            {
                TypeCheckingUtils.ValidatePayloadTypes(handler, context, eventRef.Value.PayloadType, args);
            }

            return(new SendStmt(context, machineExpr, evtExpr, args));
        }
예제 #4
0
        public override IPStmt VisitFunCallStmt(PParser.FunCallStmtContext context)
        {
            string        funName  = context.fun.GetText();
            List <IPExpr> argsList = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToList();

            if (!table.Lookup(funName, out Function fun))
            {
                throw handler.MissingDeclaration(context.fun, "function or function prototype", funName);
            }

            if (fun.Signature.Parameters.Count != argsList.Count)
            {
                throw handler.IncorrectArgumentCount((ParserRuleContext)context.rvalueList() ?? context,
                                                     argsList.Count,
                                                     fun.Signature.Parameters.Count);
            }

            foreach (Tuple <Variable, IPExpr> pair in fun.Signature.Parameters.Zip(argsList, Tuple.Create))
            {
                TypeCheckingUtils.CheckArgument(handler, context, pair.Item1.Type, pair.Item2);
            }

            method.AddCallee(fun);
            return(new FunCallStmt(context, fun, argsList));
        }
예제 #5
0
        public override IPStmt VisitRaiseStmt(PParser.RaiseStmtContext context)
        {
            var evtExpr = exprVisitor.Visit(context.expr());

            if (IsDefinitelyNullEvent(evtExpr))
            {
                throw handler.EmittedNullEvent(evtExpr);
            }

            if (!PrimitiveType.Event.IsAssignableFrom(evtExpr.Type))
            {
                throw handler.TypeMismatch(context.expr(), evtExpr.Type, PrimitiveType.Event);
            }

            method.CanRaiseEvent = true;

            var args = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToArray();

            if (evtExpr is EventRefExpr eventRef)
            {
                TypeCheckingUtils.ValidatePayloadTypes(handler, context, eventRef.Value.PayloadType, args);
            }

            return(new RaiseStmt(context, evtExpr, args));
        }
예제 #6
0
        public override IPStmt VisitStringAssignStmt(PParser.StringAssignStmtContext context)
        {
            IPExpr variable   = exprVisitor.Visit(context.lvalue());
            string baseString = context.StringLiteral().GetText();

            baseString = baseString.Substring(1, baseString.Length - 2); // strip beginning / end double quote
            int numNecessaryArgs = TypeCheckingUtils.PrintStmtNumArgs(baseString);

            if (numNecessaryArgs == -1)
            {
                throw handler.InvalidStringAssignFormat(context, context.StringLiteral().Symbol);
            }

            List <IPExpr> args = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToList();

            foreach (IPExpr arg in args)
            {
                if (arg is LinearAccessRefExpr)
                {
                    throw handler.StringAssignStmtLinearArgument(arg.SourceLocation);
                }
            }

            if (args.Count != numNecessaryArgs)
            {
                throw handler.IncorrectArgumentCount(context, args.Count, numNecessaryArgs);
            }

            if (variable.Type != PrimitiveType.String)
            {
                throw handler.TypeMismatch(context, variable.Type, PrimitiveType.String);
            }

            return(new StringAssignStmt(context, variable, baseString, args));
        }
예제 #7
0
        public override IPStmt VisitGotoStmt(PParser.GotoStmtContext context)
        {
            var             stateNameContext = context.stateName();
            var             stateName        = stateNameContext.state.GetText();
            IStateContainer current          = machine;

            foreach (var token in stateNameContext._groups)
            {
                current = current?.GetGroup(token.GetText());
                if (current == null)
                {
                    throw handler.MissingDeclaration(token, "group", token.GetText());
                }
            }

            var state = current?.GetState(stateName);

            if (state == null)
            {
                throw handler.MissingDeclaration(stateNameContext.state, "state", stateName);
            }

            var expectedType =
                state.Entry?.Signature.ParameterTypes.ElementAtOrDefault(0) ?? PrimitiveType.Null;
            var rvaluesList = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToArray();

            foreach (var arg in rvaluesList)
            {
                if (arg is LinearAccessRefExpr linearArg && linearArg.LinearType == LinearType.Swap)
                {
                    throw handler.InvalidSwap(linearArg, "swap not allowed on goto");
                }
            }

            IPExpr payload;

            if (rvaluesList.Length == 0)
            {
                payload = null;
            }
            else if (rvaluesList.Length == 1)
            {
                payload = rvaluesList[0];
            }
            else
            {
                payload = new UnnamedTupleExpr(context, rvaluesList);
            }

            var payloadType = payload?.Type ?? PrimitiveType.Null;

            if (!expectedType.IsAssignableFrom(payloadType))
            {
                throw handler.TypeMismatch(context, payloadType, expectedType);
            }

            method.CanChangeState = true;
            return(new GotoStmt(context, state, payload));
        }
예제 #8
0
        public override IPStmt VisitCtorStmt(PParser.CtorStmtContext context)
        {
            string interfaceName = context.iden().GetText();

            if (!table.Lookup(interfaceName, out Interface targetInterface))
            {
                throw handler.MissingDeclaration(context.iden(), "interface", interfaceName);
            }

            List <IPExpr> args = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToList();

            TypeCheckingUtils.ValidatePayloadTypes(handler, context, targetInterface.PayloadType, args);
            return(new CtorStmt(context, targetInterface, args));
        }
예제 #9
0
        public override IPExpr VisitFunCallExpr(PParser.FunCallExprContext context)
        {
            string funName = context.fun.GetText();

            if (!table.Lookup(funName, out Function function))
            {
                throw handler.MissingDeclaration(context.fun, "function", funName);
            }

            // Check the arguments
            IPExpr[]        arguments       = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), this).ToArray();
            ISet <Variable> linearVariables = new HashSet <Variable>();

            if (function.Signature.Parameters.Count != arguments.Length)
            {
                throw handler.IncorrectArgumentCount(context, arguments.Length, function.Signature.Parameters.Count);
            }

            for (int i = 0; i < arguments.Length; i++)
            {
                IPExpr        argument  = arguments[i];
                PLanguageType paramType = function.Signature.Parameters[i].Type;
                if (!paramType.IsAssignableFrom(argument.Type))
                {
                    throw handler.TypeMismatch(context.rvalueList().rvalue(i), argument.Type, paramType);
                }

                if (argument is ILinearRef linearRef)
                {
                    if (linearRef.LinearType == LinearType.Swap && !linearRef.Type.IsSameTypeAs(paramType))
                    {
                        throw handler.TypeMismatch(context, linearRef.Type, paramType);
                    }

                    if (linearVariables.Contains(linearRef.Variable))
                    {
                        throw handler.RelinquishedWithoutOwnership(linearRef);
                    }

                    linearVariables.Add(linearRef.Variable);
                }
            }

            method.AddCallee(function);
            return(new FunCallExpr(context, function, arguments));
        }
예제 #10
0
        public override IPExpr VisitCtorExpr(PParser.CtorExprContext context)
        {
            string interfaceName = context.interfaceName.GetText();

            if (!table.Lookup(interfaceName, out Interface @interface))
            {
                throw handler.MissingDeclaration(context.interfaceName, "interface", interfaceName);
            }

            if (method.Owner?.IsSpec == true)
            {
                throw handler.IllegalMonitorOperation(context, context.NEW().Symbol, method.Owner);
            }

            IPExpr[] arguments = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), this).ToArray();
            TypeCheckingUtils.ValidatePayloadTypes(handler, context, @interface.PayloadType, arguments);
            return(new CtorExpr(context, @interface, arguments));
        }
예제 #11
0
        public override IPStmt VisitAnnounceStmt(PParser.AnnounceStmtContext context)
        {
            if (machine?.IsSpec == true)
            {
                throw handler.IllegalMonitorOperation(context, context.ANNOUNCE().Symbol, machine);
            }

            IPExpr evtExpr = exprVisitor.Visit(context.expr());

            if (IsDefinitelyNullEvent(evtExpr))
            {
                throw handler.EmittedNullEvent(evtExpr);
            }

            if (!PrimitiveType.Event.IsAssignableFrom(evtExpr.Type))
            {
                throw handler.TypeMismatch(context.expr(), evtExpr.Type, PrimitiveType.Event);
            }

            List <IPExpr> args = TypeCheckingUtils.VisitRvalueList(context.rvalueList(), exprVisitor).ToList();

            return(new AnnounceStmt(context, evtExpr, args.Count == 0 ? null : args[0]));
        }