Evaluates the given subexpression.
56 using namespace ast::exprnode;
58 std::pmr::vector<T> op_args;
59 const auto getArgs = [&op_args,
this](
int nargs) {
61 for(
int i = 0; i < nargs; ++i) op_args.push_back(popSafe());
65 while(!op_stack_.empty()) popSafe();
68 for(
auto const* nodes : subexpr.nodes()) {
73 auto* node = subexpr.mut_head();
74 for(
size_t i = 0; i < subexpr.size(); ++i) {
76 if(dyn_cast<ExprValue*>(node)) arg_locs_.push_back(node->location());
78 auto next_node = node->mut_next();
80 cur_op = dyn_cast<ExprOp*>(node);
81 if(
auto* value = dyn_cast<ExprValue*>(node)) {
82 op_stack_.push(mapValue(*value));
83 }
else if(
auto* unary = dyn_cast<UnaryOp*>(node)) {
85 op_stack_.push(evalUnaryOp(*unary, rhs));
86 }
else if(
auto* binary = dyn_cast<BinaryOp*>(node)) {
89 op_stack_.push(evalBinaryOp(*binary, lhs, rhs));
90 }
else if(
auto op = dyn_cast<MemberAccess*>(node)) {
91 auto field = popSafe();
93 op_stack_.push(evalMemberAccess(*op, lhs, field));
94 }
else if(
auto* method = dyn_cast<MethodInvocation*>(node)) {
96 if(method->nargs() > 1) getArgs(method->nargs() - 1);
97 auto method_name = popSafe();
98 op_stack_.push(evalMethodCall(*method, method_name, op_args));
99 }
else if(
auto* newObj = dyn_cast<ClassInstanceCreation*>(node)) {
101 if(newObj->nargs() > 1) getArgs(newObj->nargs() - 1);
102 auto type = popSafe();
103 op_stack_.push(evalNewObject(*newObj, type, op_args));
104 }
else if(
auto op = dyn_cast<ArrayInstanceCreation*>(node)) {
105 auto size = popSafe();
106 auto type = popSafe();
107 op_stack_.push(evalNewArray(*op, type, size));
108 }
else if(
auto op = dyn_cast<ArrayAccess*>(node)) {
109 auto index = popSafe();
110 auto array = popSafe();
111 op_stack_.push(evalArrayAccess(*op, array, index));
112 }
else if(
auto op = dyn_cast<Cast*>(node)) {
113 auto value = popSafe();
114 auto type = popSafe();
115 op_stack_.push(evalCast(*op, type, value));
117 assert(validate(op_stack_.top()));
119 if(cur_op) mergeLocations(cur_op->nargs());
123 auto result = popSafe();
124 assert(op_stack_.empty() &&
"Stack not empty after evaluation");