/
Analyzer.php
53 lines (48 loc) · 1.99 KB
/
Analyzer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
namespace NHP;
final class Analyzer {
private $scope;
private $values;
public function __construct(Scope $scope, array $values) {
$this->scope = $scope;
$this->values = $values;
}
public function withScope(Scope $scope) {
return new self($scope, $this->values);
}
public function analyzeDefinition(AST\Definition $definition): void {
if ($definition instanceof AST\VariableDefinition) {
$definition->setScope($this->scope);
$this->withScope(Scope::localScope())->analyzeExpression($definition->value());
$this->values[$definition->name()] = new Thing($this->scope, Thing::VARIABLE_TYPE);
} elseif ($definition instanceof AST\FunctionDefinition) {
$definition->setScope($this->scope);
$thing = new Thing($this->scope, Thing::FUNCTION_TYPE);
$this->values[$definition->name()] = $thing;
$this->withScope(Scope::localScope())->analyzeExpression($definition->body());
} else {
assert(false);
}
}
public function analyzeExpression(AST\Expression $expression): void {
if ($expression instanceof AST\VariableExpression) {
if (!array_key_exists($expression->name(), $this->values)) {
throw new \Exception('no such variable');
}
$expression->setThing($this->values[$expression->name()]);
} elseif ($expression instanceof AST\FloatLiteralExpression) {
} elseif ($expression instanceof AST\BlockExpression) {
foreach ($expression->statements() as $statement) {
if ($statement instanceof AST\Definition) {
$this->analyzeDefinition($statement);
} elseif ($statement instanceof AST\Expression) {
$this->analyzeExpression($statement);
} else {
assert(false);
}
}
} else {
assert(false);
}
}
}