1
|
|
|
<?php |
2
|
|
|
namespace Desmond\functions\special; |
3
|
|
|
use Desmond\functions\DesmondSpecialFunction; |
4
|
|
|
use Desmond\ArgumentHelper; |
5
|
|
|
use Desmond\data_types\StringType; |
6
|
|
|
use Desmond\exceptions\ArgumentException; |
7
|
|
|
|
8
|
|
|
class TryCatch extends DesmondSpecialFunction |
9
|
|
|
{ |
10
|
|
|
use ArgumentHelper; |
11
|
|
|
|
12
|
9 |
|
public function run(array $args) |
13
|
|
|
{ |
14
|
9 |
|
$this->checkForm($args); |
15
|
3 |
|
$statement = $args[0]; |
16
|
3 |
|
$catch = $args[1]; |
17
|
3 |
|
$messageSym = $catch->get(1)->value(); |
18
|
3 |
|
$body = $catch->get(2); |
19
|
|
|
try { |
20
|
3 |
|
$first = $this->eval->getReturn($statement); |
21
|
2 |
|
} catch (\Exception $message) { |
22
|
2 |
|
$newId = $this->currentEnv->makeChild(); |
23
|
2 |
|
$this->currentEnv = $this->currentEnv->values[$newId]; |
24
|
|
|
|
25
|
2 |
|
$this->currentEnv->set( |
26
|
|
|
$messageSym, |
27
|
2 |
|
new StringType($message->getMessage(), true) |
28
|
|
|
); |
29
|
2 |
|
$return = $this->eval->getReturn($body); |
30
|
|
|
|
31
|
2 |
|
$this->currentEnv = $this->currentEnv->getParent(); |
32
|
2 |
|
$this->currentEnv->destroyChild($newId); |
33
|
2 |
|
return $return; |
34
|
|
|
} |
35
|
1 |
|
return $first; |
36
|
|
|
} |
37
|
|
|
|
38
|
9 |
|
private function checkForm($args) |
39
|
|
|
{ |
40
|
9 |
|
if (empty($args)) { |
41
|
1 |
|
throw new ArgumentException('"try" expects first argument.'); |
42
|
|
|
} |
43
|
8 |
|
$this->expectArguments('try', [1 => ['List']], $args); |
44
|
7 |
|
$list = $args[1]; |
45
|
7 |
|
if ($list->getFunction() != 'catch') { |
46
|
1 |
|
throw new ArgumentException('"try" expects argument 2 to be a "catch" function.'); |
47
|
|
|
} |
48
|
6 |
|
$catchArgs = $list->getArgs(); |
49
|
6 |
|
$this->expectArguments('catch', [['Symbol']], $catchArgs); |
50
|
4 |
|
if (!isset($catchArgs[1])) { |
51
|
1 |
|
throw new ArgumentException('"catch" expects argument 2.'); |
52
|
|
|
} |
53
|
3 |
|
} |
54
|
|
|
} |
55
|
|
|
|