示例#1
0
        // Requires the binding has already been consumed
        private IStatementSyntax ParseRestOfVariableDeclaration(
            TextSpan binding,
            bool mutableBinding)
        {
            var         identifier       = Tokens.RequiredToken <IIdentifierToken>();
            var         name             = identifier.Value;
            ITypeSyntax?type             = null;
            bool        inferMutableType = false;

            if (Tokens.Accept <IColonToken>())
            {
                (type, inferMutableType) = ParseVariableDeclarationType();
            }

            IExpressionSyntax?initializer = null;

            if (Tokens.Accept <IEqualsToken>())
            {
                initializer = ParseExpression();
            }

            var semicolon = Tokens.Expect <ISemicolonToken>();
            var span      = TextSpan.Covering(binding, semicolon);

            return(new VariableDeclarationStatementSyntax(span,
                                                          mutableBinding, name, identifier.Span, type, inferMutableType, initializer));
        }
示例#2
0
        private ITypeSyntax ParseTypeWithCapability()
        {
            switch (Tokens.Current)
            {
            case IOwnedKeywordToken _:
                return(ParseTypeWithCapability <IOwnedKeywordToken>(Owned, OwnedMutable));

            case IIsolatedKeywordToken _:
                return(ParseTypeWithCapability <IIsolatedKeywordToken>(Isolated, IsolatedMutable));

            case IHeldKeywordToken _:
                return(ParseTypeWithCapability <IHeldKeywordToken>(Held, HeldMutable));

            case IMutableKeywordToken _:
            {
                var mutableKeyword = Tokens.RequiredToken <IMutableKeywordToken>();
                return(ParseMutableType(mutableKeyword));
            }

            case IIdKeywordToken _:
            {
                var mutableKeyword = Tokens.RequiredToken <IMutableKeywordToken>();
                var referent       = ParseBareType();
                var span           = TextSpan.Covering(mutableKeyword.Span, referent.Span);
                return(new CapabilityTypeSyntax(Identity, referent, span));
            }

            default:
                return(ParseBareType());
            }
        }
示例#3
0
        /// <summary>
        /// Parse the type after a single `mut` keyword. Requires that the mutable
        /// keyword has already been consumed.
        /// </summary>
        private ITypeSyntax ParseMutableType(IMutableKeywordToken mutableKeyword)
        {
            var referent = ParseBareType();
            var span     = TextSpan.Covering(mutableKeyword.Span, referent.Span);

            return(new CapabilityTypeSyntax(Borrowed, referent, span));
        }
        internal FieldDeclarationSyntax ParseField(
            IClassDeclarationSyntax declaringType,
            bool mutableBinding,
            ModifierParser modifiers)
        {
            var accessModifer = modifiers.ParseAccessModifier();

            modifiers.ParseEndOfModifiers();
            // We should only be called when there is a binding keyword
            var  binding    = Tokens.Required <IBindingToken>();
            var  identifier = Tokens.RequiredToken <IIdentifierToken>();
            Name name       = identifier.Value;

            Tokens.Expect <IColonToken>();
            var type = ParseType();
            IExpressionSyntax?initializer = null;

            if (Tokens.Accept <IEqualsToken>())
            {
                initializer = ParseExpression();
            }

            var semicolon = Tokens.Expect <ISemicolonToken>();
            var span      = TextSpan.Covering(binding, semicolon);

            return(new FieldDeclarationSyntax(declaringType, span, File, accessModifer, mutableBinding,
                                              identifier.Span, name, type, initializer));
        }
        internal IReachabilityAnnotationsSyntax ParseReachabilityAnnotations()
        {
            var reachableFrom = AcceptReachableFromAnnotation();
            var canReach      = AcceptCanReachAnnotation();
            var span          = TextSpan.Covering(reachableFrom?.Span, canReach?.Span, Tokens.Current.Span.AtStart());

            return(new ReachabilityAnnotationsSyntax(span, reachableFrom, canReach));
        }
        // Requires the open brace has already been consumed
        private BlockSyntax ParseRestOfBlock(TextSpan openBrace)
        {
            var statements = ParseMany <StatementSyntax, ICloseBraceToken>(ParseStatement);
            var closeBrace = Tokens.Expect <ICloseBraceToken>();
            var span       = TextSpan.Covering(openBrace, closeBrace);

            return(new BlockSyntax(span, statements));
        }
        private (FixedList <IMemberDeclarationSyntax> members, TextSpan span) ParseClassBody(IClassDeclarationSyntax declaringType)
        {
            var openBrace  = Tokens.Expect <IOpenBraceToken>();
            var members    = ParseMemberDeclarations(declaringType);
            var closeBrace = Tokens.Expect <ICloseBraceToken>();
            var span       = TextSpan.Covering(openBrace, closeBrace);

            return(members, span);
        }
 public ReferenceLifetimeSyntax(
     ExpressionSyntax referentTypeExpression,
     TextSpan nameSpan,
     SimpleName lifetime)
     : base(TextSpan.Covering(referentTypeExpression.Span, nameSpan))
 {
     ReferentTypeExpression = referentTypeExpression;
     Lifetime = lifetime;
 }
