/
overload.php
150 lines (130 loc) · 5.21 KB
/
overload.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
/*
* This software is the property of its authors.
* See the copyright.txt file for more details.
*
*/
function _toCorrectClass ($object) {
version_assert and assertTrue(count(func_get_args()) == 1);
version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected");
version_assert and assertTrue(is_object($object));
if (get_class($object) != 'stdClass')
return $object;
version_assert and assertTrue(isset($object->__class));
$class = $object->__class;
return new $class($object);
}
function toRaw ($value) {
version_assert and assertTrue(count(func_get_args()) == 1);
version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected");
if (is_object($value) && hasMember($value, 'toRaw'))
return $value->toRaw();
else
return $value;
}
function toString ($value) {
version_assert and assertTrue(count(func_get_args()) == 1);
version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected");
if (is_object($value))
$value = _toCorrectClass($value);
if (is_object($value) && hasMember($value, 'toString'))
return $value->toString();
else if (is_object($value) && hasMember($value, 'toRaw'))
return toString($value->toRaw());
else if (is_array($value)) {
$intermediate = array();
foreach ($value as $v)
$intermediate[] = toString($v);
return '[' . implode(', ', $intermediate) . ']';
} else
return (string) $value;
}
function sum () {
$result = 0;
foreach (func_get_args() as $argument)
if (is_array($argument))
$result += call_user_func_array('sum', $argument);
else
$result += $argument;
return $result;
}
function opConcat () {
version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected");
$arguments = func_get_args();
version_assert and assertTrue(count($arguments) >= 1);
$result = $arguments[0];
foreach (array_slice($arguments, 1) as $argument) {
if (is_object($result) && hasMember($result, 'opConcat'))
$result = $result->opConcat($argument);
else if (is_object($argument) && hasMember($argument, 'opConcatRight'))
$result = $argument->opConcatRight($result);
else if (is_array($argument)) {
version_assert and assertTrue(is_array($result) && is_array($argument));
$result = array_merge($result, $argument);
} else {
version_assert and assertTrue(is_string(toRaw($result)) && is_string(toRaw($argument)));
$result = toRaw($result) . toRaw($argument);
}
}
return $result;
}
function opEquals ($lhs, $rhs) {
version_assert and assertTrue(count(func_get_args()) == 2);
version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected");
if (is_object($lhs) && hasMember($lhs, 'opEquals'))
return $lhs->opEquals($rhs);
else if (is_object($rhs) && hasMember($rhs, 'opEquals'))
return $rhs->opEquals($lhs);
else
return toRaw($lhs) === toRaw($rhs);
}
function opDispatch ($symbol, $member) {
version_assert and assertTrue(count(func_get_args()) == 2);
version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected");
if (is_array($symbol) && array_key_exists($member, $symbol))
return $symbol[$member];
if (is_object($symbol) && method_exists($symbol, $member))
return array($symbol, $member);
if (is_object($symbol) && property_exists($symbol, $member))
return $symbol->$member;
if (method_exists($symbol, 'opDispatch')) {
version_assert and assertTrue(hasMember($symbol, $member));
return $symbol->opDispatch($member);
}
assertTrue(false, get_class($symbol));
}
function opAccess ($symbol, $member) {
version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected");
$proxy = opDispatch($symbol, $member);
return is_callable($proxy) ? call_user_func($proxy) : $proxy;
}
function invoke ($name, $arguments) {
$realignedArguments = $arguments;
if (count(array_filter($arguments, function($value, $name) { return !is_int($name); }, ARRAY_FILTER_USE_BOTH)) > 0) {
if (is_object($name))
$reflection = new ReflectionFunction($name->toFunction());
else if (is_array($name))
$reflection = new ReflectionMethod($name[0], $name[1]);
else
$reflection = new ReflectionFunction($name);
$realignedArguments = array();
foreach ($reflection->getParameters() as $argumentReflection) {
$value = null;
version_assert and assertTrue($argumentReflection->isDefaultValueAvailable() ||
array_key_exists($argumentReflection->name, $arguments), "Argument *{$argumentReflection->name}* missing.");
if ($argumentReflection->isDefaultValueAvailable())
$value = $argumentReflection->getDefaultValue();
if (array_key_exists($argumentReflection->name, $arguments))
$value = $arguments[$argumentReflection->name];
if ($argumentReflection->isDefaultValueAvailable()) {
switch (gettype($argumentReflection->getDefaultValue())) {
case 'boolean':
$value = $value && $value !== '0' && $value !== 'false' ? true : false;
break;
}
}
$realignedArguments[] = $value;
}
}
return call_user_func_array($name, $realignedArguments);
}