#include "vm_apply.h"
namespace NSc::NUt {
#define Y_GEN_TRY_OP(op) \
if (!op) { return false; }
#define Y_GEN_SRC_OP(op, arg, st, act) \
switch (act.GetSrc(arg).Type) { \
case TSrc::T_LREF__POS: \
op(st.LRef(act.GetSrc(arg).Pos)); \
break; \
case TSrc::T_CREF__POS: \
op(st.CRef(act.GetSrc(arg).Pos)); \
break; \
case TSrc::T_RREF__POS: \
op(st.RRef(act.GetSrc(arg).Pos)); \
break; \
default: \
Y_ABORT(); \
}
#define Y_GEN_SRC_TRY_OP(op, arg, st, act) \
if (st.CRef(act.GetSrc(arg).Pos).IsSameOrAncestorOf(st.Current())) { \
return false; \
} \
Y_GEN_SRC_OP(op, arg, st, act);
#define Y_GEN_DST_OP(op, arg, st, act) \
switch (act.GetDst(arg).Type) { \
case TDst::T_CREATE_BACK_LREF: \
Y_GEN_TRY_OP(st.TryPushBack(op)) \
break; \
case TDst::T_CREATE_BACK_CREF: \
Y_GEN_TRY_OP(st.TryPushBack(std::as_const(op))) \
break; \
case TDst::T_CREATE_BACK_RREF: \
Y_GEN_TRY_OP(st.TryPushBack(std::move(op))) \
break; \
case TDst::T_CREATE_FRONT_LREF: \
Y_GEN_TRY_OP(st.TryPushFront(op)) \
break; \
case TDst::T_CREATE_FRONT_CREF: \
Y_GEN_TRY_OP(st.TryPushFront(std::as_const(op))) \
break; \
case TDst::T_CREATE_FRONT_RREF: \
Y_GEN_TRY_OP(st.TryPushFront(std::move(op))) \
break; \
case TDst::T_LREF__POS: \
st.LRef(act.GetDst(arg).Pos) = op; \
break; \
case TDst::T_CREF__POS: \
st.LRef(act.GetDst(arg).Pos) = std::as_const(op); \
break; \
case TDst::T_RREF__POS: \
st.LRef(act.GetDst(arg).Pos) = std::move(op); \
break; \
default: \
Y_ABORT(); \
}
#define Y_GEN_REF_OP(op, arg, st, act) \
switch (act.GetRef(arg).Type) { \
case TRef::T_CREATE_BACK: \
Y_GEN_TRY_OP(st.TryPushBack(op)) \
break; \
case TRef::T_CREATE_FRONT: \
Y_GEN_TRY_OP(st.TryPushFront(op)) \
break; \
case TRef::T_REF__POS: \
st.LRef(act.GetRef(arg).Pos) = op; \
break; \
default: \
Y_ABORT(); \
}
#define Y_GEN_PTR_OP(op, arg, st, act) \
if (auto* r = (op)) { \
switch (act.GetRef(arg).Type) { \
case TRef::T_CREATE_BACK: \
Y_GEN_TRY_OP(st.TryPushBack(*r)) \
break; \
case TRef::T_CREATE_FRONT: \
Y_GEN_TRY_OP(st.TryPushFront(*r)) \
break; \
case TRef::T_REF__POS: \
st.LRef(act.GetRef(arg).Pos) = *r; \
break; \
default: \
Y_ABORT(); \
} \
}
bool ApplyNextAction(TVMState& st, TVMAction act) {
switch (act.Type) {
case VMA_JMP__POS:
st.Pos = act.GetPos(0);
return true;
case VMA_CREATE_BACK:
Y_GEN_TRY_OP(st.TryPushBack())
return true;
case VMA_CREATE_BACK__SRC:
switch (act.GetSrc(0).Type) {
case TSrc::T_LREF__POS:
Y_GEN_TRY_OP(st.TryPushBack(st.LRef(act.GetSrc(0).Pos)))
break;
case TSrc::T_CREF__POS:
Y_GEN_TRY_OP(st.TryPushBack(st.CRef(act.GetSrc(0).Pos)))
break;
case TSrc::T_RREF__POS:
Y_GEN_TRY_OP(st.TryPushBack(st.RRef(act.GetSrc(0).Pos)))
break;
default:
Y_ABORT();
}
return true;
case VMA_CREATE_FRONT:
Y_GEN_TRY_OP(st.TryPushFront())
return true;
case VMA_CREATE_FRONT__SRC:
switch (act.GetSrc(0).Type) {
case TSrc::T_LREF__POS:
Y_GEN_TRY_OP(st.TryPushFront(st.LRef(act.GetSrc(0).Pos)))
break;
case TSrc::T_CREF__POS:
Y_GEN_TRY_OP(st.TryPushFront(st.CRef(act.GetSrc(0).Pos)))
break;
case TSrc::T_RREF__POS:
Y_GEN_TRY_OP(st.TryPushFront(st.RRef(act.GetSrc(0).Pos)))
break;
default:
Y_ABORT();
}
return true;
case VMA_DESTROY_BACK:
return st.TryPopBack();
case VMA_DESTROY_FRONT:
return st.TryPopFront();
case VMA_ASSIGN__SRC:
Y_GEN_SRC_OP(st.Current() = , 0, st, act);
return true;
case VMA_SET_STRING__IDX:
st.Current().SetString(act.GetString(0));
return true;
case VMA_SET_INT_NUMBER__IDX:
st.Current().SetIntNumber(act.GetIntNumber(0));
return true;
case VMA_SET_DICT:
st.Current().SetDict();
return true;
case VMA_SET_ARRAY:
st.Current().SetArray();
return true;
case VMA_SET_NULL:
st.Current().SetNull();
return true;
case VMA_GET_JSON:
st.Current().ToJson();
return true;
case VMA_ARRAY_CLEAR:
st.Current().ClearArray();
return true;
case VMA_ARRAY_PUSH:
st.Current().Push();
return true;
case VMA_ARRAY_PUSH__SRC:
Y_GEN_SRC_TRY_OP(st.Current().Push, 0, st, act);
return true;
case VMA_ARRAY_PUSH__DST:
Y_GEN_DST_OP(st.Current().Push(), 0, st, act);
return true;
case VMA_ARRAY_POP__REF:
Y_GEN_REF_OP(st.Current().Pop(), 0, st, act);
return true;
case VMA_ARRAY_INSERT__IDX:
st.Current().Insert(act.GetIdx(0));
return true;
case VMA_ARRAY_INSERT__IDX_SRC:
Y_GEN_SRC_TRY_OP(st.Current().Insert(act.GetIdx(0)) = , 1, st, act);
return true;
case VMA_ARRAY_INSERT__IDX_DST:
Y_GEN_DST_OP(st.Current().Insert(act.GetIdx(0)), 1, st, act);
return true;
case VMA_ARRAY_DELETE__IDX_REF:
Y_GEN_REF_OP(st.Current().Delete(act.GetIdx(0)), 1, st, act);
return true;
case VMA_ARRAY_GET__IDX_REF:
Y_GEN_REF_OP(st.Current().Get(act.GetIdx(0)), 1, st, act);
return true;
case VMA_ARRAY_GET_OR_ADD__IDX:
st.Current().GetOrAdd(act.GetIdx(0));
return true;
case VMA_ARRAY_GET_OR_ADD__IDX_SRC:
Y_GEN_SRC_TRY_OP(st.Current().GetOrAdd(act.GetIdx(0)) = , 1, st, act);
return true;
case VMA_ARRAY_GET_OR_ADD__IDX_DST:
Y_GEN_DST_OP(st.Current().GetOrAdd(act.GetIdx(0)), 1, st, act);
return true;
case VMA_ARRAY_GET_NO_ADD__IDX_REF:
Y_GEN_PTR_OP(st.Current().GetNoAdd(act.GetIdx(0)), 1, st, act);
return true;
case VMA_DICT_CLEAR:
st.Current().ClearDict();
return true;
case VMA_DICT_DELETE__IDX:
st.Current().Delete(act.GetKey(0));
return true;
case VMA_DICT_DELETE__IDX_REF:
Y_GEN_REF_OP(st.Current().Delete(act.GetKey(0)), 1, st, act);
return true;
case VMA_DICT_GET__IDX_REF:
Y_GEN_REF_OP(st.Current().Get(act.GetKey(0)), 1, st, act);
return true;
case VMA_DICT_GET_OR_ADD__IDX:
st.Current().GetOrAdd(act.GetKey(0));
return true;
case VMA_DICT_GET_OR_ADD__IDX_SRC:
Y_GEN_SRC_TRY_OP(st.Current().GetOrAdd(act.GetKey(0)) = , 1, st, act);
return true;
case VMA_DICT_GET_OR_ADD__IDX_DST:
Y_GEN_DST_OP(st.Current().GetOrAdd(act.GetKey(0)), 1, st, act);
return true;
case VMA_DICT_GET_NO_ADD__IDX_REF:
Y_GEN_PTR_OP(st.Current().GetNoAdd(act.GetKey(0)), 1, st, act);
return true;
case VMA_MERGE_UPDATE__POS:
st.Current().MergeUpdate(st.LRef(act.GetPos(0)));
return true;
case VMA_MERGE_REVERSE__POS:
st.Current().ReverseMerge(st.LRef(act.GetPos(0)));
return true;
case VMA_MERGE_COPY_FROM__POS:
st.Current().CopyFrom(st.LRef(act.GetPos(0)));
return true;
case VMA_SWAP__POS:
st.Current().Swap(st.LRef(act.GetPos(0)));
return true;
case VMA_EQUAL__POS_POS:
TValue::Equal(st.CRef(act.GetPos(0)), st.CRef(act.GetPos(1)));
return true;
case VMA_SELECT_NO_ADD__PATH_REF:
Y_GEN_REF_OP(st.Current().TrySelect(act.GetPath(0)), 1, st, act);
return true;
case VMA_SELECT_OR_ADD__PATH_REF:
Y_GEN_PTR_OP(st.Current().TrySelectOrAdd(act.GetPath(0)), 1, st, act);
return true;
case VMA_SELECT_AND_DELETE__PATH_REF:
Y_GEN_REF_OP(st.Current().TrySelectAndDelete(act.GetPath(0)), 1, st, act);
return true;
default:
Y_ABORT();
}
}
}