示例#9
0
        public IBlockExpressionSyntax ParseBlock()
        {
            var openBrace  = Tokens.Expect <IOpenBraceToken>();
            var statements = ParseMany <IStatementSyntax, ICloseBraceToken>(ParseStatement);
            var closeBrace = Tokens.Expect <ICloseBraceToken>();
            var span       = TextSpan.Covering(openBrace, closeBrace);

            return(new BlockExpressionSyntax(span, statements));
        }
 private IReachableFromAnnotationSyntax?AcceptReachableFromAnnotation()
 {
     if (!(Tokens.Current is ILeftWaveArrowToken))
     {
         return(null);
     }
     var leftArrow  = Tokens.Required <ILeftWaveArrowToken>();
     var parameters = ParseManySeparated <IParameterNameSyntax, ICommaToken>(ParseParameterName);
     var span       = TextSpan.Covering(leftArrow, parameters[^ 1].Span);
示例#11
0
 public AssignmentExpressionSyntax(
     ExpressionSyntax leftOperand,
     AssignmentOperator @operator,
     ExpressionSyntax rightOperand)
     : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span))
 {
     LeftOperand  = leftOperand;
     RightOperand = rightOperand;
     Operator     = @operator;
 }
示例#12
0
 public BinaryOperatorExpressionSyntax(
     IExpressionSyntax leftOperand,
     BinaryOperator @operator,
     IExpressionSyntax rightOperand)
     : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span))
 {
     this.leftOperand  = leftOperand;
     Operator          = @operator;
     this.rightOperand = rightOperand;
 }
示例#13
0
 public AssignmentExpressionSyntax(
     IAssignableExpressionSyntax leftOperand,
     AssignmentOperator @operator,
     IExpressionSyntax rightOperand)
     : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span))
 {
     this.leftOperand  = leftOperand;
     this.rightOperand = rightOperand;
     Operator          = @operator;
 }
示例#14
0
 public BinaryExpressionSyntax(
     ExpressionSyntax leftOperand,
     BinaryOperator @operator,
     ExpressionSyntax rightOperand)
     : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span))
 {
     LeftOperand  = leftOperand;
     Operator     = @operator;
     RightOperand = rightOperand;
 }
示例#15
0
        private ITypeSyntax ParseTypeWithCapability <TCapabilityToken>(ReferenceCapability immutableCapability, ReferenceCapability mutableCapability)
            where TCapabilityToken : ICapabilityToken
        {
            var primaryCapability = Tokens.RequiredToken <TCapabilityToken>();
            var mutableKeyword    = Tokens.AcceptToken <IMutableKeywordToken>();
            var referent          = ParseBareType();
            var span       = TextSpan.Covering(primaryCapability.Span, referent.Span);
            var capability = mutableKeyword is null ? immutableCapability : mutableCapability;

            return(new CapabilityTypeSyntax(capability, referent, span));
        }
