示例#1
0
        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);
        }
示例#2
0
        /*
         * (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);
        }
示例#3
0
 /// <summary>
 /// Adds an identifier.
 /// </summary>
 /// <returns>The identifier.</returns>
 /// <param name="identifier">Identifier.</param>
 public void AddIdentifier(NameExpression identifier)
 {
     Identifiers.Add(NamedParameter.Create(identifier));
 }
示例#4
0
        /*
         *  => [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);
        }