Esempio n. 1
0
        public NamedFunctionDeclarationSyntax ParseNamedFunction(
            FixedList <AttributeSyntax> attributes,
            FixedList <IModiferToken> modifiers)
        {
            Tokens.Expect <IFunctionKeywordToken>();
            var identifier        = Tokens.RequiredToken <IIdentifierToken>();
            var genericParameters = AcceptGenericParameters();
            var name                    = nameContext.Qualify(identifier.Value);
            var bodyParser              = NestedParser(name);
            var parameters              = bodyParser.ParseParameters();
            var lifetimeBounds          = bodyParser.ParseLifetimeBounds();
            ExpressionSyntax returnType = null;

            if (Tokens.Accept <IRightArrowToken>())
            {
                returnType = ParseExpression();
            }
            var genericConstraints = ParseGenericConstraints();
            var mayEffects         = ParseMayEffects();
            var noEffects          = ParseNoEffects();

            var(requires, ensures) = ParseFunctionContracts();
            var body = bodyParser.ParseFunctionBody();

            return(new NamedFunctionDeclarationSyntax(File, modifiers, name, identifier.Span,
                                                      genericParameters, parameters, lifetimeBounds, returnType, genericConstraints, mayEffects,
                                                      noEffects, requires, ensures, body));
        }
Esempio n. 2
0
        private FieldDeclarationSyntax ParseField(
            FixedList <AttributeSyntax> attributes,
            FixedList <IModiferToken> modifiers)
        {
            // TODO include these in the syntax tree
            var binding      = Tokens.Expect <IBindingToken>();
            var getterAccess = AcceptFieldGetter();
            var identifier   = Tokens.RequiredToken <IIdentifierToken>();
            var name         = nameContext.Qualify(identifier.Value);
            ExpressionSyntax typeExpression = null;

            if (Tokens.Accept <IColonToken>())
            {
                // Need to not consume the assignment that separates the type from the initializer,
                // hence the min operator precedence.
                typeExpression = ParseExpression(OperatorPrecedence.AboveAssignment);
            }
            ExpressionSyntax initializer = null;

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

            Tokens.Expect <ISemicolonToken>();
            return(new FieldDeclarationSyntax(File, attributes, modifiers, getterAccess, name,
                                              identifier.Span, typeExpression, initializer));
        }
Esempio n. 3
0
        private ThrowEffectEntrySyntax ParseThrowEffectEntry()
        {
            var isParams      = Tokens.Accept <IParamsKeywordToken>();
            var exceptionType = ParseExpression();

            return(new ThrowEffectEntrySyntax(isParams, exceptionType));
        }
Esempio n. 4
0
        private ConstDeclarationSyntax ParseConst(
            FixedList <AttributeSyntax> attributes,
            FixedList <IModiferToken> modifiers)
        {
            try
            {
                Tokens.Expect <IConstKeywordToken>();
                var identifier        = Tokens.RequiredToken <IIdentifierToken>();
                var name              = nameContext.Qualify(identifier.Value);
                ExpressionSyntax type = null;
                if (Tokens.Accept <IColonToken>())
                {
                    // Need to not consume the assignment that separates the type from the initializer,
                    // hence the min operator precedence.
                    type = ParseExpression(OperatorPrecedence.AboveAssignment);
                }

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

                Tokens.Expect <ISemicolonToken>();
                return(new ConstDeclarationSyntax(File, attributes, modifiers, name,
                                                  identifier.Span, type, initializer));
            }
            catch (ParseFailedException)
            {
                SkipToEndOfStatement();
                throw;
            }
        }
        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));
        }
Esempio n. 6
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));
        }
Esempio n. 7
0
 private ExpressionSyntax AcceptBaseClass()
 {
     if (!Tokens.Accept <IColonToken>())
     {
         return(null);
     }
     return(ParseExpression());
 }
Esempio n. 8
0
 private FixedList <ExpressionSyntax> AcceptBaseTypes()
 {
     if (!Tokens.Accept <ILessThanColonToken>())
     {
         return(null);
     }
     return(AcceptOneOrMore <ExpressionSyntax, ICommaToken>(ParseExpression));
 }
Esempio n. 9
0
 private ExpressionSyntax AcceptInvariant()
 {
     if (!Tokens.Accept <IInvariantKeywordToken>())
     {
         return(null);
     }
     return(ParseExpression());
 }