示例#16
0
 public BinaryOperation(
     Operand leftOperand,
     BinaryOperator @operator,
     Operand rightOperand,
     SimpleType type)
     : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span))
 {
     LeftOperand  = leftOperand;
     Operator     = @operator;
     RightOperand = rightOperand;
     Type         = type;
 }
        internal IMemberDeclarationSyntax ParseMemberFunction(
            IClassDeclarationSyntax declaringType,
            ModifierParser modifiers)
        {
            var accessModifer = modifiers.ParseAccessModifier();

            modifiers.ParseEndOfModifiers();
            var  fn         = Tokens.Expect <IFunctionKeywordToken>();
            var  identifier = Tokens.RequiredToken <IIdentifierToken>();
            Name name       = identifier.Value;
            var  bodyParser = BodyParser();
            var  parameters = bodyParser.ParseParameters(bodyParser.ParseMethodParameter);

            var(returnType, reachabilityAnnotations) = ParseReturn();

            var selfParameter   = parameters.OfType <ISelfParameterSyntax>().FirstOrDefault();
            var namedParameters = parameters.Except(parameters.OfType <ISelfParameterSyntax>())
                                  .Cast <INamedParameterSyntax>().ToFixedList();

            // if no self parameter, it is an associated function
            if (selfParameter is null)
            {
                var body = bodyParser.ParseFunctionBody();
                var span = TextSpan.Covering(fn, body.Span);
                return(new AssociatedFunctionDeclarationSyntax(declaringType, span, File, accessModifer, identifier.Span, name, namedParameters, returnType, reachabilityAnnotations, body));
            }

            if (!(parameters[0] is ISelfParameterSyntax))
            {
                Add(ParseError.SelfParameterMustBeFirst(File, selfParameter.Span));
            }

            foreach (var extraSelfParameter in parameters.OfType <ISelfParameterSyntax>().Skip(1))
            {
                Add(ParseError.ExtraSelfParameter(File, extraSelfParameter.Span));
            }

            // It is a method that may or may not have a body
            if (Tokens.Current is IOpenBraceToken)
            {
                var body = bodyParser.ParseFunctionBody();
                var span = TextSpan.Covering(fn, body.Span);
                return(new ConcreteMethodDeclarationSyntax(declaringType, span, File, accessModifer,
                                                           identifier.Span, name, selfParameter, namedParameters, returnType, reachabilityAnnotations, body));
            }
            else
            {
                var semicolon = bodyParser.Tokens.Expect <ISemicolonToken>();
                var span      = TextSpan.Covering(fn, semicolon);
                return(new AbstractMethodDeclarationSyntax(declaringType, span, File, accessModifer,
                                                           identifier.Span, name, selfParameter, namedParameters, returnType, reachabilityAnnotations));
            }
        }
 public BooleanLogicInstruction(
     Place resultPlace,
     BooleanLogicOperator @operator,
     Operand leftOperand,
     Operand rightOperand,
     Scope scope)
     : base(resultPlace, TextSpan.Covering(leftOperand.Span, rightOperand.Span), scope)
 {
     Operator     = @operator;
     LeftOperand  = leftOperand;
     RightOperand = rightOperand;
 }
示例#19
0
        public ParameterSyntax ParseParameter()
        {
            switch (Tokens.Current)
            {
            case IRefKeywordToken _:
            case IMutableKeywordToken _:
            case ISelfKeywordToken _:
            {
                var span        = Tokens.Current.Span;
                var refSelf     = Tokens.Accept <IRefKeywordToken>();
                var mutableSelf = Tokens.Accept <IMutableKeywordToken>();
                var selfSpan    = Tokens.Expect <ISelfKeywordToken>();
                span = TextSpan.Covering(span, selfSpan);
                var name = nameContext.Qualify(SpecialName.Self);
                return(new SelfParameterSyntax(span, name, refSelf, mutableSelf));
            }

            case IDotToken _:
            {
                var dot        = Tokens.Expect <IDotToken>();
                var identifier = Tokens.RequiredToken <IIdentifierToken>();
                var equals     = Tokens.AcceptToken <IEqualsToken>();
                ExpressionSyntax defaultValue = null;
                if (equals != null)
                {
                    defaultValue = ParseExpression();
                }
                var span = TextSpan.Covering(dot, identifier.Span, defaultValue?.Span);
                var name = nameContext.Qualify(SimpleName.Special("field_" + identifier.Value));
                return(new FieldParameterSyntax(span, name, defaultValue));
            }

            default:
            {
                var span           = Tokens.Current.Span;
                var isParams       = Tokens.Accept <IParamsKeywordToken>();
                var mutableBinding = Tokens.Accept <IVarKeywordToken>();
                var identifier     = Tokens.RequiredToken <IIdentifierOrUnderscoreToken>();
                var name           = nameContext.Qualify(variableNumbers.VariableName(identifier.Value));
                Tokens.Expect <IColonToken>();
                // Need to not consume the assignment that separates the type from the default value,
                // hence the min operator precedence.
                var type = ParseExpression(OperatorPrecedence.AboveAssignment);
                ExpressionSyntax defaultValue = null;
                if (Tokens.Accept <IEqualsToken>())
                {
                    defaultValue = ParseExpression();
                }
                span = TextSpan.Covering(span, type.Span, defaultValue?.Span);
                return(new NamedParameterSyntax(span, isParams, mutableBinding, name, type, defaultValue));
            }
            }
        }
