summaryrefslogtreecommitdiff
path: root/src/Parser/Parser.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Parser/Parser.php')
-rw-r--r--src/Parser/Parser.php149
1 files changed, 130 insertions, 19 deletions
diff --git a/src/Parser/Parser.php b/src/Parser/Parser.php
index 05d3726..b0b98f2 100644
--- a/src/Parser/Parser.php
+++ b/src/Parser/Parser.php
@@ -43,9 +43,17 @@ class Parser
$currentStatement = new CommentNode($currentToken);
$this->advance(1);
}
+
+ else if ($currentToken->type == TokenType::Identifier) {
+ if ($this->getNextToken()->literal == "=") {
+ $currentStatement = $this->parseVariableAssignment();
+ }
+ else {
+ $currentStatement = $this->parseFunctionCall();
+ }
+ }
else {
- #$currentStatement = $this->parseFunctionCall();
$error = sprintf("Unexpected %s at %d:%d" . PHP_EOL, $currentToken->value, $currentToken->line, $currentToken->column);
$this->addError($error);
@@ -182,7 +190,7 @@ class Parser
// skip const
$this->anticipateTokenAndSkip("const");
- $identifier = $this->getCurrentToken();
+ $identifier = new IdentifierNode($this->getCurrentToken());
$this->advance(1);
// skip :
@@ -190,17 +198,39 @@ class Parser
$type = $this->parseType();
+ $expression = null;
+ if ($this->getCurrentToken()->literal == "=") {
+ // skip =
+ $this->anticipateTokenAndSkip("=");
+
+ $expression = $this->parseExpression(
+ shouldBeMap: $type instanceof MapTypeDeclaration,
+ shouldBeFunction: $type instanceof TypeDeclaration and $type->left->literal == "function",
+ );
+ }
+
+ return new ConstVariableDeclaration(
+ $identifier,
+ $type,
+ $expression,
+ );
+ }
+
+ private function parseVariableAssignment(): Node
+ {
+ $identifier = new IdentifierNode($this->getCurrentToken());
+ $this->advance(1);
+
// skip =
$this->anticipateTokenAndSkip("=");
-
+
$expression = $this->parseExpression(
- shouldBeMap: $type instanceof MapTypeDeclaration,
- shouldBeFunction: $type instanceof TypeDeclaration and $type->left->literal == "function",
+ #shouldBeMap: $type instanceof MapTypeDeclaration,
+ #shouldBeFunction: $type instanceof TypeDeclaration and $type->left->literal == "function",
);
- return new ConstVariableDeclaration(
+ return new VariableAssignment(
$identifier,
- $type,
$expression,
);
}
@@ -291,6 +321,11 @@ class Parser
$this->advance(1);
}
+ else if ($currentToken->type == TokenType::PipePlaceholder) {
+ $currentExpression = new IdentifierNode($currentToken);
+ $this->advance(1);
+ }
+
else if ($currentToken->literal == "(") {
if ($this->getNextToken(2)->literal == ":") {
$currentExpression = $this->parseFunctionDefinition();
@@ -324,6 +359,10 @@ class Parser
return new Condition($currentExpression, $nextToken, $this->parseExpression(shouldBeMap: $shouldBeMap));
}
+ else if ($nextToken->literal == "[") {
+ return $this->parseArrayOrMapAccess($currentExpression);
+ }
+
else if ($nextToken->literal == "=>") {
$this->advance(1);
@@ -419,6 +458,28 @@ class Parser
}
}
+ private function parseArrayOrMapAccess(Node $arrayOrMap): Node
+ {
+ $items = [];
+
+ while ($this->getCurrentToken()->literal == "[") {
+ // skip current [
+ $this->anticipateTokenAndSkip("[");
+
+ $item = $this->parseExpression();
+
+ // skip last ]
+ $this->anticipateTokenAndSkip("]");
+
+ $items[] = $item;
+ }
+
+ return new ArrayMapAccessNode(
+ $arrayOrMap,
+ $items,
+ );
+ }
+
private function parseNumber(): Node
{
$currentToken = $this->getCurrentToken();
@@ -470,7 +531,7 @@ class Parser
continue;
}
- $identifier = $this->getCurrentToken();
+ $identifier = new IdentifierNode($this->getCurrentToken());
$this->advance(1);
// skip :
@@ -530,9 +591,14 @@ class Parser
$this->advance(1);
}
- /*else if ($currentToken->type == TokenType::Identifier) {
- $body[] = $this->parseFunctionCall();
- }*/
+ else if ($currentToken->type == TokenType::Identifier) {
+ if ($this->getNextToken()->literal == "=") {
+ $body[] = $this->parseVariableAssignment();
+ }
+ else {
+ $body[] = $this->parseFunctionCall();
+ }
+ }
else {
$error = sprintf("Unexpected %s at %d:%d" . PHP_EOL, $currentToken->value, $currentToken->line, $currentToken->column);
@@ -558,7 +624,7 @@ class Parser
private function parseFunctionCall(): Node
{
- $identifier = $this->getCurrentToken();
+ $identifier = new IdentifierNode($this->getCurrentToken());
$this->advance(1);
// skip first (
@@ -590,7 +656,7 @@ class Parser
// if "=" then identifier is name
if ($this->getNextToken()->literal == "=") {
- $identifier = $this->getCurrentToken();
+ $identifier = new IdentifierNode($this->getCurrentToken());
$this->advance(2);
$value = $this->parseExpression();
@@ -696,8 +762,16 @@ class Tree extends Node
class ConstVariableDeclaration extends Node
{
public function __construct(
- public Token $identifier,
+ public Node $identifier,
public Node|Token $type,
+ public Node|Token|null $expression,
+ ) {}
+}
+
+class VariableAssignment extends Node
+{
+ public function __construct(
+ public Node $identifier,
public Node|Token $expression,
) {}
}
@@ -733,6 +807,11 @@ class ArrayNode extends Node
public function __construct(
public array $values,
) {}
+
+ public function getValue(): array
+ {
+ return $this->values;
+ }
}
class MapNode extends Node
@@ -743,7 +822,13 @@ class MapNode extends Node
public function __construct(
public array $values,
) {}
+
+ public function getValue(): array
+ {
+ return $this->values;
+ }
}
+
class MapItemNode extends Node
{
public function __construct(
@@ -752,6 +837,17 @@ class MapItemNode extends Node
) {}
}
+class ArrayMapAccessNode extends Node
+{
+ public function __construct(
+ public ArrayNode|IdentifierNode $arrayOrMap,
+ /**
+ * @param Node[] $items
+ */
+ public array $items,
+ ) {}
+}
+
class OperatorExpression extends Node
{
public function __construct(
@@ -792,6 +888,11 @@ class NumberNode extends Node
public Token $token,
public int|float $value,
) {}
+
+ public function getValue(): int|float
+ {
+ return $this->value;
+ }
}
class StringNode extends Node
@@ -799,6 +900,11 @@ class StringNode extends Node
public function __construct(
public Token $token,
) {}
+
+ public function getValue(): string
+ {
+ return $this->token->value;
+ }
}
class BoolNode extends Node
@@ -806,6 +912,11 @@ class BoolNode extends Node
public function __construct(
public Token $token,
) {}
+
+ public function getValue(): bool
+ {
+ return filter_var($this->token->value, FILTER_VALIDATE_BOOLEAN);
+ }
}
class CommentNode extends Node
@@ -822,7 +933,7 @@ class FunctionDefinition extends Node
* @param FunctionDefinitionParameter[] $parameters
*/
public array $parameters,
- public TypeDeclaration $returnType,
+ public TypeDeclaration|ArrayTypeDeclaration|MapTypeDeclaration $returnType,
/**
* @param Node[] $body
*/
@@ -833,8 +944,8 @@ class FunctionDefinition extends Node
class FunctionDefinitionParameter extends Node
{
public function __construct(
- public Token $identifier,
- public TypeDeclaration $type,
+ public Node $identifier,
+ public TypeDeclaration|ArrayTypeDeclaration|MapTypeDeclaration $type,
public ?Node $defaultValue = null,
) {}
}
@@ -849,7 +960,7 @@ class FunctionReturn extends Node
class FunctionCall extends Node
{
public function __construct(
- public Token $identifier,
+ public Node $identifier,
/**
* @param FunctionCallParameter[] $parameters
*/
@@ -860,7 +971,7 @@ class FunctionCall extends Node
class FunctionCallParameter extends Node
{
public function __construct(
- public ?Token $identifier,
+ public ?Node $identifier,
public Node|Token $value,
) {}
}