Skip to content

Commit 4efad2b

Browse files
author
Timo Lehnertz
committed
Fixed missing parameter ParsingException constructor and fixed "((int) 0)" not parsing correctly
1 parent 75f0015 commit 4efad2b

File tree

3 files changed

+33
-26
lines changed

3 files changed

+33
-26
lines changed

src/parsing/FunctionParser.php

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
2-
declare(strict_types = 1);
2+
3+
declare(strict_types=1);
4+
35
namespace TimoLehnertz\formula\parsing;
46

57
use TimoLehnertz\formula\expression\FunctionExpression;
@@ -12,81 +14,81 @@
1214

1315
/**
1416
* @author Timo Lehnertz
17+
* <Function value> ::= <Type>? <FunctionArguments> "->" <Expression> | ("{" <CodeBlock> "}")
1518
*/
1619
class FunctionParser extends Parser {
1720

1821
private readonly bool $parseStatement;
1922

2023
public function __construct(bool $parseStatement) {
21-
if($parseStatement) {
22-
parent::__construct('function statement');
23-
} else {
24-
parent::__construct('function value');
25-
}
24+
parent::__construct($parseStatement ? 'function statement' : 'function value');
2625
$this->parseStatement = $parseStatement;
2726
}
2827

2928
protected function parsePart(Token $firstToken): ParserReturn {
30-
// var_dump('Moin');
31-
if(!$this->parseStatement) {
29+
if (!$this->parseStatement) {
3230
try {
3331
$parsedReturnType = (new TypeParser(false))->parse($firstToken);
3432
$token = $parsedReturnType->nextToken;
35-
} catch(ParsingException | ParsingSkippedException $e) {
33+
} catch (ParsingException | ParsingSkippedException) {
3634
$parsedReturnType = null;
3735
$token = $firstToken;
3836
}
3937
} else {
40-
if($firstToken->id === Token::KEYWORD_VOID) {
38+
if ($firstToken->id === Token::KEYWORD_VOID) {
4139
$parsedReturnType = new ParserReturn(new VoidType(), $firstToken->next());
4240
} else {
4341
$parsedReturnType = (new TypeParser(false))->parse($firstToken);
4442
}
4543
$token = $parsedReturnType->nextToken;
4644
}
47-
if($token === null) {
45+
if ($token === null) {
4846
throw new ParsingSkippedException();
4947
}
50-
if($this->parseStatement) {
51-
if($token->id !== Token::IDENTIFIER) {
48+
if ($this->parseStatement) {
49+
if ($token->id !== Token::IDENTIFIER) {
5250
throw new ParsingSkippedException();
5351
}
5452
$identifier = $token->value;
5553
$token = $token->next();
56-
if($token === null) {
54+
if ($token === null) {
5755
throw new ParsingSkippedException();
5856
}
5957
}
6058
$functionArgumentParser = new EnumeratedParser('Function arguments', new InnerFunctionArgumentParser(false), Token::BRACKETS_OPEN, Token::COMMA, Token::BRACKETS_CLOSED, false, true);
61-
$parsedArguments = $functionArgumentParser->parse($token);
59+
try {
60+
$parsedArguments = $functionArgumentParser->parse($token);
61+
} catch(ParsingException) {
62+
throw new ParsingSkippedException();
63+
}
6264
$token = $parsedArguments->nextToken;
6365
$normalArgs = [];
6466
$vArg = null;
65-
for($i = 0;$i < count($parsedArguments->parsed);$i++) {
67+
for ($i = 0; $i < count($parsedArguments->parsed); $i++) {
6668
$arg = $parsedArguments->parsed[$i];
67-
if($arg instanceof InnerFunctionArgument) {
69+
if ($arg instanceof InnerFunctionArgument) {
6870
$normalArgs[] = $arg;
69-
} else if($arg instanceof InnerVargFunctionArgument) {
71+
} else if ($arg instanceof InnerVargFunctionArgument) {
7072
$vArg = $arg;
71-
if($i !== count($parsedArguments->parsed) - 1) {
73+
if ($i !== count($parsedArguments->parsed) - 1) {
7274
throw new ParsingException(ParsingException::ERROR_VARG_NOT_LAST);
7375
}
7476
}
7577
}
76-
if(!$this->parseStatement) {
78+
if (!$this->parseStatement) {
7779
try {
7880
$parsedCodeBlock = (new ExpressionFunctionBodyParser())->parse($token);
79-
} catch(ParsingSkippedException $e) {
81+
} catch (ParsingSkippedException $e) {
8082
$parsedCodeBlock = (new CodeBlockParser(false, false))->parse($token);
81-
if($parsedReturnType === null) {
83+
if ($parsedReturnType === null) {
8284
throw new ParsingException(ParsingException::ERROR_UNEXPECTED_TOKEN, $token, 'Function requires return type');
8385
}
8486
}
8587
} else {
8688
$parsedCodeBlock = (new CodeBlockParser(false, false))->parse($token);
8789
}
8890
$innerArgs = new InnerFunctionArgumentList($normalArgs, $vArg);
89-
if($this->parseStatement) {
91+
if ($this->parseStatement) {
9092
$parsed = new FunctionStatement($parsedReturnType->parsed, $identifier, $innerArgs, $parsedCodeBlock->parsed);
9193
} else {
9294
$parsed = new FunctionExpression($parsedReturnType?->parsed ?? null, $innerArgs, $parsedCodeBlock->parsed);

src/parsing/InnerFunctionArgumentParser.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ protected function parsePart(Token $firstToken): ParserReturn {
3232
$token = $token->requireNext();
3333
}
3434
if($token->id !== Token::IDENTIFIER) {
35-
throw new ParsingException(ParsingException::ERROR_UNEXPECTED_TOKEN, 'Expected identifier');
35+
throw new ParsingException(ParsingException::ERROR_UNEXPECTED_TOKEN, $token, 'Expected identifier');
3636
}
3737
$identifier = $token->value;
3838
$parsedExpression = null;
3939
if($token->hasNext() && $token->next()->id === Token::ASSIGNMENT) {
4040
if($isVarg) {
41-
throw new ParsingException(ParsingException::ERROR_UNEXPECTED_TOKEN, 'Vargs can\'t have a default initilizer');
41+
throw new ParsingException(ParsingException::ERROR_UNEXPECTED_TOKEN, $token, 'Vargs can\'t have a default initilizer');
4242
}
4343
$parsedExpression = (new ExpressionParser())->parse($token->next()->next());
4444
$token = $parsedExpression->nextToken;

test/FormulaTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ public function testFunctionWithNoParams(): void {
244244

245245
public function testVoidFunction(): void {
246246
new Formula('void r() {}');
247-
$this->assertTrue(true); // assert no exception
247+
$this->assertTrue(true); // assert no exception was thrown
248248
}
249249

250250
public function testRecursiveFunction(): void {
@@ -261,4 +261,9 @@ public function testAnonymousVoidFunction(): void {
261261
$formula = new Formula('int b = 0;function(int) -> void a = void (int a) {b = a;}; a(1); return b;');
262262
$this->assertEquals(1, $formula->calculate()->toPHPValue());
263263
}
264+
265+
public function testGetNthBit(): void {
266+
$formula = new Formula('((((int) 0b011) >> 1) & 1)');
267+
$this->assertEquals(1, $formula->calculate()->toPHPValue());
268+
}
264269
}

0 commit comments

Comments
 (0)