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));
        }
Beispiel #2
0
 public override object VisitAssignStmt(PParser.AssignStmtContext context)
 {
     return(null);
 }