示例#20
0
        public ExpressionSyntax ParseName()
        {
            ExpressionSyntax name = ParseSimpleName();

            while (Tokens.Accept <IDotToken>())
            {
                var simpleName = ParseSimpleName();
                var span       = TextSpan.Covering(name.Span, simpleName.Span);
                name = new MemberAccessExpressionSyntax(span, name, AccessOperator.Standard, simpleName);
            }
            return(name);
        }
示例#21
0
        public IStatementSyntax ParseStatement()
        {
            switch (Tokens.Current)
            {
            case IOpenBraceToken _:
                var block = ParseBlock();
                return(new ExpressionStatementSyntax(block.Span, block));

            case ILetKeywordToken _:
                var let = Tokens.Expect <IBindingToken>();
                return(ParseRestOfVariableDeclaration(let, false));

            case IVarKeywordToken _:
                var @var = Tokens.Expect <IBindingToken>();
                return(ParseRestOfVariableDeclaration(@var, true));

            case IForeachKeywordToken _:
                var @foreach = ParseForeach();
                return(new ExpressionStatementSyntax(@foreach.Span, @foreach));

            case IWhileKeywordToken _:
                var @while = ParseWhile();
                return(new ExpressionStatementSyntax(@while.Span, @while));

            case ILoopKeywordToken _:
                var loop = ParseLoop();
                return(new ExpressionStatementSyntax(loop.Span, loop));

            case IIfKeywordToken _:
                var @if = ParseIf(ParseAs.Statement);
                return(new ExpressionStatementSyntax(@if.Span, @if));

            case IUnsafeKeywordToken _:
                return(ParseUnsafeStatement());

            default:
                try
                {
                    var expression = ParseExpression();
                    var semicolon  = Tokens.Expect <ISemicolonToken>();
                    return(new ExpressionStatementSyntax(
                               TextSpan.Covering(expression.Span, semicolon), expression));
                }
                catch (ParseFailedException)
                {
                    SkipToEndOfStatement();
                    throw;
                }
            }
        }
示例#22
0
        public ITypeSyntax ParseType()
        {
            var typeSyntax = ParseTypeWithCapability();

            IQuestionToken?question;

            while ((question = Tokens.AcceptToken <IQuestionToken>()) != null)
            {
                var span = TextSpan.Covering(typeSyntax.Span, question.Span);
                return(new OptionalTypeSyntax(span, typeSyntax));
            }

            return(typeSyntax);
        }
示例#23
0
 public CompareInstruction(
     Place resultPlace,
     CompareInstructionOperator @operator,
     NumericType type,
     Operand leftOperand,
     Operand rightOperand,
     Scope scope)
     : base(resultPlace, TextSpan.Covering(leftOperand.Span, rightOperand.Span), scope)
 {
     Operator     = @operator;
     LeftOperand  = leftOperand;
     RightOperand = rightOperand;
     Type         = type;
 }
        private IBodySyntax ParseFunctionBody()
        {
            var openBrace  = Tokens.Expect <IOpenBraceToken>();
            var statements = ParseMany <IStatementSyntax, ICloseBraceToken>(ParseStatement);

            foreach (var resultStatement in statements.OfType <IResultStatementSyntax>())
            {
                Add(ParseError.ResultStatementInBody(File, resultStatement.Span));
            }
            var closeBrace = Tokens.Expect <ICloseBraceToken>();
            var span       = TextSpan.Covering(openBrace, closeBrace);

            return(new BodySyntax(span, statements.OfType <IBodyStatementSyntax>().ToFixedList()));
        }
