Skip to content

Commit

Permalink
fix parsing newlines
Browse files Browse the repository at this point in the history
  • Loading branch information
matronator committed May 25, 2024
1 parent 376b0a9 commit 0c7647c
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 43 deletions.
103 changes: 60 additions & 43 deletions src/Parsem/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class Parser
* 5: > --> (operator)
* 6: 10 --> (right side)
*/
public const CONDITION_PATTERN = '/(?<all><%\s?if\s(?<condition>(?<negation>!?)(?<left>\S+?)\s?(?<right>(?<operator>(?:<=|<|===|==|>=|>|!==|!=))\s?(?<value>.+?))?)\s?%>)/m';
public const CONDITION_PATTERN = '/(?<all><%\s?if\s(?<condition>(?<negation>!?)(?<left>\S+?)\s?(?<right>(?<operator>(?:<=|<|===|==|>=|>|!==|!=))\s?(?<value>.+?))?)\s?%>\n?)/m';

public const LITERALLY_NULL = '__:-LITERALLY_NULL-:__';

Expand Down Expand Up @@ -82,9 +82,9 @@ public static function parseConditions(string $string, array $arguments = [], in
}

$left = $matches['left'][0];
$negation = $matches['negation'][0];
$operator = $matches['operator'][0];
$right = $matches['value'][0];
$negation = $matches['negation'][0] ?? null;
$operator = $matches['operator'][0] ?? null;
$right = $matches['value'][0] ?? null;

if (str_starts_with($left, '$')) {
$left = substr($left, 1);
Expand Down Expand Up @@ -115,52 +115,69 @@ public static function parseConditions(string $string, array $arguments = [], in
}
}

if (str_starts_with($right, '$')) {
$right = substr($right, 1);
if (!isset($arguments[$right])) {
throw new RuntimeException("Variable '$right' not found in arguments.");
}
if (isset($right)) {
$rightNegated = false;

$right = $arguments[$right];
} else {
if ((str_starts_with($right, '"') && str_ends_with($right, '"')) || (str_starts_with($right, "'") && str_ends_with($right, "'"))) {
$right = substr($right, 1, -1);
} else if ($right === 'true') {
$right = true;
} else if ($right === 'false') {
$right = false;
} else if ($right === 'null') {
$right = null;
} else if (str_contains($right, '.')) {
$right = floatval($right);
} else if (is_numeric($right) && !str_contains($right, '.')) {
$right = intval($right);
if (str_starts_with($right, '!')) {
$rightNegated = true;
$right = substr($right, 1);
}

if (str_starts_with($right, '$')) {
$right = substr($right, 1);
if (!isset($arguments[$right])) {
throw new RuntimeException("Variable '$right' not found in arguments.");
}

$right = $arguments[$right];
} else {
$right = (string)$right;
if ((str_starts_with($right, '"') && str_ends_with($right, '"')) || (str_starts_with($right, "'") && str_ends_with($right, "'"))) {
$right = substr($right, 1, -1);
} else if ($right === 'true') {
$right = true;
} else if ($right === 'false') {
$right = false;
} else if ($right === 'null') {
$right = null;
} else if (str_contains($right, '.')) {
$right = floatval($right);
} else if (is_numeric($right) && !str_contains($right, '.')) {
$right = intval($right);
} else {
$right = (string)$right;
}
}

if ($rightNegated) {
$right = !$right;
}
}

if ($operator === '==') {
$result = $left == $right;
} elseif ($operator === '===') {
$result = $left === $right;
} elseif ($operator === '!=') {
$result = $left != $right;
} elseif ($operator === '!==') {
$result = $left !== $right;
} elseif ($operator === '<') {
$result = $left < $right;
} elseif ($operator === '<=') {
$result = $left <= $right;
} elseif ($operator === '>') {
$result = $left > $right;
} elseif ($operator === '>=') {
$result = $left >= $right;
if ($operator === '==') {
$result = $left == $right;
} elseif ($operator === '===') {
$result = $left === $right;
} elseif ($operator === '!=') {
$result = $left != $right;
} elseif ($operator === '!==') {
$result = $left !== $right;
} elseif ($operator === '<') {
$result = $left < $right;
} elseif ($operator === '<=') {
$result = $left <= $right;
} elseif ($operator === '>') {
$result = $left > $right;
} elseif ($operator === '>=') {
$result = $left >= $right;
} else if (!isset($operator)) {
$result = $left;
} else {
throw new RuntimeException("Unsupported operator '$operator'.");
}
} else {
throw new RuntimeException("Unsupported operator '$operator'.");
$result = $left;
}

preg_match('/<%\s?endif\s?%>/', $string, $endMatches, PREG_OFFSET_CAPTURE, $offset);
preg_match('/<%\s?endif\s?%>\n?/', $string, $endMatches, PREG_OFFSET_CAPTURE, $offset);
if (!$endMatches) {
throw new RuntimeException("Missing <% endif %> tag.");
}
Expand Down
36 changes: 36 additions & 0 deletions tests/Parsem/ParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,42 @@ public function testNestedNumericConditions()
$parsed = Parser::parseString($string, $args4);
Assert::equal(' World!', $parsed, 'All are false');
}

/** @testCase */
public function testNewLines()
{
$string = <<<EOT
Hello
<% if false %>
Amazing
<% endif %>
World!
EOT;

$expected = <<<EOT
Hello
World!
EOT;

$string2 = <<<EOT
Hello
<% if true %>
Amazing
<% endif %>
World!
EOT;

$expected2 = <<<EOT
Hello
Amazing
World!
EOT;

$parsed = Parser::parseString($string, []);
$parsed2 = Parser::parseString($string2, []);
Assert::equal($expected, $parsed, '(false) New lines are ignored.');
Assert::equal($expected2, $parsed2, '(true) New lines are ignored.');
}
}

(new ParserTest())->run();
3 changes: 3 additions & 0 deletions tests/Parsem/output/ParserTest.actual
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Hello

World!
2 changes: 2 additions & 0 deletions tests/Parsem/output/ParserTest.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Hello
World!

0 comments on commit 0c7647c

Please sign in to comment.