Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
0
        public override IPStmt VisitSendStmt(PParser.SendStmtContext context)
        {
            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 = (context.rvalueList()?.rvalue().Select(rv => exprVisitor.Visit(rv)) ??
                             Enumerable.Empty <IPExpr>()).ToArray();

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

            return(new SendStmt(context, machineExpr, evtExpr, args));
        }
Ejemplo n.º 3
0
        public override IPStmt VisitRaiseStmt(PParser.RaiseStmtContext context)
        {
            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);
            }

            method.CanCommunicate = true;
            method.CanChangeState = true;

            IPExpr[] args = (context.rvalueList()?.rvalue().Select(rv => exprVisitor.Visit(rv)) ??
                             Enumerable.Empty <IPExpr>()).ToArray();

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

            return(new RaiseStmt(context, evtExpr, args));
        }
Ejemplo n.º 4
0
 public MapAccessExpr(ParserRuleContext sourceLocation, IPExpr mapExpr, IPExpr indexExpr, PLanguageType type)
 {
     SourceLocation = sourceLocation;
     MapExpr        = mapExpr;
     IndexExpr      = indexExpr;
     Type           = type;
 }
Ejemplo n.º 5
0
        private (IPExpr, List <IPStmt>) SimplifyLvalue(IPExpr expr)
        {
            // TODO: I am suspicious.
            Antlr4.Runtime.ParserRuleContext location = expr.SourceLocation;
            PLanguageType type = expr.Type;

            switch (expr)
            {
            case MapAccessExpr mapAccessExpr:
                (IPExpr mapExpr, List <IPStmt> mapExprDeps)      = SimplifyLvalue(mapAccessExpr.MapExpr);
                (IExprTerm mapIndex, List <IPStmt> mapIndexDeps) = SimplifyExpression(mapAccessExpr.IndexExpr);
                return(new MapAccessExpr(location, mapExpr, mapIndex, type),
                       mapExprDeps.Concat(mapIndexDeps).ToList());

            case NamedTupleAccessExpr namedTupleAccessExpr:
                (IPExpr ntExpr, List <IPStmt> ntExprDeps) = SimplifyLvalue(namedTupleAccessExpr.SubExpr);
                return(new NamedTupleAccessExpr(location, ntExpr, namedTupleAccessExpr.Entry), ntExprDeps);

            case SeqAccessExpr seqAccessExpr:
                (IPExpr seqExpr, List <IPStmt> seqExprDeps)      = SimplifyLvalue(seqAccessExpr.SeqExpr);
                (IExprTerm seqIndex, List <IPStmt> seqIndexDeps) = SimplifyExpression(seqAccessExpr.IndexExpr);
                return(new SeqAccessExpr(location, seqExpr, seqIndex, type),
                       seqExprDeps.Concat(seqIndexDeps).ToList());

            case TupleAccessExpr tupleAccessExpr:
                (IPExpr tupExpr, List <IPStmt> tupExprDeps) = SimplifyLvalue(tupleAccessExpr.SubExpr);
                return(new TupleAccessExpr(location, tupExpr, tupleAccessExpr.FieldNo, type), tupExprDeps);

            case VariableAccessExpr variableAccessExpr:
                return(variableAccessExpr, new List <IPStmt>());

            default:
                throw new ArgumentOutOfRangeException(nameof(expr));
            }
        }
Ejemplo n.º 6
0
 public TupleAccessExpr(ParserRuleContext sourceLocation, IPExpr subExpr, int fieldNo, PLanguageType type)
 {
     SourceLocation = sourceLocation;
     SubExpr        = subExpr;
     FieldNo        = fieldNo;
     Type           = type;
 }
Ejemplo n.º 7
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));
        }
Ejemplo n.º 8
0
 public IfStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt thenBranch, IPStmt elseBranch)
 {
     SourceLocation = sourceLocation;
     Condition      = condition;
     ThenBranch     = CompoundStmt.FromStatement(thenBranch);
     ElseBranch     = elseBranch == null ? null : CompoundStmt.FromStatement(elseBranch);
 }
Ejemplo n.º 9
0
 public InsertStmt(ParserRuleContext sourceLocation, IPExpr variable, IPExpr index, IPExpr value)
 {
     SourceLocation = sourceLocation;
     Variable       = variable;
     Index          = index;
     Value          = value;
 }
Ejemplo n.º 10
0
        public override IPStmt VisitRaiseStmt(PParser.RaiseStmtContext context)
        {
            if (!method.Signature.ReturnType.IsSameTypeAs(PrimitiveType.Null))
            {
                throw handler.RaiseEventInNonVoidFunction(context);
            }

            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);
            }

            method.CanRaiseEvent = true;

            IPExpr[] 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));
        }
