28 #include "valuevar.hpp"
29 #include "display.hpp"
34 using namespace Juice;
40 typedef std::shared_ptr<BaseFrame> shpfrm;
42 struct BaseFrame : std::enable_shared_from_this<BaseFrame> {
44 typedef map<string,val::Value> map_type;
45 typedef map<string,val::Value>::const_iterator const_map_iterator;
52 shared_ptr<interp::Kont> bc_p =
nullptr,
53 shared_ptr<interp::Kont> ec_p = shared_ptr<interp::Kont>(),
54 shared_ptr<interp::Kont> cc_p =
nullptr) :
55 name(name_p), up(u), global(g), bc(bc_p), ec(ec_p), cc(cc_p), depth(u ? u->depth + 1 : 0) {
57 cout << name <<
" FRAME CREATED: " <<
this << endl;
62 shared_ptr<interp::Kont> getec() {
return ec; }
63 void resetec() { ec =
nullptr; }
64 std::vector<BaseFrame*> getStack(std::vector<BaseFrame*> s = std::vector<BaseFrame*>()) {
66 return up ? up->getStack(s) : s;
70 virtual val::Value find(
const string& s)
const = 0;
71 virtual val::Value findLocal(
const string& s)
const = 0;
72 virtual val::Value& findR(
const string& s,
bool funcall=
false) = 0;
76 virtual val::Value& add(
string s, val::Value&&
val) = 0;
77 virtual val::Value& addSpecial(
string s, val::Value&&
val) = 0;
78 virtual val::Value& addEllipsis(
string s, val::Value&&
val,
80 virtual val::Value& addArg(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) = 0;
81 virtual bool remove(
const string& symb) = 0;
82 virtual bool removeSpecial(
const string& symb) = 0;
84 virtual shpfrm getTrueFrame() {
return shared_from_this(); }
86 virtual operator string()
const = 0;
87 virtual void clearTmp() = 0;
88 virtual void clear() {
90 cout <<
"clearing: " <<
this << endl;
94 ec = bc = cc =
nullptr;
96 virtual bool isFrame() {
return false; }
97 virtual bool isShadow() {
return false; }
101 cout << name <<
" FRAME DELETED: " <<
this << endl;
105 unsigned getDepth()
const {
return depth; }
110 shared_ptr<interp::Kont> bc;
111 shared_ptr<interp::Kont>
ec;
112 shared_ptr<interp::Kont>
cc;
124 Frame(
const string& name_p,
127 shared_ptr<interp::Kont> bc =
nullptr,
128 shared_ptr<interp::Kont> ec = shared_ptr<interp::Kont>(),
129 shared_ptr<interp::Kont> cc =
nullptr) :
133 val::Value find(
const string& s)
const {
134 const map_type& ml = s[0] !=
'?' ? m : mtmp;
135 auto elt = ml.find(s);
136 if (elt != ml.end()) {
142 throw std::out_of_range(
"object '" + s +
"' not found");
147 val::Value findLocal(
const string& s)
const {
148 const map_type& ml = s[0] !=
'?' ? m : mtmp;
149 auto elt = ml.find(s);
150 if (elt != ml.end()) {
153 throw std::out_of_range(
"object '" + s +
"' not found");
156 val::Value& findR(
const string& s,
bool funcall=
false) {
157 map_type& ml = s[0] !=
'?' ? m : mtmp;
158 auto elt = ml.find(s);
159 if (elt != ml.end() &&
160 (!funcall || ml[s].which() == val::vt_clos || ml[s].which() == val::vt_builting)) {
164 return up->findR(s, funcall);
166 throw std::out_of_range(
"object '" + s +
"' not found");
172 auto a = arr::make_cow<arr::Array<arr::zstring>>(
false, arr::rsv,
Vector<idx_type>{0});
173 for (
auto elt=m.begin(); elt != m.end(); ++elt) {
179 val::Value& add(
string s, val::Value&&
val) {
181 cout <<
"add " << s <<
"=" << val::to_string(
val) <<
" to " <<
this << endl;
183 map_type& ml = s[0] !=
'?' ? m : mtmp;
184 auto elt = ml.find(s);
185 if (elt != ml.end()) {
186 val::Value tmp = elt->second;
190 auto res = ml.emplace(s, val::gval(
val));
191 return res.first->second;
194 auto res = ml.emplace(s, val::gval(
val));
195 return res.first->second;
199 val::Value& addSpecial(
string s, val::Value&&
val) {
201 cout <<
"add special " << s <<
" to " <<
this << endl;
203 auto elt = m.find(s);
204 if (elt != m.end()) {
205 val::Value tmp = elt->second;
209 auto res = m.emplace(s, val::gval(
val));
210 return res.first->second;
212 else if (name ==
"global") {
213 auto res = m.emplace(s, val::gval(
val));
214 return res.first->second;
217 return up->addSpecial(s, std::move(
val));
222 val::Value& addArg(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
224 throw std::range_error(
"'addArg' no meaningful on base frame");
227 val::Value& addEllipsis(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
229 throw std::range_error(
"'addEllipsis' no meaningful on base frame");
232 virtual bool remove(
const string& symb) {
233 if (!symb.size())
return false;
235 map_type& ml = symb[0] !=
'?' ? m : mtmp;
236 return ml.erase(symb) == 1;
239 virtual bool removeSpecial(
const string& symb) {
240 if (!symb.size())
return false;
242 map_type& ml = symb[0] !=
'?' ? m : mtmp;
243 if (ml.erase(symb) == 0) {
244 return up ? up->removeSpecial(symb) :
false;
251 operator string()
const {
253 ss <<
"frame(" << this->up <<
"<-" <<
this <<
')' << endl;
255 ss << p.first <<
":" << val::to_string(p.second) <<
" ";
257 for (
auto p : mtmp) {
258 ss << p.first <<
":" << val::to_string(p.second) <<
" ";
268 virtual bool isFrame() {
return true; }
278 val::Value& addArg(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
280 cout <<
"addArg " << s <<
" to " <<
this <<
"; isRef: " << isRef << endl;
282 map_type& ml = s[0] !=
'?' ? m : mtmp;
283 auto elt = ml.find(s);
284 if (elt != ml.end()) {
287 auto res = ml.emplace(s, isRef ? std::move(
val) : val::gval(
val));
289 setRef(res.first->second);
291 resetRef(res.first->second);
292 return res.first->second;
295 val::Value& addEllipsis(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
296 mv.emplace_back(make_tuple(s, std::move(
val), loc));
297 return get<1>(mv.back());
300 std::vector<std::tuple<std::string, val::Value, yy::location>> mv;
306 static const size_t MAX_ARGS = 5096;
307 typedef std::tuple<string, val::Value, yy::location> arg_t;
311 Frame(
"native", u->global, u, nullptr, ec, nullptr),
312 currentPos(0), mv(nargs)
314 mv.reserve(MAX_ARGS);
317 val::Value& addArg(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
318 mv[currentPos] = make_tuple(s, isRef ? std::move(
val) : val::Value(val::gval(
val)), loc);
320 setRef(get<1>(mv[currentPos]));
322 resetRef(get<1>(mv[currentPos]));
323 return get<1>(mv[currentPos++]);
326 val::Value& addEllipsis(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
328 mv.emplace_back(make_tuple(s, isRef ? std::move(
val) : val::Value(val::gval(
val)), loc));
330 setRef(get<1>(mv.back()));
332 resetRef(get<1>(mv.back()));
333 return get<1>(mv.back());
336 val::Value find(
const string& s)
const {
338 auto res = std::find_if(mv.begin(), mv.end(), [s](
const arg_t& x) { return get<0>(x) == s; });
339 if (res != mv.end()) {
343 return Frame::find(s);
347 val::Value findLocal(
const string& s)
const {
349 auto res = std::find_if(mv.begin(), mv.end(), [s](
const arg_t& x) { return get<0>(x) == s; });
350 if (res != mv.end()) {
354 return Frame::findLocal(s);
358 val::Value& findR(
const string& s,
bool funcall=
false) {
360 auto res = std::find_if(mv.begin(), mv.end(), [s](
const arg_t& x) { return get<0>(x) == s; });
361 const auto res_t = get<1>(*res).which();
362 if (res != mv.end() && (!funcall || res_t == val::vt_clos || res_t == val::vt_builting)) {
366 return Frame::findR(s, funcall);
370 operator string()
const {
372 for (
const auto& t : mv) {
373 const auto& v = get<1>(t);
374 if (v.which() != 0) {
375 ss << get<0>(t) <<
":" << val::to_string(v) <<
" ";
391 return std::any_of(mv.begin(), mv.end(),
392 [](
const std::tuple<string, val::Value, yy::location>& x) {
393 return get<1>(x).which() == val::vt_future; });
397 vector<std::tuple<string, val::Value, yy::location>> mv;
405 shared_ptr<interp::Kont> bc,
406 shared_ptr<interp::Kont> ec,
407 shared_ptr<interp::Kont> cc) :
Frame(
"shadow", u->global, u, bc, ec, cc) { }
409 val::Value find(
const string& s)
const {
411 return Frame::find(s);
418 val::Value findLocal(
const string& s)
const {
420 return Frame::findLocal(s);
423 return up->findLocal(s);
427 val::Value& findR(
const string& s,
bool funcall=
false) {
429 return Frame::findR(s, funcall);
432 return up->findR(s, funcall);
437 return up->getNames();
440 val::Value& add(
string s, val::Value&&
val) {
443 cout <<
"add " << s <<
" to " <<
this << endl;
445 return Frame::add(s, std::move(
val));
448 return up->add(s, std::move(
val));
452 val::Value& addSpecial(
string s, val::Value&&
val) {
453 return up->addSpecial(s, std::move(
val));
456 val::Value& addArg(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
457 return up->add(s, std::move(
val));
460 val::Value& addEllipsis(
string s, val::Value&&
val,
const yy::location& loc,
bool isRef) {
462 throw std::out_of_range(
"'addEllipsis' irrelevant for shadow frame");
465 bool remove(
const string& symb) {
466 return up->remove(symb);
469 bool removeSpecial(
const string& symb) {
470 return up->removeSpecial(symb);
473 operator string()
const {
476 ss <<
"shadow(" << string(*up) <<
"<-" <<
this <<
")";
479 ss <<
"shadow(null<-" <<
this <<
")";
488 virtual shpfrm getTrueFrame() {
return up->getTrueFrame(); }