9 #include <hilti/ast/expressions/type.h> 10 #include <hilti/ast/operators/common.h> 11 #include <hilti/ast/types/bytes.h> 12 #include <hilti/ast/types/reference.h> 13 #include <hilti/ast/types/result.h> 14 #include <hilti/ast/types/stream.h> 15 #include <hilti/ast/types/tuple.h> 16 #include <hilti/ast/types/type.h> 20 BEGIN_OPERATOR_CUSTOM(
generic, Unpack)
23 return type::DocOnly(
"<unpackable>");
25 const auto& elements = ops[1].type().as<type::Tuple>().elements();
26 const auto& data_type = elements[0].type();
27 return type::Result(type::Tuple({ops[0].type().as<type::Type_>().typeValue(), data_type}, ops[0].meta()));
30 bool isLhs()
const {
return false; }
31 auto priority()
const {
return hilti::operator_::Priority::Normal; }
33 const std::vector<Operand>& operands()
const {
34 static std::vector<Operand> _operands = {Operand{{}, type::Type_(type::Wildcard())},
35 Operand{{}, type::Tuple(type::Wildcard())}};
39 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
40 const auto& elements = i.op1().type().template as<type::Tuple>().elements();
41 const auto& data_type = elements[0].type();
43 if ( ! (data_type.isA<type::Bytes>() || data_type.isA<type::stream::View>()) )
44 p.node.addError(
"unpack() can be used only with bytes or a stream view as input");
47 std::string doc()
const {
return "Unpacks a value from a binary representation."; }
50 BEGIN_OPERATOR_CUSTOM(
generic, Begin)
53 return type::DocOnly(
"<iterator>");
55 return type::isIterable(ops[0].type()) ? ops[0].type().iteratorType(ops[0].isConstant()) : type::unknown;
58 bool isLhs()
const {
return false; }
59 auto priority()
const {
return hilti::operator_::Priority::Normal; }
61 const std::vector<Operand>& operands()
const {
62 static std::vector<Operand> _operands = {
63 Operand{{}, type::Any(),
false, {},
"<container>"},
68 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
69 if ( ! type::isIterable(i.operands()[0].type()) )
70 p.node.addError(
"not an iterable type");
73 std::string doc()
const {
return "Returns an iterator to the beginning of the container's content."; }
76 BEGIN_OPERATOR_CUSTOM(
generic, End)
79 return type::DocOnly(
"<iterator>");
81 return type::isIterable(ops[0].type()) ? ops[0].type().iteratorType(ops[0].isConstant()) : type::unknown;
84 bool isLhs()
const {
return false; }
85 auto priority()
const {
return hilti::operator_::Priority::Normal; }
87 const std::vector<Operand>& operands()
const {
88 static std::vector<Operand> _operands = {
89 {{}, type::Any(),
false, {},
"<container>"},
94 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
95 if ( ! type::isIterable(i.operands()[0].type()) )
96 p.node.addError(
"not an iterable type");
99 std::string doc()
const {
return "Returns an iterator to the end of the container's content."; }
102 BEGIN_OPERATOR_CUSTOM(
generic, New)
105 return type::DocOnly(
"strong_ref<T>");
107 auto t = ops[0].type();
109 if (
auto tv = ops[0].type().tryAs<type::Type_>() )
112 return type::StrongReference(t, t.meta());
115 bool isLhs()
const {
return false; }
116 auto priority()
const {
return hilti::operator_::Priority::Normal; }
118 const std::vector<Operand>& operands()
const {
119 static std::vector<Operand> _operands = {
121 {{}, type::Tuple(type::Wildcard())},
126 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
127 auto t = i.operands()[0].type();
129 if (
auto tv = i.operands()[0].type().tryAs<type::Type_>() )
132 if ( ! type::isAllocable(t) )
133 p.node.addError(
"not an allocable type");
136 std::string doc()
const {
138 Returns a reference to an instance of a type newly allocated on the heap. 139 If `x' is a type, a default instance of that type will be allocated. 140 If `x` is an expression, an instance of the expression's type will be allocated and initialized with the value of the expression. 150 OPERATOR_DECLARE_ONLY(generic, CastedCoercion)
156 using hilti::expression::ResolvedOperatorBase::ResolvedOperatorBase;
161 static operator_::Kind kind() {
return operator_::Kind::Cast; }
162 const std::vector<operator_::Operand>& operands()
const {
163 static std::vector<Operand> _operands = {};
169 bool isLhs()
const {
return false; }
170 auto priority()
const {
return hilti::operator_::Priority::Normal; }
172 std::string doc()
const {
return "<dynamic - no doc>"; }
173 std::string docNamespace()
const {
return "<dynamic - no ns>"; }
175 Expression instantiate(
const std::vector<Expression>& operands,
const Meta& meta)
const {
176 auto ro = expression::ResolvedOperator(
CastedCoercion(*
this, operands, meta));
178 return std::move(ro);
Definition: generic.h:154
Definition: visitor-types.h:28
Definition: operator-registry.h:15
Definition: operator.h:35
Definition: generic.h:158
Definition: resolved-operator.h:37