Ejemplo n.º 11
0
        public override IPStmt VisitAssertStmt(PParser.AssertStmtContext context)
        {
            IPExpr assertion = exprVisitor.Visit(context.assertion);

            if (!PrimitiveType.Bool.IsSameTypeAs(assertion.Type))
            {
                throw handler.TypeMismatch(context.assertion, assertion.Type, PrimitiveType.Bool);
            }
            IPExpr message;

            if (context.message == null)
            {
                message = new StringExpr(context, "", new List <IPExpr>());
            }
            else
            {
                message = exprVisitor.Visit(context.message);
                if (!message.Type.IsSameTypeAs(PrimitiveType.String))
                {
                    throw handler.TypeMismatch(context.message, message.Type, PrimitiveType.String);
                }
            }

            return(new AssertStmt(context, assertion, message));
        }
Ejemplo n.º 12
0
 public UnaryOpExpr(ParserRuleContext sourceLocation, UnaryOpType operation, IPExpr subExpr)
 {
     SourceLocation = sourceLocation;
     Operation      = operation;
     SubExpr        = subExpr;
     Type           = subExpr.Type;
 }
Ejemplo n.º 13
0
 public IfStmt(ParserRuleContext sourceLocation, IPExpr condition, IPStmt thenBranch, IPStmt elseBranch)
 {
     SourceLocation = sourceLocation;
     Condition      = condition;
     ThenBranch     = thenBranch;
     ElseBranch     = elseBranch;
 }
Ejemplo n.º 14
0
 public SetAccessExpr(ParserRuleContext sourceLocation, IPExpr setExpr, IPExpr indexExpr, PLanguageType type)
 {
     SourceLocation = sourceLocation;
     SetExpr        = setExpr;
     IndexExpr      = indexExpr;
     Type           = type;
 }
Ejemplo n.º 15
0
        public override IPStmt VisitRemoveStmt(PParser.RemoveStmtContext context)
        {
            IPExpr variable = exprVisitor.Visit(context.lvalue());
            IPExpr value    = exprVisitor.Visit(context.expr());

            if (PLanguageType.TypeIsOfKind(variable.Type, TypeKind.Sequence))
            {
                if (!PrimitiveType.Int.IsAssignableFrom(value.Type))
                {
                    throw handler.TypeMismatch(context.expr(), value.Type, PrimitiveType.Int);
                }
            }
            else if (PLanguageType.TypeIsOfKind(variable.Type, TypeKind.Map))
            {
                var map = (MapType)variable.Type.Canonicalize();
                if (!map.KeyType.IsAssignableFrom(value.Type))
                {
                    throw handler.TypeMismatch(context.expr(), value.Type, map.KeyType);
                }
            }
            else
            {
                throw handler.TypeMismatch(variable, TypeKind.Sequence, TypeKind.Map);
            }

            return(new RemoveStmt(context, variable, value));
        }
Ejemplo n.º 16
0
 public StringAssignStmt(ParserRuleContext sourceLocation, IPExpr location, string baseString, List <IPExpr> args)
 {
     SourceLocation = sourceLocation;
     Location       = location;
     BaseString     = baseString;
     Args           = args;
 }
Ejemplo n.º 17
0
 public SendStmt(ParserRuleContext sourceLocation, IPExpr machineExpr, IPExpr evt,
                 IReadOnlyList <IPExpr> arguments)
 {
     SourceLocation = sourceLocation;
     MachineExpr    = machineExpr;
     Evt            = evt;
     Arguments      = arguments;
 }
Ejemplo n.º 18
0
        public override IPStmt VisitPrintStmt(PParser.PrintStmtContext context)
        {
            IPExpr message = exprVisitor.Visit(context.message);

            if (!message.Type.IsSameTypeAs(PrimitiveType.String))
            {
                throw handler.TypeMismatch(context.message, message.Type, PrimitiveType.String);
            }
            return(new PrintStmt(context, message));
        }
Ejemplo n.º 19
0
        public override IPStmt VisitReturnStmt(PParser.ReturnStmtContext context)
        {
            IPExpr        returnValue = context.expr() == null ? null : exprVisitor.Visit(context.expr());
            PLanguageType returnType  = returnValue?.Type ?? PrimitiveType.Null;

            if (!method.Signature.ReturnType.IsAssignableFrom(returnType))
            {
                throw handler.TypeMismatch(context, returnType, method.Signature.ReturnType);
            }
            return(new ReturnStmt(context, returnValue));
        }
Ejemplo n.º 20
0
        public override IPStmt VisitAssertStmt(PParser.AssertStmtContext context)
        {
            IPExpr assertion = exprVisitor.Visit(context.expr());

            if (!PrimitiveType.Bool.IsSameTypeAs(assertion.Type))
            {
                throw handler.TypeMismatch(context.expr(), assertion.Type, PrimitiveType.Bool);
            }
            string message = context.StringLiteral()?.GetText() ?? "";

            return(new AssertStmt(context, assertion, message));
        }
