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)
22 Type result(
const std::vector<Expression>& ops)
const {
24 return type::DocOnly(
"<unpackable>");
26 auto data_type = ops[1].type().as<type::Tuple>().types()[0];
27 return type::Result(type::Tuple({ops[0].type().as<type::Type_>().typeValue(), data_type}, ops[0].meta()));
30 bool isLhs()
const {
return false; }
32 std::vector<Operand> operands()
const {
33 return {{.type = type::Type_(type::Wildcard())}, {.type = type::Tuple(type::Wildcard())}};
36 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
37 auto data_type = i.op1().type().template as<type::Tuple>().types()[0];
39 if ( ! (data_type.isA<type::Bytes>() || data_type.isA<type::stream::View>()) )
40 p.node.addError(
"unpack() can be used only with bytes or a stream view as input");
43 std::string doc()
const {
return "Unpacks a value from a binary representation."; }
46 BEGIN_OPERATOR_CUSTOM(
generic, Begin)
47 Type result(
const std::vector<Expression>& ops)
const {
49 return type::DocOnly(
"<iterator>");
51 return type::isIterable(ops[0].type()) ? ops[0].type().iteratorType(ops[0].isConstant()) : type::unknown;
54 bool isLhs()
const {
return false; }
56 std::vector<Operand> operands()
const {
58 {.type = type::Any(), .doc =
"<container>"},
62 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
63 if ( ! type::isIterable(i.operands()[0].type()) )
64 p.node.addError(
"not an iterable type");
67 std::string doc()
const {
return "Returns an iterator to the beginning of the container's content."; }
70 BEGIN_OPERATOR_CUSTOM(
generic, End)
71 Type result(
const std::vector<Expression>& ops)
const {
73 return type::DocOnly(
"<iterator>");
75 return type::isIterable(ops[0].type()) ? ops[0].type().iteratorType(ops[0].isConstant()) : type::unknown;
78 bool isLhs()
const {
return false; }
80 std::vector<Operand> operands()
const {
82 {.type = type::Any(), .doc =
"<container>"},
86 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
87 if ( ! type::isIterable(i.operands()[0].type()) )
88 p.node.addError(
"not an iterable type");
91 std::string doc()
const {
return "Returns an iterator to the end of the container's content."; }
94 BEGIN_OPERATOR_CUSTOM(
generic, New)
95 Type result(
const std::vector<Expression>& ops)
const {
97 return type::DocOnly(
"strong_ref<T>");
99 auto t = ops[0].type();
101 if (
auto tv = ops[0].type().tryAs<type::Type_>() )
104 return type::StrongReference(t, t.meta());
107 bool isLhs()
const {
return false; }
109 std::vector<Operand> operands()
const {
111 {.id =
"t", .type = type::Any()},
112 {.type = type::Tuple(type::Wildcard())},
116 void validate(
const expression::ResolvedOperator& i, operator_::position_t p)
const {
117 auto t = i.operands()[0].type();
119 if (
auto tv = i.operands()[0].type().tryAs<type::Type_>() )
122 if ( ! type::isAllocable(t) )
123 p.node.addError(
"not an allocable type");
126 std::string doc()
const {
128 Returns a reference to an instance of a type newly allocated on the heap. 129 If `x' is a type, a default instance of that type will be allocated. 130 If `x` is an expression, an instance of the expression's type will be allocated and initialized with the value of the expression. 140 OPERATOR_DECLARE_ONLY(generic, CastedCoercion)
146 using hilti::expression::ResolvedOperatorBase::ResolvedOperatorBase;
151 static operator_::Kind kind() {
return operator_::Kind::Cast; }
152 std::vector<operator_::Operand> operands()
const {
return {}; }
153 Type result(
const std::vector<Expression>& ops)
const {
return ops[1].as<
expression::Type_>().typeValue(); }
154 bool isLhs()
const {
return false; }
156 std::string doc()
const {
return "<dynamic - no doc>"; }
157 std::string docNamespace()
const {
return "<dynamic - no ns>"; }
159 Expression instantiate(
const std::vector<Expression>& operands,
const Meta& meta)
const {
160 auto ro = expression::ResolvedOperator(
CastedCoercion(*
this, operands, meta));
162 return std::move(ro);
Definition: generic.h:144
Definition: visitor-types.h:26
Definition: operator.h:38
Definition: generic.h:148
Definition: resolved-operator.h:55