From b0165db87248c5fc2bbbcf41dbe78d0ceba36985 Mon Sep 17 00:00:00 2001 From: Pavel Shevaev Date: Fri, 22 Nov 2024 12:12:29 +0300 Subject: [PATCH] Improving blocks parsing in case of errors --- src/compile/antlr_proc.cs | 22 ++++++++++++++++------ tests/test_vm.cs | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/compile/antlr_proc.cs b/src/compile/antlr_proc.cs index 42ee252b..1426dac7 100644 --- a/src/compile/antlr_proc.cs +++ b/src/compile/antlr_proc.cs @@ -4914,7 +4914,7 @@ public override object VisitStmParal(bhlParser.StmParalContext ctx) LSP_AddSemanticToken(ctx.PARAL(), SemanticToken.Keyword); var block = ProcBlock(BlockType.PARAL, ctx.block()?.statement()); - if(block.children.Count == 0) + if(block == null) AddError(ctx, "empty paral blocks are not allowed"); return null; } @@ -4924,7 +4924,7 @@ public override object VisitStmParalAll(bhlParser.StmParalAllContext ctx) LSP_AddSemanticToken(ctx.PARAL_ALL(), SemanticToken.Keyword); var block = ProcBlock(BlockType.PARAL_ALL, ctx.block()?.statement()); - if(block.children.Count == 0) + if(block == null) AddError(ctx, "empty paral blocks are not allowed"); return null; } @@ -5123,11 +5123,16 @@ public override object VisitStmWhile(bhlParser.StmWhileContext ctx) PopBlock(ast); - return_found.Remove(PeekFuncDecl()); + BlockResetsCurrentFunctionReturnInfo(); return null; } + void BlockResetsCurrentFunctionReturnInfo() + { + return_found.Remove(PeekFuncDecl()); + } + public override object VisitStmDoWhile(bhlParser.StmDoWhileContext ctx) { LSP_AddSemanticToken(ctx.DO(), SemanticToken.Keyword); @@ -5158,7 +5163,7 @@ public override object VisitStmDoWhile(bhlParser.StmDoWhileContext ctx) PopBlock(ast); - return_found.Remove(PeekFuncDecl()); + BlockResetsCurrentFunctionReturnInfo(); return null; } @@ -5222,7 +5227,7 @@ public override object VisitStmFor(bhlParser.StmForContext ctx) local_scope.Exit(); PopScope(); - return_found.Remove(PeekFuncDecl()); + BlockResetsCurrentFunctionReturnInfo(); return null; } @@ -5653,10 +5658,15 @@ AST_Block ProcBlock(BlockType type, IParseTree[] sts) PopScope(); if(is_paral) - return_found.Remove(PeekFuncDecl()); + BlockResetsCurrentFunctionReturnInfo(); PopBlock(ast); + //NOTE: if there are no children, something is definitely wrong + // probably due to parsing errors + if(ast.children.Count == 0) + return null; + PeekAST().AddChild(ast); return ast; } diff --git a/tests/test_vm.cs b/tests/test_vm.cs index a77b0194..270d56c2 100644 --- a/tests/test_vm.cs +++ b/tests/test_vm.cs @@ -4185,6 +4185,31 @@ func int test() AssertEqual(3, Execute(vm, "test").result.PopRelease().num); CommonChecks(vm); } + + [Fact] + public void TestParseErrorInDoWhileBlockWithReturn() + { + string bhl = @" + + func int test() + { + string i; + do { + return i + } while(true) + } + "; + AssertError( + delegate() { + Compile(bhl); + }, + "incompatible types: 'int' and 'string'", + new PlaceAssert(bhl, @" + return i +---------------^" + ) + ); + } [Fact] public void TestBreakInDoWhile()