From 287880394244383f750ba614924a1a3fc037e9ff Mon Sep 17 00:00:00 2001 From: Paulo Mattos Date: Wed, 23 Dec 2020 16:28:04 -0300 Subject: [PATCH 1/2] =?UTF-8?q?Parse=20e=20bind=20de=20fun=C3=A7=C3=B5es?= =?UTF-8?q?=20locais?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Syntax/Binding/BinderTests.cs | 22 ++++++++++++++++ src/Compiler/CodeAnalysis/Binding/Binder.cs | 25 ++++++++----------- src/Compiler/CodeAnalysis/Syntax/Parser.cs | 20 +++++++++++++-- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/Compiler.Tests/CodeAnalysis/Syntax/Binding/BinderTests.cs b/src/Compiler.Tests/CodeAnalysis/Syntax/Binding/BinderTests.cs index e5a59d3..f068a55 100644 --- a/src/Compiler.Tests/CodeAnalysis/Syntax/Binding/BinderTests.cs +++ b/src/Compiler.Tests/CodeAnalysis/Syntax/Binding/BinderTests.cs @@ -1490,6 +1490,28 @@ function main() AssertDiagnostics(text, diagnostics); } + + [Fact] + public void Binder_LocalFunction_Declaration() + { + var text = @" + function a(x : int) + { + b(string(x)) + + function b(x : string) + { + + } + } + "; + + var diagnostics = new List() + { + }; + + AssertDiagnostics(text, diagnostics); + } private Compilation AssertDiagnostics(string text, List expectedDiagnostics, bool generateGraph = false) { diff --git a/src/Compiler/CodeAnalysis/Binding/Binder.cs b/src/Compiler/CodeAnalysis/Binding/Binder.cs index dbebd67..07a673a 100644 --- a/src/Compiler/CodeAnalysis/Binding/Binder.cs +++ b/src/Compiler/CodeAnalysis/Binding/Binder.cs @@ -63,7 +63,7 @@ public static BoundGlobalScope BindGlobalScope(ImmutableArray syntax .OfType(); foreach (var functionSyntax in functionDeclarations) { - var function = binder.BindFunctionDeclaration(functionSyntax); + var function = binder.BindFunctionDeclaration(functionSyntax, null); binder.Diagnostics.AddRange(function.BoundScope!.Diagnostics); } @@ -123,15 +123,6 @@ public static BoundProgram BindProgram(BoundGlobalScope globalScope) foreach (var function in functionsToLower) { - // Structs generate declartions for their constructors. However, these have no function bodies. - // We will skip attempting to lower the bodies for these and allow the Emitter to automatically - // generate the code necessary. This will avoid the potential of reporting diagnostic errors to - // the user for code they never wrote. - if (function.ReturnType is StructSymbol && function.Name.EndsWith(".ctor")) - { - continue; - } - Debug.Assert(function.BoundScope != null); var binder = new Binder(function.BoundScope, function, function.Receiver); var body = binder.BindStatement(function.Declaration!.Body); @@ -160,7 +151,7 @@ private static BoundProgram EmptyProgram(BoundGlobalScope globalScope) ImmutableArray.Empty); } - private FunctionSymbol BindFunctionDeclaration(FunctionDeclarationSyntax syntax) + private FunctionSymbol BindFunctionDeclaration(FunctionDeclarationSyntax syntax, List? functionsToLower) { var parameters = ImmutableArray.CreateBuilder(); var seenParameterNames = new HashSet(); @@ -180,6 +171,12 @@ private FunctionSymbol BindFunctionDeclaration(FunctionDeclarationSyntax syntax) } } + var localFunctions = syntax.Body.Statements.OfType(); + foreach (var localFunction in localFunctions) + { + BindFunctionDeclaration(localFunction, functionsToLower); + } + var returnType = BindTypeClause(syntax.Type) ?? TypeSymbol.Void; var receiver = _type; var function = new FunctionSymbol(syntax.Identifier.Text, @@ -190,6 +187,7 @@ private FunctionSymbol BindFunctionDeclaration(FunctionDeclarationSyntax syntax) receiver); _scope.TryDeclareFunction(function); + functionsToLower?.Add(function); return function; } @@ -246,8 +244,7 @@ private void BindMemberBlockStatement(MemberBlockStatementSyntax syntax, List(); _scope = new BlockBoundScope(_scope); - foreach (var statementSyntax in syntax.Statements) + foreach (var statementSyntax in syntax.Statements.Where(s => s.Kind != SyntaxKind.FunctionDeclaration)) { var statement = BindStatement(statementSyntax); statements.Add(statement); diff --git a/src/Compiler/CodeAnalysis/Syntax/Parser.cs b/src/Compiler/CodeAnalysis/Syntax/Parser.cs index 73110b2..d46fd73 100644 --- a/src/Compiler/CodeAnalysis/Syntax/Parser.cs +++ b/src/Compiler/CodeAnalysis/Syntax/Parser.cs @@ -209,10 +209,21 @@ private MemberSyntax ParseFunctionDeclaration() var parameters = ParseParameterList(); var closeParenthesisToken = MatchToken(SyntaxKind.CloseParenthesisToken); var type = ParseOptionalTypeClause(); - var body = ParseBlockStatement(); + var body = ParseBlockStatementInternal(ParseFunctionStatement); return new FunctionDeclarationSyntax(_syntaxTree, functionKeyword, identifier, openParenthesisToken, parameters, closeParenthesisToken, type, body); } + private StatementSyntax ParseFunctionStatement() + { + switch (Current.Kind) + { + case SyntaxKind.FunctionKeyword: + return ParseFunctionDeclaration(); + default: + return ParseStatement(); + } + } + private SeparatedSyntaxList ParseParameterList() { return ParseList(SyntaxKind.CloseParenthesisToken, SyntaxKind.CommaToken, ParseParameter); @@ -410,6 +421,11 @@ private TypeClauseSyntax ParseTypeClause() } private BlockStatementSyntax ParseBlockStatement() + { + return ParseBlockStatementInternal(ParseStatement); + } + + private BlockStatementSyntax ParseBlockStatementInternal(Func func) { var statements = ImmutableArray.CreateBuilder(); var openBraceToken = MatchToken(SyntaxKind.OpenBraceToken); @@ -418,7 +434,7 @@ private BlockStatementSyntax ParseBlockStatement() { var startToken = Current; - var statement = ParseStatement(); + var statement = func(); statements.Add(statement); // If ParseStatement() did not consume any tokens, From 47d44a7b9f816001c98b4c002b19cc02122a6dd1 Mon Sep 17 00:00:00 2001 From: Paulo Mattos Date: Wed, 23 Dec 2020 16:38:10 -0300 Subject: [PATCH 2/2] =?UTF-8?q?Simplifica=20mudan=C3=A7as=20do=20parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Compiler/CodeAnalysis/Binding/Binder.cs | 2 +- src/Compiler/CodeAnalysis/Syntax/Parser.cs | 22 ++++----------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/Compiler/CodeAnalysis/Binding/Binder.cs b/src/Compiler/CodeAnalysis/Binding/Binder.cs index 07a673a..07f448f 100644 --- a/src/Compiler/CodeAnalysis/Binding/Binder.cs +++ b/src/Compiler/CodeAnalysis/Binding/Binder.cs @@ -244,7 +244,7 @@ private void BindMemberBlockStatement(MemberBlockStatementSyntax syntax, List ParseParameterList() { return ParseList(SyntaxKind.CloseParenthesisToken, SyntaxKind.CommaToken, ParseParameter); @@ -370,6 +359,8 @@ public StatementSyntax ParseStatement() return ParseContinueStatement(); case SyntaxKind.ReturnKeyword: return ParseReturnStatement(); + case SyntaxKind.FunctionKeyword: + return ParseFunctionDeclaration(); default: return ParseExpressionStatement(); } @@ -421,11 +412,6 @@ private TypeClauseSyntax ParseTypeClause() } private BlockStatementSyntax ParseBlockStatement() - { - return ParseBlockStatementInternal(ParseStatement); - } - - private BlockStatementSyntax ParseBlockStatementInternal(Func func) { var statements = ImmutableArray.CreateBuilder(); var openBraceToken = MatchToken(SyntaxKind.OpenBraceToken); @@ -434,7 +420,7 @@ private BlockStatementSyntax ParseBlockStatementInternal(Func f { var startToken = Current; - var statement = func(); + var statement = ParseStatement(); statements.Add(statement); // If ParseStatement() did not consume any tokens,