From 01df92b798f53292757ccf1678d295a75a017d4b Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Wed, 1 May 2024 17:11:10 -0500 Subject: [PATCH] More support for labels --- src/main/antlr/BoxTemplateGrammar.g4 | 4 +- src/main/antlr/CFTemplateGrammar.g4 | 4 +- .../compiler/parser/BoxTemplateParser.java | 20 +++++-- .../compiler/parser/CFTemplateParser.java | 20 +++++-- .../TestCases/phase1/LabeledLoopTest.java | 53 +++++++++++++++++++ 5 files changed, 91 insertions(+), 10 deletions(-) diff --git a/src/main/antlr/BoxTemplateGrammar.g4 b/src/main/antlr/BoxTemplateGrammar.g4 index 4c5468d2a..4640db162 100644 --- a/src/main/antlr/BoxTemplateGrammar.g4 +++ b/src/main/antlr/BoxTemplateGrammar.g4 @@ -245,14 +245,14 @@ while: // or... break: - COMPONENT_OPEN PREFIX BREAK ( + COMPONENT_OPEN PREFIX BREAK attribute* ( COMPONENT_CLOSE | COMPONENT_SLASH_CLOSE ); // or... continue: - COMPONENT_OPEN PREFIX CONTINUE ( + COMPONENT_OPEN PREFIX CONTINUE attribute* ( COMPONENT_CLOSE | COMPONENT_SLASH_CLOSE ); diff --git a/src/main/antlr/CFTemplateGrammar.g4 b/src/main/antlr/CFTemplateGrammar.g4 index ea51441bd..457b71e55 100644 --- a/src/main/antlr/CFTemplateGrammar.g4 +++ b/src/main/antlr/CFTemplateGrammar.g4 @@ -281,14 +281,14 @@ while: // or... break: - COMPONENT_OPEN PREFIX BREAK ( + COMPONENT_OPEN PREFIX BREAK attribute* ( COMPONENT_CLOSE | COMPONENT_SLASH_CLOSE ); // or... continue: - COMPONENT_OPEN PREFIX CONTINUE ( + COMPONENT_OPEN PREFIX CONTINUE attribute* ( COMPONENT_CLOSE | COMPONENT_SLASH_CLOSE ); diff --git a/src/main/java/ortus/boxlang/compiler/parser/BoxTemplateParser.java b/src/main/java/ortus/boxlang/compiler/parser/BoxTemplateParser.java index cbe05319f..ce623bb0c 100644 --- a/src/main/java/ortus/boxlang/compiler/parser/BoxTemplateParser.java +++ b/src/main/java/ortus/boxlang/compiler/parser/BoxTemplateParser.java @@ -539,11 +539,25 @@ private BoxStatement toAst( File file, IncludeContext node ) { } private BoxStatement toAst( File file, ContinueContext node ) { - return new BoxContinue( getPosition( node ), getSourceText( node ) ); + List annotations = new ArrayList<>(); + + for ( var attr : node.attribute() ) { + annotations.add( toAst( file, attr ) ); + } + BoxExpression labelSearch = findExprInAnnotations( annotations, "label", false, null, "continue", getPosition( node ) ); + String label = getBoxExprAsString( labelSearch, "label", false ); + return new BoxContinue( label, getPosition( node ), getSourceText( node ) ); } private BoxStatement toAst( File file, BreakContext node ) { - return new BoxBreak( getPosition( node ), getSourceText( node ) ); + List annotations = new ArrayList<>(); + + for ( var attr : node.attribute() ) { + annotations.add( toAst( file, attr ) ); + } + BoxExpression labelSearch = findExprInAnnotations( annotations, "label", false, null, "break", getPosition( node ) ); + String label = getBoxExprAsString( labelSearch, "label", false ); + return new BoxBreak( label, getPosition( node ), getSourceText( node ) ); } private BoxStatement toAst( File file, WhileContext node ) { @@ -569,7 +583,7 @@ private BoxStatement toAst( File file, WhileContext node ) { body.addAll( toAst( file, node.statements() ) ); } BoxExpression labelSearch = findExprInAnnotations( annotations, "label", false, null, "while", getPosition( node ) ); - String label = getBoxExprAsString( labelSearch, "condition", false ); + String label = getBoxExprAsString( labelSearch, "label", false ); return new BoxWhile( label, condition, body, getPosition( node ), getSourceText( node ) ); } diff --git a/src/main/java/ortus/boxlang/compiler/parser/CFTemplateParser.java b/src/main/java/ortus/boxlang/compiler/parser/CFTemplateParser.java index 5c04b7758..1356fbb80 100644 --- a/src/main/java/ortus/boxlang/compiler/parser/CFTemplateParser.java +++ b/src/main/java/ortus/boxlang/compiler/parser/CFTemplateParser.java @@ -661,11 +661,25 @@ private BoxStatement toAst( File file, IncludeContext node ) { } private BoxStatement toAst( File file, ContinueContext node ) { - return new BoxContinue( getPosition( node ), getSourceText( node ) ); + List annotations = new ArrayList<>(); + + for ( var attr : node.attribute() ) { + annotations.add( toAst( file, attr ) ); + } + BoxExpression labelSearch = findExprInAnnotations( annotations, "label", false, null, "continue", getPosition( node ) ); + String label = getBoxExprAsString( labelSearch, "label", false ); + return new BoxContinue( label, getPosition( node ), getSourceText( node ) ); } private BoxStatement toAst( File file, BreakContext node ) { - return new BoxBreak( getPosition( node ), getSourceText( node ) ); + List annotations = new ArrayList<>(); + + for ( var attr : node.attribute() ) { + annotations.add( toAst( file, attr ) ); + } + BoxExpression labelSearch = findExprInAnnotations( annotations, "label", false, null, "break", getPosition( node ) ); + String label = getBoxExprAsString( labelSearch, "label", false ); + return new BoxBreak( label, getPosition( node ), getSourceText( node ) ); } private BoxStatement toAst( File file, WhileContext node ) { @@ -692,7 +706,7 @@ private BoxStatement toAst( File file, WhileContext node ) { } BoxExpression labelSearch = findExprInAnnotations( annotations, "label", false, null, "while", getPosition( node ) ); - String label = getBoxExprAsString( labelSearch, "condition", false ); + String label = getBoxExprAsString( labelSearch, "label", false ); return new BoxWhile( label, condition, body, getPosition( node ), getSourceText( node ) ); } diff --git a/src/test/java/TestCases/phase1/LabeledLoopTest.java b/src/test/java/TestCases/phase1/LabeledLoopTest.java index f2e771804..17fcdd8e9 100644 --- a/src/test/java/TestCases/phase1/LabeledLoopTest.java +++ b/src/test/java/TestCases/phase1/LabeledLoopTest.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import ortus.boxlang.compiler.parser.BoxSourceType; import ortus.boxlang.runtime.BoxRuntime; import ortus.boxlang.runtime.context.IBoxContext; import ortus.boxlang.runtime.context.ScriptingRequestBoxContext; @@ -70,6 +71,58 @@ public void testSimpleLabeledWhile() { assertThat( variables.get( result ) ).isEqualTo( 1 ); } + @Test + public void testSimpleLabeledWhileContinue() { + + instance.executeSource( + """ + result = 0 + mylabel : while( true ) { + result ++ + if( result > 2 ) break; + continue mylabel; + result ++ + } + """, + context ); + assertThat( variables.get( result ) ).isEqualTo( 3 ); + } + + @Test + public void testSimpleLabeledWhileTag() { + + instance.executeSource( + """ + + + + + + + """, + context, BoxSourceType.BOXTEMPLATE ); + assertThat( variables.get( result ) ).isEqualTo( 1 ); + } + + @Test + public void testSimpleLabeledWhileContinueTag() { + + instance.executeSource( + """ + + + + + + + + + + """, + context, BoxSourceType.BOXTEMPLATE ); + assertThat( variables.get( result ) ).isEqualTo( 3 ); + } + @Test public void testSimpleLabeledDoWhile() {