Esempio n. 10
0
        private FixedList <EffectSyntax> ParseNoEffects()
        {
            if (!Tokens.Accept <INoKeywordToken>())
            {
                return(FixedList <EffectSyntax> .Empty);
            }

            return(AcceptOneOrMore <EffectSyntax, ICommaToken>(ParseEffect));
        }
        private (ITypeSyntax?, IReachabilityAnnotationsSyntax) ParseReturn()
        {
            if (Tokens.Accept <IRightArrowToken>())
            {
                return(ParseType(), ParseReachabilityAnnotations());
            }

            return(null, new ReachabilityAnnotationsSyntax(Tokens.Current.Span.AtStart(), null, null));
        }
        public BlockSyntax AcceptBlock()
        {
            var openBrace = Tokens.Current.Span;

            if (!Tokens.Accept <IOpenBraceToken>())
            {
                return(null);
            }
            return(ParseRestOfBlock(openBrace));
        }
        public GenericConstraintSyntax AcceptGenericConstraint()
        {
            if (!Tokens.Accept <IWhereKeywordToken>())
            {
                return(null);
            }
            var expression = ParseExpression();

            return(new GenericConstraintSyntax(expression));
        }
Esempio n. 14
0
        /// <summary>
        /// Skip tokens until we reach what we assume to be the end of a statement
        /// </summary>
        // TODO does this belong on a statement parser or something
        private void SkipToEndOfStatement()
        {
            while (!Tokens.AtEnd <ISemicolonToken>())
            {
                Tokens.Next();
            }

            // Consume the semicolon is we aren't at the end of the file.
            var _ = Tokens.Accept <ISemicolonToken>();
        }
        public FixedList <GenericParameterSyntax> AcceptGenericParameters()
        {
            if (!Tokens.Accept <IOpenBracketToken>())
            {
                return(null);
            }
            var parameters = ParseMany <GenericParameterSyntax, ICommaToken, ICloseBracketToken>(ParseGenericParameter);

            Tokens.Expect <ICloseBracketToken>();
            return(parameters);
        }
Esempio n. 16
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);
        }
Esempio n. 17
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));
            }
            }
        }
Esempio n. 18
0
        private AttributeSyntax AcceptAttribute()
        {
            if (!Tokens.Accept <IHashHashToken>())
            {
                return(null);
            }
            var name = ParseName();
            FixedList <ArgumentSyntax> arguments = null;

            if (Tokens.Accept <IOpenParenToken>())
            {
                arguments = ParseArguments();
                Tokens.Expect <ICloseParenToken>();
            }
            return(new AttributeSyntax(name, arguments));
        }
        public UsingDirectiveSyntax AcceptUsingDirective()
        {
            if (!Tokens.Accept <IUsingKeywordToken>())
            {
                return(null);
            }
            var identifiers = AcceptOneOrMore <IIdentifierToken, IDotToken>(
                () => Tokens.AcceptToken <IIdentifierToken>());
            RootName name = GlobalNamespaceName.Instance;

            foreach (var identifier in identifiers)
            {
                name = name.Qualify(identifier.Value);
            }
            Tokens.Expect <ISemicolonToken>();
            return(new UsingDirectiveSyntax((Name)name));
        }
        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 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));
        }
        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());
            }
        }
Esempio n. 23
0
        public FixedList <T> ParseMany <T, TSeparator, TTerminator>(Func <T> parseItem)
            where T : class
            where TSeparator : class, IToken
            where TTerminator : IToken
        {
            var items = new List <T>();

            while (!Tokens.AtEnd <TTerminator>())
            {
                items.Add(parseItem());
                if (!Tokens.Accept <TSeparator>())
                {
                    break;
                }
            }

            return(items.ToFixedList());
        }
Esempio n. 24
0
        public FixedList <T> AcceptSeparatedList <T, TSeparator>(Func <T> acceptItem)
            where T : class
            where TSeparator : class, IToken
        {
            var items = new List <T>();
            var item  = acceptItem();

            while (item != null)
            {
                items.Add(item);
                if (!Tokens.Accept <TSeparator>())
                {
                    break;
                }

                item = acceptItem();
            }
            return(items.ToFixedList());
        }
