Esempio n. 1
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);
        }
Esempio n. 2
0
        /*
         *  fn name (parameters...) -> type [captures...] {
         *      code...
         *  }
         */
        FunctionDeclaration ParseFunction()
        {
            var function = FunctionDeclaration.Create(unit.Location);

            unit.Expect(LoreToken.Keyword, "fn");

            // Read the name of the function
            var name = unit.Expect(LoreToken.Identifier);

            function.SetName(name.Value);

            // Read the parameter list
            if (unit.Match(LoreToken.OpenParen))
            {
                function.SetParameters(ParseDeclarationArgumentList());
            }

            // Read the return type
            if (unit.Accept(LoreToken.Operator, "->"))
            {
                var names = new List <NameExpression> ();
                while (unit.Match(LoreToken.Identifier))
                {
                    names.Add(ParseName());
                    if (!unit.Accept(LoreToken.Comma))
                    {
                        break;
                    }
                }
                if (names.Count == 1)
                {
                    function.SetReturnType(names [0]);
                }
                else
                {
                    function.SetReturnTuple(names);
                }
            }

            // Create the function body
            CodeBlock body = CodeBlock.Create(unit.Location);

            // Parse captures
            if (unit.Accept(LoreToken.OpenBracket))
            {
                while (!unit.Match(LoreToken.CloseBracket))
                {
                    var lex     = unit.Read();
                    var capture = Capture.Create(unit, lex);
                    body.AddCapture(capture);
                }
                unit.Expect(LoreToken.CloseBracket);
            }

            // Parse body
            if (unit.Match(LoreToken.OpenBrace))
            {
                body = ParseBlock();
            }
            else if (unit.Accept(LoreToken.Operator, "=>"))
            {
                body.AddChild(ParseExpression());
            }

            // Return the function
            function.SetBody(body);
            return(function);
        }
Esempio n. 3
0
 /// <summary>
 /// Merge this code block with another one.
 /// </summary>
 /// <param name="other">The other code block.</param>
 public void Merge(CodeBlock other)
 {
     Captures.AddRange(other.Captures.GroupBy(c => c.Identifier).Select(g => g.First()));
     Children.AddRange(other.Children);
 }
Esempio n. 4
0
 /// <summary>
 /// Sets the body of the function.
 /// </summary>
 /// <returns>The body.</returns>
 /// <param name="body">Body.</param>
 public void SetBody(CodeBlock body)
 {
     this.body = body;
 }
Esempio n. 5
0
 public virtual void Accept(CodeBlock block) => Update(block);