-
Notifications
You must be signed in to change notification settings - Fork 111
Expand file tree
/
Copy pathprimitive-type.cpp
More file actions
88 lines (73 loc) · 2.56 KB
/
primitive-type.cpp
File metadata and controls
88 lines (73 loc) · 2.56 KB
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
// Compiler for PHP (aka KPHP)
// Copyright (c) 2020 LLC «V Kontakte»
// Distributed under the GPL v3 License, see LICENSE.notice.txt
#include "compiler/inferring/primitive-type.h"
#include <map>
#include <string>
#include "common/algorithms/find.h"
#include "compiler/stage.h"
const char *ptype_name(PrimitiveType id) {
switch (id) {
case tp_any: return "any";
case tp_Null: return "Null";
case tp_False: return "False";
case tp_bool: return "bool";
case tp_int: return "int";
case tp_float: return "float";
case tp_array: return "array";
case tp_iterable: return "iterable";
case tp_string: return "string";
case tp_tmp_string: return "tmp_string";
case tp_mixed: return "mixed";
case tp_tuple: return "tuple";
case tp_shape: return "shape";
case tp_future: return "future";
case tp_future_queue: return "future_queue";
case tp_regexp: return "regexp";
case tp_Class: return "Class";
case tp_object: return "object";
case tp_void: return "void";
case tp_Error: return "Error";
case ptype_size: kphp_fail();
}
kphp_fail();
}
bool can_store_false(PrimitiveType tp) {
kphp_assert(vk::none_of_equal(tp, tp_False, tp_Null));
// any+or_false means just 'false' keyword, it's not wrapped into Optional: it's bool in cpp, but stays just false in type comparisons
return vk::any_of_equal(tp, tp_bool, tp_mixed, tp_any);
}
bool can_store_null(PrimitiveType tp) {
kphp_assert(vk::none_of_equal(tp, tp_False, tp_Null));
// any+or_null means just 'null' keyword, it's represented as Optional<bool> in cpp, so any can't store null
return vk::any_of_equal(tp, tp_mixed, tp_Class);
}
PrimitiveType type_lca(PrimitiveType a, PrimitiveType b) {
kphp_assert(vk::none_of_equal(a, tp_False, tp_Null));
kphp_assert(vk::none_of_equal(b, tp_False, tp_Null));
if (a == b) {
return a;
}
if (a == tp_Error || b == tp_Error) {
return tp_Error;
}
if (a > b) {
std::swap(a, b);
}
if (a == tp_any) {
return b;
}
if (b >= tp_void) { // instances, future, etc — can mix only with false
if (a == tp_Class && b == tp_object) {
return tp_object;
}
return tp_Error;
}
if (vk::any_of_equal(a, tp_int, tp_float) && vk::any_of_equal(b, tp_int, tp_float)) { // float can store int
return tp_float;
}
if (tp_bool <= a && a <= tp_mixed && tp_bool <= b && b <= tp_mixed) {
return tp_mixed;
}
return std::max(a, b);
}