// 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)); }
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()); } }
/// <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; }
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);
public AssignmentExpressionSyntax( ExpressionSyntax leftOperand, AssignmentOperator @operator, ExpressionSyntax rightOperand) : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span)) { LeftOperand = leftOperand; RightOperand = rightOperand; Operator = @operator; }
public BinaryOperatorExpressionSyntax( IExpressionSyntax leftOperand, BinaryOperator @operator, IExpressionSyntax rightOperand) : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span)) { this.leftOperand = leftOperand; Operator = @operator; this.rightOperand = rightOperand; }
public AssignmentExpressionSyntax( IAssignableExpressionSyntax leftOperand, AssignmentOperator @operator, IExpressionSyntax rightOperand) : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span)) { this.leftOperand = leftOperand; this.rightOperand = rightOperand; Operator = @operator; }
public BinaryExpressionSyntax( ExpressionSyntax leftOperand, BinaryOperator @operator, ExpressionSyntax rightOperand) : base(TextSpan.Covering(leftOperand.Span, rightOperand.Span)) { LeftOperand = leftOperand; Operator = @operator; RightOperand = rightOperand; }
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)); }
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; }
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)); } } }
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); }
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; } } }
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); }
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())); }
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)); }