private ClassDeclarationSyntax ParseClassDeclarationSyntax(Lexer lexer, DeclarationModifierSyntax modifiers) { var token = lexer.GetNextRelevantToken(); token.ExpectedToBe(TokenDescriptor.ClassKeyword); ValidateModifiers(modifiersForClass, modifiers, token); token = lexer.GetNextRelevantToken(); token.ExpectedToBe(TokenDescriptor.Identifier); var name = token.Value; token = lexer.PeekNextRelevantToken(); if (token.Is(TokenDescriptor.LeftBrace)) { lexer.GetNextRelevantToken(); // class has a body lexer.GetNextRelevantToken(true).ExpectedToBe(TokenDescriptor.RightBrace); } return(SyntaxFactory.ClassDeclarationSyntax(name, modifiers)); }
private CompileUnitSyntax ParseCompileUnit(Lexer lexer) { NamespaceDeclarationSyntax namespaceDeclarationSyntax = new NamespaceDeclarationSyntax(); var funcDeclarationSyntaxList = new List <FunctionDeclarationSyntax>(); var classDeclarationSyntaxList = new List <ClassDeclarationSyntax>(); DeclarationModifierSyntax declModifiers = SyntaxFactory.ModifierSyntax(); while (true) { // first we should expect the namespace declaration var peekedToken = lexer.PeekNextRelevantToken(true); if (peekedToken.Is(TokenDescriptor.EndOfFile)) { break; } if (peekedToken.Descriptor == TokenDescriptor.NamespaceKeyword) { if (namespaceDeclarationSyntax.Identifier.Length == 0) { namespaceDeclarationSyntax = ParseNamespaceDeclarationSyntax(lexer); } else { throw new CaliParseException("Duplicate namespace declaration found", peekedToken); } } else { if (IsDeclModifier(peekedToken.Descriptor)) { ParseDeclarationModifiers(lexer, declModifiers); peekedToken = lexer.PeekNextRelevantToken(); } var tokenDescriptor = peekedToken.Descriptor; if (tokenDescriptor == TokenDescriptor.FunctionKeyword) { funcDeclarationSyntaxList.Add(ParseFuncDeclarationSyntax(lexer, declModifiers)); } else if (tokenDescriptor == TokenDescriptor.ClassKeyword) { classDeclarationSyntaxList.Add(ParseClassDeclarationSyntax(lexer, declModifiers)); } else { throw new CaliParseException($"Unexpected token '{peekedToken.Value}'", peekedToken); } } } return(SyntaxFactory.CompileUnitSyntax( namespaceDeclarationSyntax, funcDeclarationSyntaxList, classDeclarationSyntaxList)); }
private static void ValidateModifiers(ICollection <DeclarationModifier> validModifiers, DeclarationModifierSyntax modifiers, Token token) { // TODO: complete if (false) { throw new CaliParseException($"Invalid modifier '{modifiers.Modifier}' for class", token); } }
private void ParseDeclarationModifiers(Lexer lexer, DeclarationModifierSyntax syntax) { var modifiers = new List <Token>(); Token token; do { token = lexer.GetNextRelevantToken(); modifiers.Add(token); token = lexer.PeekNextRelevantToken(); } while (IsDeclModifier(token.Descriptor)); modifiers.ForEach(it => syntax.Append(it.Descriptor)); }
private FunctionDeclarationSyntax ParseFuncDeclarationSyntax(Lexer lexer, DeclarationModifierSyntax modifiers) { // expect func or modifier keyword var token = lexer.GetNextRelevantToken(); token.ExpectedToBe(TokenDescriptor.FunctionKeyword); ValidateModifiers(modifiersForFunction, modifiers, token); token = lexer.GetNextRelevantToken(); token.ExpectedToBe(TokenDescriptor.Identifier); var name = token.Value; lexer.GetNextRelevantToken().ExpectedToBe(TokenDescriptor.LeftParenthesis); var parameterDeclarations = ParseParameterList(lexer); lexer.GetNextRelevantToken(true).ExpectedToBe(TokenDescriptor.RightParenthesis); TypeReferenceSyntax returnType; token = lexer.PeekNextRelevantToken(); if (token.Is(TokenDescriptor.Arrow)) { lexer.GetNextRelevantToken(); // now return type returnType = ParseTypeReferenceSyntax(lexer); } else { returnType = SyntaxFactory.UnitTypeReference; } token = lexer.PeekNextRelevantToken(); token.ExpectedToBe(TokenDescriptor.LeftBrace); // expect function body // var statements = ParseMethodBody(lexer); return(SyntaxFactory.FunctionDeclarationSyntax( name, modifiers, parameterDeclarations, returnType, new List <IStatementSyntax>())); }