Ejemplo n.º 21
0
        private (VariableAccessExpr, IPStmt) SaveInTemporary(IPExpr expr, PLanguageType tempType)
        {
            Antlr4.Runtime.ParserRuleContext location = expr.SourceLocation;
            Variable temp = function.Scope.Put($"$tmp{numTemp++}", location, VariableRole.Local | VariableRole.Temp);

            Debug.Assert(tempType.IsAssignableFrom(expr.Type));
            temp.Type = tempType;
            function.AddLocalVariable(temp);
            AssignStmt stmt = new AssignStmt(location, new VariableAccessExpr(location, temp), expr);

            return(new VariableAccessExpr(location, temp), stmt);
        }
Ejemplo n.º 22
0
        public override IPStmt VisitWhileStmt(PParser.WhileStmtContext context)
        {
            IPExpr condition = exprVisitor.Visit(context.expr());

            if (condition.Type != PrimitiveType.Bool)
            {
                throw handler.TypeMismatch(context.expr(), condition.Type, PrimitiveType.Bool);
            }
            IPStmt body = Visit(context.statement());

            return(new WhileStmt(context, condition, body));
        }
Ejemplo n.º 23
0
        public override IPStmt VisitIfStmt(PParser.IfStmtContext context)
        {
            IPExpr condition = exprVisitor.Visit(context.expr());

            if (condition.Type != PrimitiveType.Bool)
            {
                throw handler.TypeMismatch(context.expr(), condition.Type, PrimitiveType.Bool);
            }
            IPStmt thenBody = Visit(context.thenBranch);
            IPStmt elseBody = context.elseBranch == null ? new NoStmt(context) : Visit(context.elseBranch);

            return(new IfStmt(context, condition, thenBody, elseBody));
        }
Ejemplo n.º 24
0
        public override IPStmt VisitInsertStmt(PParser.InsertStmtContext context)
        {
            IPExpr variable = exprVisitor.Visit(context.lvalue());
            IPExpr index    = exprVisitor.Visit(context.expr());
            IPExpr value    = exprVisitor.Visit(context.rvalue());

            // Check linear types
            var valueIsInvariant = false;

            if (value is ILinearRef linearRef)
            {
                valueIsInvariant = linearRef.LinearType.Equals(LinearType.Swap);
            }

            // Check subtyping
            PLanguageType keyType   = index.Type;
            PLanguageType valueType = value.Type;

            PLanguageType expectedKeyType;
            PLanguageType expectedValueType;

            switch (variable.Type.Canonicalize())
            {
            case SequenceType sequenceType:
                expectedKeyType   = PrimitiveType.Int;
                expectedValueType = sequenceType.ElementType;
                break;

            case MapType mapType:
                expectedKeyType   = mapType.KeyType;
                expectedValueType = mapType.ValueType;
                break;

            default:
                throw handler.TypeMismatch(variable, TypeKind.Sequence, TypeKind.Map);
            }

            if (!expectedKeyType.IsAssignableFrom(keyType))
            {
                throw handler.TypeMismatch(context.rvalue(), keyType, expectedKeyType);
            }

            if (valueIsInvariant && !expectedValueType.IsSameTypeAs(valueType) ||
                !valueIsInvariant && !expectedValueType.IsAssignableFrom(valueType))
            {
                throw handler.TypeMismatch(context.rvalue(), valueType, expectedValueType);
            }

            return(new InsertStmt(context, variable, index, value));
        }
Ejemplo n.º 25
0
 public static void CheckArgument(ITranslationErrorHandler handler, ParserRuleContext context,
                                  PLanguageType argumentType, IPExpr arg)
 {
     if (arg is ILinearRef linearRef)
     {
         if (linearRef.LinearType.Equals(LinearType.Swap) && !arg.Type.IsSameTypeAs(argumentType))
         {
             throw handler.TypeMismatch(context, arg.Type, argumentType);
         }
     }
     if (!argumentType.IsAssignableFrom(arg.Type))
     {
         throw handler.TypeMismatch(context, arg.Type, argumentType);
     }
 }
Ejemplo n.º 26
0
 public BinOpExpr(ParserRuleContext sourceLocation, BinOpType operation, IPExpr lhs, IPExpr rhs)
 {
     SourceLocation = sourceLocation;
     Operation      = operation;
     Lhs            = lhs;
     Rhs            = rhs;
     if (IsArithmetic(operation))
     {
         Debug.Assert(Lhs.Type.IsSameTypeAs(Rhs.Type));
         Type = Lhs.Type;
     }
     else
     {
         Type = PrimitiveType.Bool;
     }
 }