示例#25
0
        private IExpressionStatementSyntax ParseUnsafeStatement()
        {
            var unsafeKeyword    = Tokens.Expect <IUnsafeKeywordToken>();
            var isBlock          = Tokens.Current is IOpenBraceToken;
            var expression       = isBlock ? ParseBlock() : ParseParenthesizedExpression();
            var span             = TextSpan.Covering(unsafeKeyword, expression.Span);
            var unsafeExpression = new UnsafeExpressionSyntax(span, expression);

            if (!isBlock)
            {
                var semicolon = Tokens.Expect <ISemicolonToken>();
                span = TextSpan.Covering(span, semicolon);
            }
            return(new ExpressionStatementSyntax(span, unsafeExpression));
        }
        public ExpressionBlockSyntax ParseExpressionBlock()
        {
            switch (Tokens.Current)
            {
            case IOpenBraceToken _:
                return(ParseBlock());

            case IEqualsGreaterThanToken _:
            default:
                var equalsGreaterThan = Tokens.Expect <IEqualsGreaterThanToken>();
                var expression        = ParseExpression();
                var span = TextSpan.Covering(equalsGreaterThan, expression.Span);
                return(new ResultExpressionSyntax(span, expression));
            }
        }
        private IClassDeclarationSyntax ParseClass(
            ModifierParser modifiers)
        {
            var accessModifier  = modifiers.ParseAccessModifier();
            var mutableModifier = modifiers.ParseMutableModifier();

            modifiers.ParseEndOfModifiers();
            var  @class     = Tokens.Expect <IClassKeywordToken>();
            var  identifier = Tokens.RequiredToken <IIdentifierToken>();
            Name name       = identifier.Value;
            var  headerSpan = TextSpan.Covering(@class, identifier.Span);
            var  bodyParser = BodyParser();

            return(new ClassDeclarationSyntax(ContainingNamespace, headerSpan, File, accessModifier, mutableModifier, identifier.Span,
                                              name, bodyParser.ParseClassBody));
        }
        public GenericParameterSyntax ParseGenericParameter()
        {
            Name name;
            var  dollar = Tokens.AcceptToken <IDollarToken>();

            if (dollar != null)
            {
                var lifetime = Tokens.RequiredToken <ILifetimeNameToken>();
                var span     = TextSpan.Covering(dollar.Span, lifetime.Span);

                switch (lifetime)
                {
                case IIdentifierToken lifetimeIdentifier:
                    name = nameContext.Qualify(lifetimeIdentifier.Value);
                    break;

                case IRefKeywordToken _:
                    name = nameContext.Qualify(SpecialName.Ref);
                    break;

                case IOwnedKeywordToken _:
                    Add(ParseError.OwnedNotValidAsGenericLifetimeParameter(File, span));
                    // We just treat it as if they had written `$\owned`
                    name = nameContext.Qualify("owned");
                    break;

                default:
                    throw NonExhaustiveMatchException.For(lifetime);
                }

                return(new GenericParameterSyntax(true, false, name, null));
            }

            var isParams   = Tokens.Accept <IParamsKeywordToken>();
            var identifier = Tokens.RequiredToken <IIdentifierToken>();

            name = nameContext.Qualify(identifier.Value);
            ExpressionSyntax typeExpression = null;

            if (Tokens.Accept <IColonToken>())
            {
                typeExpression = ParseExpression();
            }
            return(new GenericParameterSyntax(false, isParams, name, typeExpression));
        }
        public IParameterSyntax ParseMethodParameter()
        {
            switch (Tokens.Current)
            {
            case IMutableKeywordToken _:
            case ISelfKeywordToken _:
            {
                var span        = Tokens.Current.Span;
                var mutableSelf = Tokens.Accept <IMutableKeywordToken>();
                var selfSpan    = Tokens.Expect <ISelfKeywordToken>();
                span = TextSpan.Covering(span, selfSpan);
                return(new SelfParameterSyntax(span, mutableSelf));
            }

            default:
                return(ParseFunctionParameter());
            }
        }
        public INamedParameterSyntax ParseFunctionParameter()
        {
            var span           = Tokens.Current.Span;
            var mutableBinding = Tokens.Accept <IVarKeywordToken>();
            var identifier     = Tokens.RequiredToken <IIdentifierOrUnderscoreToken>();
            var name           = identifier.Value;

            Tokens.Expect <IColonToken>();
            var type = ParseType();
            IExpressionSyntax?defaultValue = null;

            if (Tokens.Accept <IEqualsToken>())
            {
                defaultValue = ParseExpression();
            }
            span = TextSpan.Covering(span, type.Span, defaultValue?.Span);
            return(new NamedParameterSyntax(span, mutableBinding, name, type, defaultValue));
        }