From eaef408c2d03216f0a2896d2ac45aad0bec08aa7 Mon Sep 17 00:00:00 2001 From: fglock Date: Thu, 10 Oct 2024 20:46:57 +0200 Subject: [PATCH] add tests --- .../java/org/perlonjava/astnode/For3Node.java | 4 +- .../perlonjava/codegen/EmitterVisitor.java | 2 +- .../org/perlonjava/parser/StringParser.java | 4 +- .../perlonjava/runtime/ErrorMessageUtil.java | 6 +- .../org/perlonjava/PerlExecutionTest.java | 1 + src/test/resources/statement.pl | 128 ++++++++++++++++++ 6 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/statement.pl diff --git a/src/main/java/org/perlonjava/astnode/For3Node.java b/src/main/java/org/perlonjava/astnode/For3Node.java index bcd129d6..b82c341a 100644 --- a/src/main/java/org/perlonjava/astnode/For3Node.java +++ b/src/main/java/org/perlonjava/astnode/For3Node.java @@ -99,13 +99,13 @@ public For3Node(String labelName, boolean useNewScope, Node initialization, Node private static boolean isMagicWhile(Node node) { String operator = ""; if (node instanceof OperatorNode) { - // "<", "each", "glob" + // "<>", "each", "glob" operator = ((OperatorNode) node).operator; } else if (node instanceof BinaryOperatorNode) { // "readline" operator = ((BinaryOperatorNode) node).operator; } - return operator.equals("<") || + return operator.equals("<>") || operator.equals("each") || operator.equals("glob") || operator.equals("readline"); diff --git a/src/main/java/org/perlonjava/codegen/EmitterVisitor.java b/src/main/java/org/perlonjava/codegen/EmitterVisitor.java index a059b59b..896a1e33 100644 --- a/src/main/java/org/perlonjava/codegen/EmitterVisitor.java +++ b/src/main/java/org/perlonjava/codegen/EmitterVisitor.java @@ -1046,7 +1046,7 @@ public void visit(OperatorNode node) { case "not": handleUnaryBuiltin(node, "not"); break; - case "<": + case "<>": handleDiamondBuiltin(node); break; case "abs": diff --git a/src/main/java/org/perlonjava/parser/StringParser.java b/src/main/java/org/perlonjava/parser/StringParser.java index 398c2103..3e951642 100644 --- a/src/main/java/org/perlonjava/parser/StringParser.java +++ b/src/main/java/org/perlonjava/parser/StringParser.java @@ -532,8 +532,8 @@ public static Node parseRawString(Parser parser, String operator) { if (operator.equals("<") || operator.equals("<<") || operator.equals("'") || operator.equals("\"") || operator.equals("/") || operator.equals("//") || operator.equals("`")) { parser.tokenIndex--; // will reparse the quote - if (operator.equals("<<")) { - operator = "<"; + if (operator.equals("<") || operator.equals("<<")) { + operator = "<>"; } } ParsedString rawStr; diff --git a/src/main/java/org/perlonjava/runtime/ErrorMessageUtil.java b/src/main/java/org/perlonjava/runtime/ErrorMessageUtil.java index c78542c2..258eab4a 100644 --- a/src/main/java/org/perlonjava/runtime/ErrorMessageUtil.java +++ b/src/main/java/org/perlonjava/runtime/ErrorMessageUtil.java @@ -136,7 +136,11 @@ public int getLineNumber(int index) { // Count newlines from the last processed index to the current index for (int i = tokenIndex + 1; i <= index; i++) { - if (tokens.get(i).type == LexerTokenType.NEWLINE) { + LexerToken tok = tokens.get(i); + if (tok.type == LexerTokenType.EOF) { + break; + } + if (tok.type == LexerTokenType.NEWLINE) { lastLineNumber++; } } diff --git a/src/test/java/org/perlonjava/PerlExecutionTest.java b/src/test/java/org/perlonjava/PerlExecutionTest.java index f4c7ca3b..c656f336 100644 --- a/src/test/java/org/perlonjava/PerlExecutionTest.java +++ b/src/test/java/org/perlonjava/PerlExecutionTest.java @@ -44,6 +44,7 @@ void tearDown() { "flipflop.pl", "regex.pl", "regexreplace.pl", + "statement.pl", "split.pl", "transliterate.pl", "array.pl", diff --git a/src/test/resources/statement.pl b/src/test/resources/statement.pl new file mode 100644 index 00000000..9750f72a --- /dev/null +++ b/src/test/resources/statement.pl @@ -0,0 +1,128 @@ +use 5.32.0; +use strict; +use feature 'say'; +use feature 'isa'; + +# Test variable assignment and modification +my $a = 15; +my $x = $a; +print "not " if $x != 15; say "ok # \$x is 15"; + +$a = 12; +print "not " if $a != 12; say "ok # \$a is 12"; + +# Test if/else +my $if_test = 10; +if ($if_test > 5) { + print "not " if $if_test <= 5; say "ok # if statement works"; +} else { + print "not "; say "ok # if statement works"; +} + +# Test if/elsif/else +my $elsif_test = 15; +if ($elsif_test < 10) { + print "not "; say "ok # elsif statement works"; +} elsif ($elsif_test > 20) { + print "not "; say "ok # elsif statement works"; +} else { + print "not " if $elsif_test < 10 || $elsif_test > 20; say "ok # elsif statement works"; +} + +# Test unless +my $unless_test = 5; +unless ($unless_test > 10) { + print "not " if $unless_test > 10; say "ok # unless statement works"; +} + +# Test while loop +my $while_counter = 0; +while ($while_counter < 5) { + $while_counter++; +} +print "not " if $while_counter != 5; say "ok # while loop works"; + +# Test until loop +my $until_counter = 0; +until ($until_counter == 5) { + $until_counter++; +} +print "not " if $until_counter != 5; say "ok # until loop works"; + +# Test for loop (C-style, 3-argument) +my $for_sum = 0; +for (my $i = 0; $i < 5; $i++) { + $for_sum += $i; +} +print "not " if $for_sum != 10; say "ok # C-style for loop works"; + +# Test for loop (list iteration) with continue block +my @list = (1, 2, 3, 4, 5); +my $list_sum = 0; +my $continue_count = 0; +for my $item (@list) { + $list_sum += $item; +} continue { + $continue_count++; +} +print "not " if $list_sum != 15; say "ok # list iteration for loop works"; +print "not " if $continue_count != 5; say "ok # continue block in list iteration for loop works"; + +# Test while loop with continue block +my $while_sum = 0; +my $while_continue_count = 0; +while ($while_continue_count < 5) { + $while_sum += $while_continue_count; + $while_continue_count++; +} continue { + $while_sum++; +} +print "not " if $while_sum != 15; say "ok # while loop with continue block works"; + +# Test return statement +sub test_return { + return 42; +} +my $return_value = test_return(); +print "not " if $return_value != 42; say "ok # return statement works"; + +# Test nested loops +my $nested_sum = 0; +for my $i (1..3) { + for my $j (1..3) { + $nested_sum += $i * $j; + } +} +print "not " if $nested_sum != 36; say "ok # nested loops work"; + +# Test do-while loop +my $do_while_counter = 0; +do { + $do_while_counter++; +} while ($do_while_counter < 5); +print "not " if $do_while_counter != 5; say "ok # do-while loop works"; + +# Test loop with empty body +my $empty_loop_counter = 0; +while ($empty_loop_counter < 5) { + $empty_loop_counter++; + # Empty body +} +print "not " if $empty_loop_counter != 5; say "ok # loop with empty body works"; + +# Test conditional with complex expression +my $complex_condition = (5 > 3 && 10 < 20) || (15 == 15 && 7 != 8); +if ($complex_condition) { + print "not " if !$complex_condition; say "ok # conditional with complex expression works"; +} else { + print "not "; say "ok # conditional with complex expression works"; +} + +# Test scope in loops +my $scope_test = 0; +for my $i (1..3) { + my $local_var = $i * 2; + $scope_test += $local_var; +} +print "not " if $scope_test != 12; say "ok # scope in loops works"; +