Ejemplo n.º 27
0
        public override IPStmt VisitAssignStmt(PParser.AssignStmtContext context)
        {
            IPExpr variable = exprVisitor.Visit(context.lvalue());
            IPExpr value    = exprVisitor.Visit(context.rvalue());

            // If we're doing a move/swap assignment
            if (value is ILinearRef linearRef)
            {
                Variable refVariable = linearRef.Variable;
                switch (linearRef.LinearType)
                {
                case LinearType.Move:
                    // Moved values must be subtypes of their destinations
                    if (!variable.Type.IsAssignableFrom(refVariable.Type))
                    {
                        throw handler.TypeMismatch(context.rvalue(), refVariable.Type, variable.Type);
                    }

                    return(new MoveAssignStmt(context, variable, refVariable));

                case LinearType.Swap:
                    // Within a function, swaps must only be subtyped in either direction
                    // the actual types are checked at runtime. This is to allow swapping
                    // with the `any` type.
                    if (!variable.Type.IsAssignableFrom(refVariable.Type) &&
                        !refVariable.Type.IsAssignableFrom(variable.Type))
                    {
                        throw handler.TypeMismatch(context.rvalue(), refVariable.Type, variable.Type);
                    }

                    return(new SwapAssignStmt(context, variable, refVariable));

                default:
                    throw handler.InternalError(linearRef.SourceLocation,
                                                new ArgumentOutOfRangeException(nameof(context)));
                }
            }

            // If this is a value assignment, we just need subtyping
            if (!variable.Type.IsAssignableFrom(value.Type))
            {
                throw handler.TypeMismatch(context.rvalue(), value.Type, variable.Type);
            }

            return(new AssignStmt(context, variable, value));
        }
Ejemplo n.º 28
0
        public override IPStmt VisitGotoStmt(PParser.GotoStmtContext context)
        {
            PParser.StateNameContext stateNameContext = context.stateName();
            string          stateName = stateNameContext.state.GetText();
            IStateContainer current   = machine;

            foreach (PParser.IdenContext token in stateNameContext._groups)
            {
                current = current?.GetGroup(token.GetText());
                if (current == null)
                {
                    throw handler.MissingDeclaration(token, "group", token.GetText());
                }
            }
            State state = current?.GetState(stateName);

            if (state == null)
            {
                throw handler.MissingDeclaration(stateNameContext.state, "state", stateName);
            }
            IPExpr        payload      = null;
            PLanguageType expectedType =
                state.Entry.Signature.ParameterTypes.ElementAtOrDefault(0) ?? PrimitiveType.Null;

            if (context.rvalueList()?.rvalue() is PParser.RvalueContext[] rvalues)
            {
                if (rvalues.Length == 1)
                {
                    payload = exprVisitor.Visit(rvalues[0]);
                }
                else
                {
                    IPExpr[] tupleFields = rvalues.Select(exprVisitor.Visit).ToArray();
                    payload = new UnnamedTupleExpr(context, tupleFields,
                                                   new TupleType(tupleFields.Select(f => f.Type).ToList()));
                }
            }
            PLanguageType payloadType = payload?.Type ?? PrimitiveType.Null;

            if (!expectedType.IsAssignableFrom(payloadType))
            {
                throw handler.TypeMismatch(context, payloadType, expectedType);
            }
            return(new GotoStmt(context, state, payload));
        }
Ejemplo n.º 29
0
        public override IPStmt VisitAnnounceStmt(PParser.AnnounceStmtContext context)
        {
            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 = (context.rvalueList()?.rvalue().Select(rv => exprVisitor.Visit(rv)) ??
                                  Enumerable.Empty <IPExpr>()).ToList();

            return(new AnnounceStmt(context, evtExpr, args.Count == 0 ? null : args[0]));
        }
Ejemplo n.º 30
0
        private (IExprTerm, List <IPStmt>) SimplifyRvalue(IPExpr expr)
        {
            // TODO: I am suspicious.
            Antlr4.Runtime.ParserRuleContext location = expr.SourceLocation;
            PLanguageType type = expr.Type;

#pragma warning disable CCN0002 // Non exhaustive patterns in switch block
            switch (expr)
            {
            case NamedTupleAccessExpr _:
            case SeqAccessExpr _:
            case TupleAccessExpr _:
            case MapAccessExpr _:
                (IExprTerm dataTypeItem, List <IPStmt> dataTypeItemDeps)      = SimplifyExpression(expr);
                (IExprTerm cloneddataTypeItem, IPStmt cloneddataTypeItemDeps) = SaveInTemporary(new CloneExpr(dataTypeItem));
                return(cloneddataTypeItem, dataTypeItemDeps.Append(cloneddataTypeItemDeps).ToList());

            default:
                return(SimplifyExpression(expr));
            }
#pragma warning restore CCN0002 // Non exhaustive patterns in switch block
        }