public Expr Parse(ParserContext context) { // Ensure current token is parentheses start. context.Stream.EnsureCurrent(TokenType.SymbolParenthesesL); // Peek at the next token. Token peek = context.Stream.Peek(); // Lambda expresion. if (TokenIdentifier.IsType(peek, context) || peek.Type == TokenType.SymbolParenthesesR) { // Delegate to the lambda expression parser. return(new LambdaExprParser().Parse(context)); } // Skip the parentheses start token. context.Stream.Skip(); // Parse the expression. Expr expr = new ExprParser().Parse(context); // Ensure current token is parentheses end. context.Stream.EnsureCurrent(TokenType.SymbolParenthesesR); // Skip the parentheses end token. context.Stream.Skip(); // Return the expression. return(expr); }
public List <Expr> Parse(ParserContext context) { // Create the resulting argument list. List <Expr> arguments = new List <Expr>(); // Parse the next value. Expr value = new ExprParser().Parse(context); // Append value to the argument list. arguments.Add(value); // Capture the current token. Token token = context.Stream.Current; // Expect either a comma or pipe symbol. if (token.Type != SyntaxAnalysis.TokenType.OperatorPipe && token.Type != SyntaxAnalysis.TokenType.SymbolComma) { throw new Exception($"Expected next token to be of type either comma symbol or pipe operator, but got '{token.Type}'"); } // There is another value. else if (token.Type == SyntaxAnalysis.TokenType.SymbolComma) { // Skip comma token. context.Stream.Skip(); // Recursively invoke a new pipe args parser instance. List <Expr> nextArguments = new PipeArgsParser().Parse(context); // Append resulting arguments. arguments.AddRange(nextArguments); } // Return the resulting argument list. return(arguments); }
public Expr Parse(ParserContext context) { // Ensure current return keyword. context.Stream.EnsureCurrent(SyntaxAnalysis.TokenType.KeywordReturn); // Skip over the return keyword. context.Stream.Skip(); // Capture the current token. Token token = context.Stream.Current; // There is no return expression. if (token.Type == SyntaxAnalysis.TokenType.SymbolSemiColon) { // Skip the semi-colon. context.Stream.Skip(); // TODO: Should return void? Investigate. // Return null as no expression/return value was captured. return(null); } // Otherwise, invoke the expression parser. Expr expr = new ExprParser().Parse(context); // Ensure current is a semi-colon. context.Stream.EnsureCurrent(SyntaxAnalysis.TokenType.SymbolSemiColon); // Skip the semi-colon. context.Stream.Skip(); // Return the expression. return(expr); }
public VarDeclareExpr Parse(ParserContext context) { // Parse the type. Type type = new TypeParser().Parse(context); // Create the variable declaration & link the type. VarDeclareExpr declaration = new VarDeclareExpr(type, null); // Invoke identifier parser. string identifier = new IdentifierParser().Parse(context); // Assign the name. declaration.SetName(identifier); // Capture current token. Token token = context.Stream.Current; // A value is being assigned. if (token.Type == SyntaxAnalysis.TokenType.OperatorAssignment) { // Skip the assignment operator. context.Stream.Skip(); // Parse value. Expr value = new ExprParser().Parse(context); // Assign value. declaration.Value = value; } // Return the resulting declaration construct. return(declaration); }
public Expr Parse(TokenStream stream) { // Skip return keyword. stream.Skip(TokenType.KeywordReturn); // Look at the next token. Token nextToken = stream.Peek(); // There is no return expression. if (nextToken.Type == TokenType.SymbolSemiColon) { // Skip to the semi-colon. stream.Skip(TokenType.SymbolSemiColon); // Return null as no expression/return value was captured. return(null); } // Otherwise, invoke the expression parser. Expr expr = new ExprParser().Parse(stream); // Consume semi-colon after the expression. stream.Skip(TokenType.SymbolSemiColon); return(expr); }
public Expr Parse(TokenStream stream) { // Skip to parentheses start token. stream.Skip(TokenType.SymbolParenthesesL); // Parse the expression. Expr expr = new ExprParser().Parse(stream); // Skip to parentheses end token. stream.Skip(TokenType.SymbolParenthesesR); return(expr); }
public ArrayExpr Parse(ParserContext context) { // Ensure current token is bracket start. context.Stream.EnsureCurrent(TokenType.SymbolBracketL); // Skip bracket start token. context.Stream.Skip(); // Create the value buffer list. List <Expr> values = new List <Expr>(); // Begin parsing values. context.Stream.NextUntil(TokenType.SymbolBracketR, (Token token) => { // Invoke expression parser. Expr value = new ExprParser().Parse(context); // Add the captured expression to the list. values.Add(value); // Capture current token. Token current = context.Stream.Current; // Ensure current token is either semi-colon or bracket end. if (current.Type != TokenType.SymbolComma && current.Type != TokenType.SymbolBracketR) { throw new Exception($"Expected token in array expression to be of type comma or bracket end, but got '{current.Type}'"); } // Skip comma token. else if (current.Type == TokenType.SymbolComma) { context.Stream.Skip(); } // Signal to update iterator to current token, since parsers where invoked. return(true); }); // Ensure current token is bracket end. context.Stream.EnsureCurrent(TokenType.SymbolBracketR); // Skip bracket end token. context.Stream.Skip(); // Create the resulting array construct. ArrayExpr arrayExpr = new ArrayExpr(this.type, values.ToArray()); // Return the resulting array construct. return(arrayExpr); }
public List <Expr> Parse(ParserContext context) { // Ensure current token is parentheses start. context.Stream.EnsureCurrent(TokenType.SymbolParenthesesL); // Skip parentheses start. context.Stream.Skip(); // Create the argument list result. List <Expr> args = new List <Expr>(); // Contains at least one argument. if (context.Stream.Current.Type != TokenType.SymbolParenthesesR) { while (true) { // Invoke the expression parser to parse the argument. Expr arg = new ExprParser().Parse(context); // Append the parsed argument. args.Add(arg); // Capture the current token's type. TokenType currentTokenType = context.Stream.Current.Type; // Arguments ended. if (currentTokenType == TokenType.SymbolParenthesesR) { break; } // Otherwise, expect a comma. else if (currentTokenType != TokenType.SymbolComma) { throw new Exception("Unexpected token in function call argument list"); } // Skip token. context.Stream.Skip(); } } // Ensure current token is parentheses end. context.Stream.EnsureCurrent(TokenType.SymbolParenthesesR); // Skip parentheses end. context.Stream.Skip(); return(args); }
public Function Parse(TokenStream stream) { // TODO: Use expression? Maybe add it to the body block? // Parse the expression. Expr expr = new ExprParser().Parse(stream); // Create the anonymous function. var function = new Function(); // Set the function name to anonymous. function.SetNameAnonymous(); // Create default prototype. function.CreatePrototype(); // TODO: Finish implementing (continue Kaleidoscope tutorial). Block body = function.CreateBody(); return(function); }
public StructProperty Parse(ParserContext context) { // Invoke identifier parser. string identifier = new IdentifierParser().Parse(context); // Ensure current token is symbol colon. context.Stream.EnsureCurrent(TokenType.SymbolColon); // Skip colon symbol token. context.Stream.Skip(); // Invoke expression parser to capture the value. Expr value = new ExprParser().Parse(context); // Create the resulting property construct. StructProperty property = new StructProperty(identifier, value, this.index); // Return the resulting property construct. return(property); }
public VarDeclareExpr Parse(TokenStream stream) { // Consume the type string. var typeValue = stream.Next().Value; // Create the type. var type = new Type(typeValue); // Create the variable declaration & link the type. var declaration = new VarDeclareExpr(type, null); // Consume the variable name. var name = stream.Next().Value; // Ensure captured name is not null nor empty. if (string.IsNullOrEmpty(name)) { throw new Exception("Unexpected variable declaration identifier to be null or empty"); } // Assign the name. declaration.SetName(name); // Peek next token for value. Token nextToken = stream.Peek(); // Value is being assigned. if (nextToken.Type == TokenType.OperatorAssignment) { // Skip over the Assignment operator stream.Skip(); // Parse value. Expr value = new ExprParser().Parse(stream); // Assign value. declaration.Value = value; } return(declaration); }
public List <Expr> Parse(TokenStream stream) { // Create the argument list result. var args = new List <Expr>(); // Contains at least one argument. if (stream.Get().Type != TokenType.SymbolParenthesesL) { while (true) { // Invoke the expression parser to parse the argument. Expr arg = new ExprParser().Parse(stream); // Append the parsed argument. args.Add(arg); TokenType currentTokenType = stream.Get().Type; // Arguments ended. if (currentTokenType == TokenType.SymbolParenthesesR) { break; } // Otherwise, expect a comma. else if (currentTokenType != TokenType.SymbolComma) { throw new Exception("Unexpected token in function call argument list"); } // Skip token. stream.Skip(); } } return(args); }