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> 21 BEGIN_OPERATOR_CUSTOM(
generic, Unpack)
24 return type::DocOnly(
"<unpackable>");
26 const auto& data_type = ops[1].type().as<type::Tuple>().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 std::vector<Operand> operands()
const {
34 return {{.type = type::Type_(type::Wildcard())}, {.type = type::Tuple(type::Wildcard())}};
37 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
38 const auto& data_type = i.op1().type().template as<type::Tuple>().elements()[0].type();
40 if ( ! (data_type.isA<type::Bytes>() || data_type.isA<type::stream::View>()) )
41 p.node.addError(
"unpack() can be used only with bytes or a stream view as input");
44 std::string doc()
const {
return "Unpacks a value from a binary representation."; }
47 BEGIN_OPERATOR_CUSTOM(
generic, Begin)
50 return type::DocOnly(
"<iterator>");
52 return type::isIterable(ops[0].type()) ? ops[0].type().iteratorType(ops[0].isConstant()) : type::unknown;
55 bool isLhs()
const {
return false; }
56 auto priority()
const {
return hilti::operator_::Priority::Normal; }
58 std::vector<Operand> operands()
const {
60 {.type = type::Any(), .doc =
"<container>"},
64 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
65 if ( ! type::isIterable(i.operands()[0].type()) )
66 p.node.addError(
"not an iterable type");
69 std::string doc()
const {
return "Returns an iterator to the beginning of the container's content."; }
72 BEGIN_OPERATOR_CUSTOM(
generic, End)
75 return type::DocOnly(
"<iterator>");
77 return type::isIterable(ops[0].type()) ? ops[0].type().iteratorType(ops[0].isConstant()) : type::unknown;
80 bool isLhs()
const {
return false; }
81 auto priority()
const {
return hilti::operator_::Priority::Normal; }
83 std::vector<Operand> operands()
const {
85 {.type = type::Any(), .doc =
"<container>"},
89 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
90 if ( ! type::isIterable(i.operands()[0].type()) )
91 p.node.addError(
"not an iterable type");
94 std::string doc()
const {
return "Returns an iterator to the end of the container's content."; }
97 BEGIN_OPERATOR_CUSTOM(
generic, New)
100 return type::DocOnly(
"strong_ref<T>");
102 auto t = ops[0].type();
104 if (
auto tv = ops[0].type().tryAs<type::Type_>() )
107 return type::StrongReference(t, t.meta());
110 bool isLhs()
const {
return false; }
111 auto priority()
const {
return hilti::operator_::Priority::Normal; }
113 std::vector<Operand> operands()
const {
115 {.id =
"t", .type = type::Any()},
116 {.type = type::Tuple(type::Wildcard())},
120 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
121 auto t = i.operands()[0].type();
123 if (
auto tv = i.operands()[0].type().tryAs<type::Type_>() )
126 if ( ! type::isAllocable(t) )
127 p.node.addError(
"not an allocable type");
130 std::string doc()
const {
132 Returns a reference to an instance of a type newly allocated on the heap. 133 If `x' is a type, a default instance of that type will be allocated. 134 If `x` is an expression, an instance of the expression's type will be allocated and initialized with the value of the expression. 144 OPERATOR_DECLARE_ONLY(generic, CastedCoercion)
150 using hilti::expression::ResolvedOperatorBase::ResolvedOperatorBase;
155 static operator_::Kind kind() {
return operator_::Kind::Cast; }
156 std::vector<operator_::Operand> operands()
const {
return {}; }
160 bool isLhs()
const {
return false; }
161 auto priority()
const {
return hilti::operator_::Priority::Normal; }
163 std::string doc()
const {
return "<dynamic - no doc>"; }
164 std::string docNamespace()
const {
return "<dynamic - no ns>"; }
166 Expression instantiate(
const std::vector<Expression>& operands,
const Meta& meta)
const {
167 auto ro = expression::ResolvedOperator(
CastedCoercion(*
this, operands, meta));
169 return std::move(ro);
Definition: generic.h:148
Definition: visitor-types.h:28
Definition: operator.h:38
Definition: generic.h:152
Definition: resolved-operator.h:40