AssignStatement ParseAssignStatement() { var stmt = AssignStatement.Create(unit.Location); // Parse identifiers while (!unit.Match(LoreToken.Operator, "=")) { // Parse name var ident = ParseName(); var name = NamedParameter.Create(ident); // Parse type if (unit.Accept(LoreToken.Colon)) { name.SetType(ParseName()); } // Add the named parameter to the identifiers stmt.AddIdentifier(name); // Try parsing another identifier if (!unit.Match(LoreToken.Operator, "=")) { unit.Expect(LoreToken.Comma); } } unit.Expect(LoreToken.Operator, "="); // Parse expressions do { var expr = ParseExpression(); stmt.AddExpression(expr); } while (unit.Accept(LoreToken.Comma)); // Verify that all identifiers are satisfied var pluralizeExpression = stmt.ExpressionCount > 1 ? "s" : string.Empty; var pluralizeIdentifier = stmt.IdentifierCount > 1 ? "s" : string.Empty; if (stmt.IdentifierCount > stmt.ExpressionCount) { var count = stmt.IdentifierCount - stmt.ExpressionCount; var pluralizeDifference = count > 1 ? "s" : string.Empty; throw LoreException.Create(stmt.Location) .Describe($"Attempt to assign {stmt.ExpressionCount} expression{pluralizeExpression} to {stmt.IdentifierCount} identifier{pluralizeIdentifier}.") .Resolve($"Add more expressions or remove {count} identifier{pluralizeDifference}."); } if (stmt.IdentifierCount < stmt.ExpressionCount) { var count = stmt.ExpressionCount - stmt.IdentifierCount; var pluralizeDifference = count > 1 ? "s" : string.Empty; throw LoreException.Create(stmt.Location) .Describe($"Attempt to assign {stmt.ExpressionCount} expression{pluralizeExpression} to {stmt.IdentifierCount} identifier{pluralizeIdentifier}.") .Resolve($"Discard {count} expression{pluralizeDifference} by using the _ operator."); } return(stmt); }
/* * (parameter [, parameter...]) */ List <NamedParameter> ParseDeclarationArgumentList() { var parameters = new List <NamedParameter> (); unit.Expect(LoreToken.OpenParen); while (!unit.Match(LoreToken.CloseParen)) { // Parse the name of the parameter var parameter = NamedParameter.Create(ParseName()); // Parse the type of the parameter unit.Expect(LoreToken.Colon); parameter.SetType(ParseName()); parameters.Add(parameter); } unit.Expect(LoreToken.CloseParen); return(parameters); }
/// <summary> /// Adds an identifier. /// </summary> /// <returns>The identifier.</returns> /// <param name="identifier">Identifier.</param> public void AddIdentifier(NameExpression identifier) { Identifiers.Add(NamedParameter.Create(identifier)); }
/* * => [captures...] expression * or * => [captures...] { code... } * or * (parameters...) => [captures...] expression * or * (parameters...) => [captures...] { code... } */ LambdaExpression ParseLambda(TupleExpression argumentList = null) { var lambda = LambdaExpression.Create(unit.Location); // Parse parameter list if (argumentList == null || argumentList.Count == 0) { if (unit.Match(LoreToken.OpenParen)) { var parameters = ParseDeclarationArgumentList(); lambda.SetParameters(parameters); } } else { var lst = new List <NamedParameter> (); foreach (var argument in argumentList.Items) { var name = argument as NameExpression; if (name == null) { throw LoreException.Create(unit.Location).Describe($"Invalid parameter list in lambda declaration."); } lst.Add(NamedParameter.Create(name)); } lambda.SetParameters(lst); } // Expect arrow operator unit.Expect(LoreToken.Operator, "=>"); // Create master code block CodeBlock master = CodeBlock.Create(unit.Location); // Parse captures if (unit.Match(LoreToken.OpenBracket)) { // Parse captures unit.Expect(LoreToken.OpenBracket); while (!unit.Match(LoreToken.CloseBracket)) { var lex = unit.Read(); var capture = Capture.Create(unit, lex); master.AddCapture(capture); } unit.Expect(LoreToken.CloseBracket); } // Parse block if (unit.Match(LoreToken.OpenBrace)) { var block = ParseBlockWithoutCaptures(); // Merge captures master.Merge(block); } // Or parse expression else { // Create return statement for the result of the expression var retstmt = ReturnStatement.Create(unit.Location); retstmt.SetExpression(ParseExpression()); // Create a new block with the return statement var block = CodeBlock.Create(unit.Location); block.AddChild(retstmt); // Merge captures master.Merge(block); } // Set the lambda body lambda.SetBody(master); Console.WriteLine(lambda); return(lambda); }