Example #1
0
        /*
         *  { code... }
         */
        CodeBlock ParseBlockWithoutCaptures()
        {
            var code = CodeBlock.Create(unit.Location);

            unit.Expect(LoreToken.OpenBrace);
            while (!unit.Match(LoreToken.CloseBrace))
            {
                code.AddChild(ParseStatement());
            }
            unit.Expect(LoreToken.CloseBrace);
            return(code);
        }
Example #2
0
        /*
         *  [captures...] { code... }
         */
        CodeBlock ParseBlockWithCaptures()
        {
            var capturedBlock = CodeBlock.Create(unit.Location);

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

            // Parse the actual block
            var pureBlock = ParseBlockWithoutCaptures();

            // Merge the block with the captures
            capturedBlock.Merge(pureBlock);
            return(capturedBlock);
        }
Example #3
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);
        }
Example #4
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);
        }