expression.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "explorer/ast/expression.h"
  5. #include <map>
  6. #include <optional>
  7. #include "explorer/ast/pattern.h"
  8. #include "explorer/ast/value.h"
  9. #include "explorer/base/arena.h"
  10. #include "explorer/base/error_builders.h"
  11. #include "llvm/ADT/StringExtras.h"
  12. #include "llvm/Support/Casting.h"
  13. #include "llvm/Support/raw_ostream.h"
  14. namespace Carbon {
  15. using llvm::cast;
  16. using llvm::isa;
  17. auto IntrinsicExpression::FindIntrinsic(std::string_view name,
  18. SourceLocation source_loc)
  19. -> ErrorOr<Intrinsic> {
  20. // TODO: Remove Print special casing once we have variadics or overloads.
  21. if (name == "Print") {
  22. return Intrinsic::Print;
  23. }
  24. static const auto& intrinsic_map = *new std::map<std::string_view, Intrinsic>(
  25. {{"print", Intrinsic::Print},
  26. {"new", Intrinsic::Alloc},
  27. {"delete", Intrinsic::Dealloc},
  28. {"print_allocs", Intrinsic::PrintAllocs},
  29. {"rand", Intrinsic::Rand},
  30. {"implicit_as", Intrinsic::ImplicitAs},
  31. {"implicit_as_convert", Intrinsic::ImplicitAsConvert},
  32. {"int_eq", Intrinsic::IntEq},
  33. {"int_compare", Intrinsic::IntCompare},
  34. {"int_bit_complement", Intrinsic::IntBitComplement},
  35. {"int_bit_and", Intrinsic::IntBitAnd},
  36. {"int_bit_or", Intrinsic::IntBitOr},
  37. {"int_bit_xor", Intrinsic::IntBitXor},
  38. {"int_left_shift", Intrinsic::IntLeftShift},
  39. {"int_right_shift", Intrinsic::IntRightShift},
  40. {"str_eq", Intrinsic::StrEq},
  41. {"str_compare", Intrinsic::StrCompare},
  42. {"assert", Intrinsic::Assert}});
  43. name.remove_prefix(std::strlen("__intrinsic_"));
  44. auto it = intrinsic_map.find(name);
  45. if (it == intrinsic_map.end()) {
  46. return ProgramError(source_loc) << "Unknown intrinsic '" << name << "'";
  47. }
  48. return it->second;
  49. }
  50. auto IntrinsicExpression::name() const -> std::string_view {
  51. switch (intrinsic()) {
  52. case IntrinsicExpression::Intrinsic::Print:
  53. // TODO: Remove Print special casing once we have variadics or overloads.
  54. return "Print";
  55. case IntrinsicExpression::Intrinsic::Alloc:
  56. return "__intrinsic_new";
  57. case IntrinsicExpression::Intrinsic::Dealloc:
  58. return "__intrinsic_delete";
  59. case IntrinsicExpression::Intrinsic::PrintAllocs:
  60. return "__intrinsic_print_allocs";
  61. case IntrinsicExpression::Intrinsic::Rand:
  62. return "__intrinsic_rand";
  63. case IntrinsicExpression::Intrinsic::ImplicitAs:
  64. return "__intrinsic_implicit_as";
  65. case IntrinsicExpression::Intrinsic::ImplicitAsConvert:
  66. return "__intrinsic_implicit_as_convert";
  67. case IntrinsicExpression::Intrinsic::IntEq:
  68. return "__intrinsic_int_eq";
  69. case IntrinsicExpression::Intrinsic::IntCompare:
  70. return "__intrinsic_int_compare";
  71. case IntrinsicExpression::Intrinsic::IntBitComplement:
  72. return "__intrinsic_int_bit_complement";
  73. case IntrinsicExpression::Intrinsic::IntBitAnd:
  74. return "__intrinsic_int_bit_and";
  75. case IntrinsicExpression::Intrinsic::IntBitOr:
  76. return "__intrinsic_int_bit_or";
  77. case IntrinsicExpression::Intrinsic::IntBitXor:
  78. return "__intrinsic_int_bit_xor";
  79. case IntrinsicExpression::Intrinsic::IntLeftShift:
  80. return "__intrinsic_int_left_shift";
  81. case IntrinsicExpression::Intrinsic::IntRightShift:
  82. return "__intrinsic_int_right_shift";
  83. case IntrinsicExpression::Intrinsic::StrEq:
  84. return "__intrinsic_str_eq";
  85. case IntrinsicExpression::Intrinsic::StrCompare:
  86. return "__intrinsic_str_compare";
  87. case IntrinsicExpression::Intrinsic::Assert:
  88. return "__intrinsic_assert";
  89. }
  90. }
  91. auto ExpressionFromParenContents(
  92. Nonnull<Arena*> arena, SourceLocation source_loc,
  93. const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*> {
  94. std::optional<Nonnull<Expression*>> single_term = paren_contents.SingleTerm();
  95. if (single_term.has_value()) {
  96. return *single_term;
  97. } else {
  98. return TupleExpressionFromParenContents(arena, source_loc, paren_contents);
  99. }
  100. }
  101. auto TupleExpressionFromParenContents(
  102. Nonnull<Arena*> arena, SourceLocation source_loc,
  103. const ParenContents<Expression>& paren_contents) -> Nonnull<TupleLiteral*> {
  104. return arena->New<TupleLiteral>(source_loc, paren_contents.elements);
  105. }
  106. Expression::~Expression() = default;
  107. auto OperatorToString(Operator op) -> std::string_view {
  108. switch (op) {
  109. case Operator::Add:
  110. return "+";
  111. case Operator::As:
  112. return "as";
  113. case Operator::AddressOf:
  114. case Operator::BitwiseAnd:
  115. return "&";
  116. case Operator::BitwiseOr:
  117. return "|";
  118. case Operator::BitwiseXor:
  119. case Operator::Complement:
  120. return "^";
  121. case Operator::BitShiftLeft:
  122. return "<<";
  123. case Operator::BitShiftRight:
  124. return ">>";
  125. case Operator::Div:
  126. return "/";
  127. case Operator::Neg:
  128. case Operator::Sub:
  129. return "-";
  130. case Operator::Mul:
  131. case Operator::Deref:
  132. case Operator::Ptr:
  133. return "*";
  134. case Operator::Not:
  135. return "not";
  136. case Operator::NotEq:
  137. return "!=";
  138. case Operator::And:
  139. return "and";
  140. case Operator::Or:
  141. return "or";
  142. case Operator::Eq:
  143. return "==";
  144. case Operator::Mod:
  145. return "%";
  146. case Operator::Less:
  147. return "<";
  148. case Operator::LessEq:
  149. return "<=";
  150. case Operator::Greater:
  151. return ">";
  152. case Operator::GreaterEq:
  153. return ">=";
  154. }
  155. }
  156. static void PrintFields(llvm::raw_ostream& out,
  157. const std::vector<FieldInitializer>& fields,
  158. std::string_view separator) {
  159. llvm::ListSeparator sep;
  160. for (const auto& field : fields) {
  161. out << sep << "." << field.name() << separator << field.expression();
  162. }
  163. }
  164. void Expression::Print(llvm::raw_ostream& out) const {
  165. switch (kind()) {
  166. case ExpressionKind::IndexExpression: {
  167. const auto& index = cast<IndexExpression>(*this);
  168. out << index.object() << "[" << index.offset() << "]";
  169. break;
  170. }
  171. case ExpressionKind::SimpleMemberAccessExpression: {
  172. const auto& access = cast<SimpleMemberAccessExpression>(*this);
  173. out << access.object() << "." << access.member_name();
  174. break;
  175. }
  176. case ExpressionKind::CompoundMemberAccessExpression: {
  177. const auto& access = cast<CompoundMemberAccessExpression>(*this);
  178. out << access.object() << ".(" << access.path() << ")";
  179. break;
  180. }
  181. case ExpressionKind::BaseAccessExpression: {
  182. const auto& access = cast<BaseAccessExpression>(*this);
  183. out << access.object() << ".base";
  184. break;
  185. }
  186. case ExpressionKind::TupleLiteral: {
  187. out << "(";
  188. llvm::ListSeparator sep;
  189. for (Nonnull<const Expression*> field :
  190. cast<TupleLiteral>(*this).fields()) {
  191. out << sep << *field;
  192. }
  193. out << ")";
  194. break;
  195. }
  196. case ExpressionKind::StructLiteral:
  197. out << "{";
  198. PrintFields(out, cast<StructLiteral>(*this).fields(), " = ");
  199. out << "}";
  200. break;
  201. case ExpressionKind::StructTypeLiteral:
  202. out << "{";
  203. PrintFields(out, cast<StructTypeLiteral>(*this).fields(), ": ");
  204. out << "}";
  205. break;
  206. case ExpressionKind::OperatorExpression: {
  207. out << "(";
  208. const auto& op = cast<OperatorExpression>(*this);
  209. switch (op.arguments().size()) {
  210. case 0:
  211. out << OperatorToString(op.op());
  212. break;
  213. case 1:
  214. out << OperatorToString(op.op()) << " " << *op.arguments()[0];
  215. break;
  216. case 2:
  217. out << *op.arguments()[0] << " " << OperatorToString(op.op()) << " "
  218. << *op.arguments()[1];
  219. break;
  220. default:
  221. CARBON_FATAL("Unexpected argument count: {0}", op.arguments().size());
  222. }
  223. out << ")";
  224. break;
  225. }
  226. case ExpressionKind::CallExpression: {
  227. const auto& call = cast<CallExpression>(*this);
  228. out << call.function();
  229. if (isa<TupleLiteral>(call.argument())) {
  230. out << call.argument();
  231. } else {
  232. out << "(" << call.argument() << ")";
  233. }
  234. break;
  235. }
  236. case ExpressionKind::FunctionTypeLiteral: {
  237. const auto& fn = cast<FunctionTypeLiteral>(*this);
  238. out << "fn " << fn.parameter() << " -> " << fn.return_type();
  239. break;
  240. }
  241. case ExpressionKind::IntrinsicExpression: {
  242. const auto& iexp = cast<IntrinsicExpression>(*this);
  243. out << iexp.name() << iexp.args();
  244. break;
  245. }
  246. case ExpressionKind::IfExpression: {
  247. const auto& if_expr = cast<IfExpression>(*this);
  248. out << "if " << if_expr.condition() << " then "
  249. << if_expr.then_expression() << " else " << if_expr.else_expression();
  250. break;
  251. }
  252. case ExpressionKind::WhereExpression: {
  253. const auto& where = cast<WhereExpression>(*this);
  254. out << where.self_binding().type() << " where ";
  255. llvm::ListSeparator sep(" and ");
  256. for (const WhereClause* clause : where.clauses()) {
  257. out << sep << *clause;
  258. }
  259. break;
  260. }
  261. case ExpressionKind::BuiltinConvertExpression: {
  262. // These don't represent source syntax, so just print the original
  263. // expression.
  264. out << *cast<BuiltinConvertExpression>(this)->source_expression();
  265. break;
  266. }
  267. case ExpressionKind::UnimplementedExpression: {
  268. const auto& unimplemented = cast<UnimplementedExpression>(*this);
  269. out << "UnimplementedExpression<" << unimplemented.label() << ">(";
  270. llvm::ListSeparator sep;
  271. for (Nonnull<const AstNode*> child : unimplemented.children()) {
  272. out << sep << *child;
  273. }
  274. out << ")";
  275. break;
  276. }
  277. case ExpressionKind::ArrayTypeLiteral: {
  278. const auto& array_literal = cast<ArrayTypeLiteral>(*this);
  279. out << "[" << array_literal.element_type_expression() << ";";
  280. if (array_literal.has_size_expression()) {
  281. out << " " << array_literal.size_expression();
  282. }
  283. out << "]";
  284. break;
  285. }
  286. case ExpressionKind::IdentifierExpression:
  287. case ExpressionKind::DotSelfExpression:
  288. case ExpressionKind::IntLiteral:
  289. case ExpressionKind::BoolLiteral:
  290. case ExpressionKind::BoolTypeLiteral:
  291. case ExpressionKind::IntTypeLiteral:
  292. case ExpressionKind::StringLiteral:
  293. case ExpressionKind::StringTypeLiteral:
  294. case ExpressionKind::TypeTypeLiteral:
  295. case ExpressionKind::ValueLiteral:
  296. PrintID(out);
  297. break;
  298. }
  299. }
  300. void Expression::PrintID(llvm::raw_ostream& out) const {
  301. switch (kind()) {
  302. case ExpressionKind::IdentifierExpression:
  303. out << cast<IdentifierExpression>(*this).name();
  304. break;
  305. case ExpressionKind::DotSelfExpression:
  306. out << ".Self";
  307. break;
  308. case ExpressionKind::IntLiteral:
  309. out << cast<IntLiteral>(*this).value();
  310. break;
  311. case ExpressionKind::BoolLiteral:
  312. out << (cast<BoolLiteral>(*this).value() ? "true" : "false");
  313. break;
  314. case ExpressionKind::BoolTypeLiteral:
  315. out << "bool";
  316. break;
  317. case ExpressionKind::IntTypeLiteral:
  318. out << "i32";
  319. break;
  320. case ExpressionKind::StringLiteral:
  321. out << "\"";
  322. out.write_escaped(cast<StringLiteral>(*this).value());
  323. out << "\"";
  324. break;
  325. case ExpressionKind::StringTypeLiteral:
  326. out << "String";
  327. break;
  328. case ExpressionKind::TypeTypeLiteral:
  329. out << "type";
  330. break;
  331. case ExpressionKind::ValueLiteral:
  332. out << cast<ConstantValueLiteral>(*this).constant_value();
  333. break;
  334. case ExpressionKind::ArrayTypeLiteral:
  335. case ExpressionKind::FunctionTypeLiteral:
  336. case ExpressionKind::StructLiteral:
  337. case ExpressionKind::IndexExpression:
  338. case ExpressionKind::SimpleMemberAccessExpression:
  339. case ExpressionKind::CompoundMemberAccessExpression:
  340. case ExpressionKind::BaseAccessExpression:
  341. case ExpressionKind::IfExpression:
  342. case ExpressionKind::WhereExpression:
  343. case ExpressionKind::BuiltinConvertExpression:
  344. case ExpressionKind::TupleLiteral:
  345. case ExpressionKind::StructTypeLiteral:
  346. case ExpressionKind::CallExpression:
  347. case ExpressionKind::OperatorExpression:
  348. case ExpressionKind::IntrinsicExpression:
  349. case ExpressionKind::UnimplementedExpression:
  350. out << "...";
  351. break;
  352. }
  353. }
  354. DotSelfExpression::DotSelfExpression(CloneContext& context,
  355. const DotSelfExpression& other)
  356. : Expression(context, other),
  357. name_(other.name_),
  358. self_binding_(context.Remap(other.self_binding_)) {}
  359. MemberAccessExpression::MemberAccessExpression(
  360. CloneContext& context, const MemberAccessExpression& other)
  361. : Expression(context, other),
  362. object_(context.Clone(other.object_)),
  363. is_type_access_(other.is_type_access_),
  364. is_addr_me_method_(other.is_addr_me_method_),
  365. impl_(context.Clone(other.impl_)),
  366. constant_value_(context.Clone(other.constant_value_)) {}
  367. SimpleMemberAccessExpression::SimpleMemberAccessExpression(
  368. CloneContext& context, const SimpleMemberAccessExpression& other)
  369. : RewritableMixin(context, other),
  370. member_name_(other.member_name_),
  371. member_(context.Clone(other.member_)),
  372. found_in_interface_(context.Clone(other.found_in_interface_)),
  373. value_node_(context.Clone(other.value_node_)) {}
  374. CompoundMemberAccessExpression::CompoundMemberAccessExpression(
  375. CloneContext& context, const CompoundMemberAccessExpression& other)
  376. : MemberAccessExpression(context, other),
  377. path_(context.Clone(other.path_)),
  378. member_(context.Clone(other.member_)) {}
  379. WhereClause::~WhereClause() = default;
  380. void WhereClause::Print(llvm::raw_ostream& out) const {
  381. switch (kind()) {
  382. case WhereClauseKind::ImplsWhereClause: {
  383. const auto& clause = cast<ImplsWhereClause>(*this);
  384. out << clause.type() << " impls " << clause.constraint();
  385. break;
  386. }
  387. case WhereClauseKind::EqualsWhereClause: {
  388. const auto& clause = cast<EqualsWhereClause>(*this);
  389. out << clause.lhs() << " == " << clause.rhs();
  390. break;
  391. }
  392. case WhereClauseKind::RewriteWhereClause: {
  393. const auto& clause = cast<RewriteWhereClause>(*this);
  394. out << "." << clause.member_name() << " = " << clause.replacement();
  395. break;
  396. }
  397. }
  398. }
  399. void WhereClause::PrintID(llvm::raw_ostream& out) const { out << "..."; }
  400. WhereExpression::WhereExpression(CloneContext& context,
  401. const WhereExpression& other)
  402. : RewritableMixin(context, other),
  403. self_binding_(context.Clone(other.self_binding_)),
  404. clauses_(context.Clone(other.clauses_)),
  405. enclosing_dot_self_(context.Remap(other.enclosing_dot_self_)) {}
  406. } // namespace Carbon