/* * { 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); }
/* * [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); }
/* * => [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); }
/* * 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); }