Esempio n. 25
0
        private NameSyntax ParseSimpleName()
        {
            var        identifier = Tokens.RequiredToken <IIdentifierToken>();
            var        name       = new SimpleName(identifier.Value);
            NameSyntax syntax;

            if (Tokens.Accept <IOpenBracketToken>())
            {
                var arguments    = ParseArguments();
                var closeBracket = Tokens.Expect <ICloseBracketToken>();
                var span         = TextSpan.Covering(identifier.Span, closeBracket);
                syntax = new GenericNameSyntax(span, identifier.Value, arguments);
            }
            else
            {
                syntax = new IdentifierNameSyntax(identifier.Span, name);
            }
            return(syntax);
        }
        private (NamespaceName, TextSpan) ParseNamespaceName()
        {
            var           firstSegment = Tokens.RequiredToken <IIdentifierToken>();
            var           span         = firstSegment.Span;
            NamespaceName name         = firstSegment.Value;

            while (Tokens.Accept <IDotToken>())
            {
                var(nameSegment, segmentSpan) = Tokens.ExpectToken <IIdentifierToken>();
                // We need the span to cover a trailing dot
                span = TextSpan.Covering(span, segmentSpan);
                if (nameSegment is null)
                {
                    break;
                }
                name = name.Qualify(nameSegment.Value);
            }

            return(name, span);
        }
        /// <summary>
        /// Parse an expected item and then parse additional items as long as there is
        /// a separator.
        /// </summary>
        public FixedList <T> ParseManySeparated <T, TSeparator>(Func <T> parseItem)
        //where T : class
            where TSeparator : class, IToken
        {
            var item = parseItem();

            if (item is null)
            {
                throw new ParseFailedException();
            }
            var items = new List <T>()
            {
                item
            };

            while (Tokens.Accept <TSeparator>())
            {
                items.Add(parseItem());
            }

            return(items.ToFixedList());
        }
        // Requires the binding has already been consumed
        private StatementSyntax ParseRestOfVariableDeclaration(bool mutableBinding)
        {
            var identifier        = Tokens.RequiredToken <IIdentifierToken>();
            var name              = this.nameContext.Qualify(variableNumbers.VariableName(identifier.Value));
            ExpressionSyntax type = null;

            if (Tokens.Accept <IColonToken>())
            {
                // Need to not consume the assignment that separates the type from the initializer,
                // hence the min operator precedence.
                type = ParseExpression(OperatorPrecedence.LogicalOr);
            }

            ExpressionSyntax initializer = null;

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

            Tokens.Expect <ISemicolonToken>();
            return(new VariableDeclarationStatementSyntax(mutableBinding, name, identifier.Span, type,
                                                          initializer));
        }
Esempio n. 29
0
        public FixedList <T> AcceptOneOrMore <T, TSeparator>(Func <T> acceptItem)
            where T : class
            where TSeparator : class, IToken
        {
            var item = acceptItem();

            if (item == null)
            {
                throw new ParseFailedException();
            }
            var items = new List <T>();

            while (item != null)
            {
                items.Add(item);
                if (!Tokens.Accept <TSeparator>())
                {
                    break;
                }

                item = acceptItem();
            }
            return(items.ToFixedList());
        }
Esempio n. 30
0
        public OperatorDeclarationSyntax ParseOperator(
            FixedList <AttributeSyntax> attributes,
            FixedList <IModiferToken> modifiers)
        {
            var operatorKeyword   = Tokens.Expect <IOperatorKeywordToken>();
            var genericParameters = AcceptGenericParameters();
            // TODO correctly store these in the syntax class
            OverloadableOperator oper;
            TextSpan             endOperatorSpan;

            switch (Tokens.Current)
            {
            case IHashToken _:
                Tokens.Expect <IHashToken>();
                switch (Tokens.Current)
                {
                case IOpenParenToken _:
                    Tokens.Next();
                    endOperatorSpan = Tokens.Expect <ICloseParenToken>();
                    oper            = OverloadableOperator.TupleInitializer;
                    break;

                case IOpenBracketToken _:
                    Tokens.Next();
                    endOperatorSpan = Tokens.Expect <ICloseBracketToken>();
                    oper            = OverloadableOperator.ListInitializer;
                    break;

                case IOpenBraceToken _:
                    Tokens.Next();
                    endOperatorSpan = Tokens.Expect <ICloseBraceToken>();
                    oper            = OverloadableOperator.SetInitializer;
                    break;

                default:
                    throw NonExhaustiveMatchException.For(Tokens.Current);
                }
                break;

            case IStringLiteralToken _:
                endOperatorSpan = Tokens.Expect <IStringLiteralToken>();
                // TODO need to check it is empty string
                oper = OverloadableOperator.StringLiteral;
                break;

            // TODO case for user defined literals ''
            default:
                Tokens.UnexpectedToken();
                throw new ParseFailedException();
            }

            var nameSpan                = TextSpan.Covering(operatorKeyword, endOperatorSpan);
            var name                    = nameContext.Qualify(SimpleName.Special("op_" + oper));
            var bodyParser              = NestedParser(name);
            var parameters              = bodyParser.ParseParameters();
            var lifetimeBounds          = bodyParser.ParseLifetimeBounds();
            ExpressionSyntax returnType = null;

            if (Tokens.Accept <IRightArrowToken>())
            {
                returnType = bodyParser.ParseExpression();
            }
            var genericConstraints = ParseGenericConstraints();
            var mayEffects         = ParseMayEffects();
            var noEffects          = ParseNoEffects();

            var(requires, ensures) = ParseFunctionContracts();
            var body = bodyParser.ParseBlock();

            return(new OperatorDeclarationSyntax(File, modifiers, name, nameSpan, genericParameters,
                                                 parameters, lifetimeBounds, returnType, genericConstraints, mayEffects, noEffects, requires,
                                                 ensures, body));
        }