forked from nique_372/BasesParserSLan
901 lines
28 KiB
MQL5
901 lines
28 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Query.mqh |
|
|
//| Copyright 2026, Nique. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2026, Nique."
|
|
#property link "https://www.mql5.com"
|
|
#property strict
|
|
|
|
#ifndef BASESPARSERSLAN_SRC_QUERY_QUERY_MQH
|
|
#define BASESPARSERSLAN_SRC_QUERY_QUERY_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#include "Asm.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
namespace TSN
|
|
{
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CSLDomQueryVm : public CSLDomQueryCompiler
|
|
{
|
|
private:
|
|
//--- Iteracion
|
|
//- ambos (que tipos se aceptan)
|
|
uchar m_stack_it_types[TSN_DOMPATH_MAX_DEPTH_ITER];
|
|
|
|
//- iteracion de obj
|
|
CHashMapFastIterator(string, CDomNodeBase*) m_stack_it_obj[TSN_DOMPATH_MAX_DEPTH_ITER];
|
|
|
|
//- iteracion de array
|
|
CDomNodeManager* m_stack_it_ptr[TSN_DOMPATH_MAX_DEPTH_ITER]; // Punteros de manager
|
|
int m_stack_it_k[TSN_DOMPATH_MAX_DEPTH_ITER]; // k (vlaor acutal de itacion)
|
|
int m_stack_it_count[TSN_DOMPATH_MAX_DEPTH_ITER]; // numero de elementos restantes.
|
|
int m_stack_it_ix[TSN_DOMPATH_MAX_DEPTH_ITER]; // indice en m_ctx.m_nodes
|
|
|
|
//- indice de la iteracion actual
|
|
int m_stack_it_curr;
|
|
|
|
//--- Registros de nodes
|
|
CDomNodeBase* m_dnodes[TSN_DOMPATH_MAX_SIZE_DNODES];
|
|
int m_dnodes_size;
|
|
|
|
//--- Actual
|
|
ulong m_current_hash;
|
|
CDomNodeBase* m_curr;
|
|
|
|
//--- Instrution pointer
|
|
int m_ip;
|
|
|
|
//---
|
|
CDomNodeBase* m_base_node;
|
|
|
|
public:
|
|
//--- Call frame actual
|
|
int m_num_args;
|
|
int m_reg_start_params;
|
|
|
|
//--- Objeto actual
|
|
int m_el_s;
|
|
int m_el_r;
|
|
|
|
public:
|
|
CSLDomQueryVm(void) {}
|
|
~CSLDomQueryVm(void) {}
|
|
|
|
//--- Metodo base
|
|
bool Run(CDomNodeBase* &elemts[]);
|
|
|
|
//---
|
|
void BaseNode(CDomNodeBase* base) { m_base_node = base; }
|
|
CDomNodeBase* BaseNode() { return m_base_node; }
|
|
|
|
//--- Funciones
|
|
// Leer
|
|
template <typename T>
|
|
__forceinline T FReadIntegerAs(int param_index);
|
|
__forceinline double FReadDouble(int param_index);
|
|
__forceinline string FReadString(int param_index);
|
|
__forceinline bool FReadBool(int param_index);
|
|
CDomNodeBase* FReadNode(int param_index);
|
|
|
|
// Pusearh un valor a los registros
|
|
template <typename T>
|
|
void FPushInteger(T v);
|
|
void FPushValue(double v);
|
|
void FPushValue(bool v);
|
|
void FPushValue(const string& v);
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Read |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
__forceinline T CSLDomQueryVm::FReadIntegerAs(int param_index)
|
|
{
|
|
return (T)m_reg[m_reg_start_params + param_index].v.iv;
|
|
}
|
|
//+------------------------------------------------------------------+>
|
|
__forceinline bool CSLDomQueryVm::FReadBool(int param_index)
|
|
{
|
|
return m_reg[m_reg_start_params + param_index].v.bv;
|
|
}
|
|
//+------------------------------------------------------------------+>
|
|
__forceinline double CSLDomQueryVm::FReadDouble(int param_index)
|
|
{
|
|
return m_reg[m_reg_start_params + param_index].v.dv;
|
|
}
|
|
//+------------------------------------------------------------------+>
|
|
__forceinline string CSLDomQueryVm::FReadString(int param_index)
|
|
{
|
|
return m_sreg[m_reg[m_reg_start_params + param_index].v.ix];
|
|
}
|
|
//+------------------------------------------------------------------+>
|
|
__forceinline CDomNodeBase* CSLDomQueryVm::FReadNode(int param_index)
|
|
{
|
|
return m_dnodes[m_reg[m_reg_start_params + param_index].v.ix];
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Push |
|
|
//+------------------------------------------------------------------+
|
|
void CSLDomQueryVm::FPushValue(bool v)
|
|
{
|
|
m_reg[m_reg_s].tt = DOMPATHV_TYPE_BOL;
|
|
m_reg[m_reg_s++].v.bv = v;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CSLDomQueryVm::FPushValue(double v)
|
|
{
|
|
m_reg[m_reg_s].tt = DOMPATHV_TYPE_FLT;
|
|
m_reg[m_reg_s++].v.dv = v;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
void CSLDomQueryVm::FPushInteger(T v)
|
|
{
|
|
//Print("new integer: ", v);
|
|
m_reg[m_reg_s].tt = DOMPATHV_TYPE_INT;
|
|
m_reg[m_reg_s++].v.iv = (long)v;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CSLDomQueryVm::FPushValue(const string &v)
|
|
{
|
|
//---
|
|
m_sreg[m_sreg_s] = v;
|
|
|
|
//---
|
|
m_reg[m_reg_s].tt = DOMPATHV_TYPE_STR;
|
|
m_reg[m_reg_s++].v.ix = m_sreg_s++;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Bloque math |
|
|
//+------------------------------------------------------------------+
|
|
#define TSN_DOMPATH_DO_MATH_TYPED_PREV(OP) \
|
|
const long l = m_bytecode[m_ip];\
|
|
const long l2 = m_bytecode[m_ip + 1];\
|
|
switch(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].tt)\
|
|
{\
|
|
case DOMPATHV_TYPE_BOL:\
|
|
case DOMPATHV_TYPE_INT:\
|
|
{\
|
|
switch(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].tt)\
|
|
{\
|
|
case DOMPATHV_TYPE_BOL:\
|
|
case DOMPATHV_TYPE_INT:\
|
|
{\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].tt = DOMPATHV_TYPE_INT;\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].v.iv = m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.iv OP m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].v.iv;\
|
|
m_ip += 2;\
|
|
break;\
|
|
}\
|
|
case DOMPATHV_TYPE_FLT:\
|
|
{\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].tt = DOMPATHV_TYPE_FLT;\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].v.dv = (double)m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.iv\
|
|
OP m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].v.dv;\
|
|
m_ip += 2;\
|
|
break;\
|
|
}\
|
|
default:\
|
|
m_ip = int(l2 >> TSN_DOMPATH_BIT_INS_JUMP_START_MATHERR);\
|
|
break;\
|
|
}\
|
|
break;\
|
|
}\
|
|
case DOMPATHV_TYPE_FLT:\
|
|
{\
|
|
switch(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].tt)\
|
|
{\
|
|
case DOMPATHV_TYPE_BOL:\
|
|
case DOMPATHV_TYPE_INT:\
|
|
{\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].tt = DOMPATHV_TYPE_INT;\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].v.dv = (double)m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.iv\
|
|
OP m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].v.dv;\
|
|
m_ip += 2;\
|
|
break;\
|
|
}\
|
|
case DOMPATHV_TYPE_FLT:\
|
|
{\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].v.dv = m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.dv\
|
|
OP m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].v.dv;\
|
|
m_ip += 2;\
|
|
break;\
|
|
}\
|
|
default:\
|
|
m_ip = int(l2 >> TSN_DOMPATH_BIT_INS_JUMP_START_MATHERR);\
|
|
break;\
|
|
}\
|
|
break;\
|
|
}
|
|
|
|
|
|
//----- All
|
|
#define TSN_DOMPATH_DO_MATH_TYPED_ALL(OP) \
|
|
TSN_DOMPATH_DO_MATH_TYPED_PREV(OP)\
|
|
default:\
|
|
{\
|
|
m_ip = int(l2 >> TSN_DOMPATH_BIT_INS_JUMP_START_MATHERR);\
|
|
break;\
|
|
}\
|
|
}
|
|
|
|
//----- Str en especifico
|
|
#define TSN_DOMPATH_DO_MATH_TYPED_SUM \
|
|
TSN_DOMPATH_DO_MATH_TYPED_PREV(+)\
|
|
case DOMPATHV_TYPE_STR:\
|
|
{\
|
|
if(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].tt!=DOMPATHV_TYPE_STR)\
|
|
{\
|
|
m_ip = int(l2 >> TSN_DOMPATH_BIT_INS_JUMP_START_MATHERR);\
|
|
break;\
|
|
}\
|
|
m_sreg[m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].v.ix] = m_sreg[m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.ix] + \
|
|
m_sreg[m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].v.ix];\
|
|
break;\
|
|
}\
|
|
default:\
|
|
m_ip = int(l2 >> TSN_DOMPATH_BIT_INS_JUMP_START_MATHERR);\
|
|
break;\
|
|
}
|
|
|
|
|
|
//-------------------
|
|
#define TSN_DOMPATH_DO_MATH_TYPED_INTEGER(OP) \
|
|
const long l = m_bytecode[m_ip];\
|
|
const long l2 = m_bytecode[m_ip + 1];\
|
|
if((((1 << m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].tt)| (1 << m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].tt)) & (DOMPATHV_F_BOL|DOMPATHV_F_INT))==0)\
|
|
{\
|
|
m_ip = int(l2 >> TSN_DOMPATH_BIT_INS_JUMP_START_MATHERR);\
|
|
}\
|
|
else\
|
|
{\
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].tt=DOMPATHV_TYPE_INT; \
|
|
m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_A(l2)].v.iv = m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.iv OP m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)].v.iv; \
|
|
m_ip+=2;\
|
|
}
|
|
|
|
|
|
// "a" + @.valor @.valor + "a"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
// compara registros mismo layout incnial [8][28][28] [1 = expected][28 = jump]
|
|
#define TSN_DOMPATH_DO_COMP_TYPED_ALL(B, C, OP) \
|
|
switch(B.tt) \
|
|
{ \
|
|
case DOMPATHV_TYPE_BOL: \
|
|
res = (B.v.bv OP (C.tt == DOMPATHV_TYPE_FLT ? (bool)C.v.dv : (bool)C.v.iv)); \
|
|
break; \
|
|
case DOMPATHV_TYPE_INT: \
|
|
res = (B.v.iv OP (C.tt == DOMPATHV_TYPE_FLT ? (long)C.v.dv : C.v.iv)); \
|
|
break; \
|
|
case DOMPATHV_TYPE_FLT: \
|
|
res = (B.v.dv OP (C.tt != DOMPATHV_TYPE_FLT ? (double)C.v.iv : C.v.dv)); \
|
|
break; \
|
|
case DOMPATHV_TYPE_STR: \
|
|
{\
|
|
if(C.tt!=DOMPATHV_TYPE_STR)\
|
|
break; \
|
|
res = m_sreg[B.v.ix] OP m_sreg[C.v.ix]; \
|
|
break; \
|
|
} \
|
|
default: \
|
|
break; \
|
|
}
|
|
|
|
//---
|
|
#define TSN_DOMPATH_DEFINE_BOOL_OP(OP) \
|
|
bool res=false;\
|
|
const long l = m_bytecode[m_ip];\
|
|
TSN_DOMPATH_DO_COMP_TYPED_ALL(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)], m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_C(l)], OP) \
|
|
m_ip++;\
|
|
if(res == bool(m_bytecode[m_ip] & TSN_DOMPATH_BIT_INS_MASK_CMP))\
|
|
m_ip++;\
|
|
else\
|
|
m_ip = TSN_DOMPATH_BIT_INS_GET_JUMP(m_bytecode[m_ip]);
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool CSLDomQueryVm::Run(CDomNodeBase* &elemts[])
|
|
{
|
|
//---
|
|
m_ip = 0;
|
|
m_el_s = 0;
|
|
m_el_r = ArrayResize(elemts, 8, 8);
|
|
m_stack_it_curr = -1;
|
|
|
|
//--- Reinicio
|
|
m_sreg_s = m_locked_sreg; // Empieza desde ahi
|
|
m_dnodes_size = 0; // Tambien de 0
|
|
m_curr = m_base_node;
|
|
// inicia en mitad por convencion para los dinamicos...
|
|
m_reg_s = TSN_DOMPATH_MAX_SIZE_REG >> 1;
|
|
|
|
//---
|
|
while(true)
|
|
{
|
|
switch(uchar(m_bytecode[m_ip]&TSN_DOMPATH_MASK_INS_TYPE))
|
|
{
|
|
//--- Acceso
|
|
// Acceso normal en iteracion
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_KEY:
|
|
{
|
|
// [8bit=Type][28bit=a donde saltar instucino ip]
|
|
// [64hash=completo]
|
|
// accceso directo por hash 64
|
|
m_curr = m_curr.Get((ulong)m_bytecode[m_ip + 1]);
|
|
if(m_curr == NULL)
|
|
{
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE);
|
|
break;
|
|
}
|
|
// no fallo eotnces slatoams dos
|
|
m_ip += 2; // [curr][hash] [aqui]
|
|
break;
|
|
}
|
|
// Acceso F
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_KEY_F:
|
|
{
|
|
// accceso directo por hash 64
|
|
m_curr = m_curr.Get((ulong)m_bytecode[m_ip + 1]);
|
|
if(m_curr == NULL)
|
|
return false;
|
|
// no fallo eotnces slatoams dos
|
|
m_ip += 2; // [curr][hash] [aqui]
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_IDX:
|
|
{
|
|
// [8bit=type][28bit=index][28bit=a donde saltar]
|
|
const int i = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE) & TSN_DOMPATH_INS_MASK_INDEX_ACCES;
|
|
m_curr = m_curr.AtSafe(i); // Acceso
|
|
if(m_curr == NULL)
|
|
{
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_INS_ACCESO_INDEX_JUMP_BIT_S);
|
|
break;
|
|
}
|
|
m_ip++; // todo bien salta al siguiente
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_IDX_F:
|
|
{
|
|
// [8bit=type][28bit=index]
|
|
m_curr = m_curr.AtSafe(int(m_bytecode[m_ip++] >> TSN_DOMPATH_BIT_INS_ETYPE)); // Acceso
|
|
if(m_curr == NULL)
|
|
return false; // aqui seria finalizar directo..
|
|
m_ip++;
|
|
break;
|
|
}
|
|
|
|
//--- Iniciar iteracion
|
|
case DOMPATH_QUERY_INS_TYPE_INICIAR_ITERACION:
|
|
{
|
|
// No reuiqre mas solo type.. [8bit][8bit=qeu aceptamos, 0xff si aceptos de todo]
|
|
//---
|
|
m_stack_it_curr++;
|
|
m_stack_it_types[m_stack_it_curr] = uchar(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE);
|
|
|
|
//---
|
|
if(m_curr.m_type == TSN_SBL_BASE_TYPE_OBJ)
|
|
{
|
|
m_stack_it_obj[m_stack_it_curr] = m_curr.BenginIteration();
|
|
m_stack_it_count[m_stack_it_curr] = -1;
|
|
m_stack_it_k[m_stack_it_curr] = 0;
|
|
}
|
|
else
|
|
{
|
|
m_stack_it_ptr[m_stack_it_curr] = m_curr.m_ctx;
|
|
m_stack_it_ix[m_stack_it_curr] = m_curr.m_v.ix;
|
|
m_stack_it_k[m_stack_it_curr] = 0;
|
|
m_stack_it_count[m_stack_it_curr] = m_curr.Size(); // Tamaño de este array
|
|
}
|
|
|
|
//---
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_ITER_ASSING:
|
|
{
|
|
// [8bit=type ins][28bit en caso falle saltar a]
|
|
const int c = m_stack_it_count[m_stack_it_curr];
|
|
if(c == -1) // iteramos sobre un objeto
|
|
{
|
|
//---
|
|
if(m_stack_it_k[m_stack_it_curr] > 0)
|
|
m_stack_it_obj[m_stack_it_curr].Next();
|
|
|
|
//---
|
|
if(m_stack_it_obj[m_stack_it_curr].IsValid())
|
|
{
|
|
//--- En caso sea 0 no.. venimos.. aun tomamos los valores y recien ahi..
|
|
m_current_hash = m_stack_it_obj[m_stack_it_curr].Hash();
|
|
m_curr = m_stack_it_obj[m_stack_it_curr].Val();
|
|
//Print(m_stack_it_obj[m_stack_it_curr].Key());
|
|
m_stack_it_k[m_stack_it_curr]++;
|
|
}
|
|
else // SI no es valido
|
|
{
|
|
m_stack_it_curr--;
|
|
// Saltamos a donde se diga una vez que termine la iteracion
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE);
|
|
break; // de una salimos de aqui
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(m_stack_it_k[m_stack_it_curr] < m_stack_it_count[m_stack_it_curr])
|
|
{
|
|
m_curr = m_stack_it_ptr[m_stack_it_curr].m_node[m_stack_it_ix[m_stack_it_curr]].values[m_stack_it_k[m_stack_it_curr]++];
|
|
}
|
|
else // Termino..
|
|
{
|
|
m_stack_it_curr--;
|
|
// Saltamos a donde se diga una vez que termine la iteracion
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE);
|
|
break; // de una salimos de aqui
|
|
}
|
|
}
|
|
|
|
//--- Ahora verificamos tipo
|
|
const uchar t = m_stack_it_types[m_stack_it_curr];
|
|
if(t != TSN_DOMPATH_INS_ITER_ALL_TYPES && t != m_curr.m_type) // en caso no coincide
|
|
break; // Volvemos a este punto.. denuvo.. (ip no avanza..)
|
|
|
|
//---
|
|
m_ip++;
|
|
break;
|
|
}
|
|
|
|
//---
|
|
case DOMPATH_QUERY_INS_TYPE_EXIST:
|
|
{
|
|
// 2 slots
|
|
// expectred [type=8|28=JumpInFail][hash=64]
|
|
if(m_current_hash != (ulong)m_bytecode[m_ip + 1])
|
|
{
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE);
|
|
break;
|
|
}
|
|
m_ip += 2; // [act][hash][ahora]
|
|
break;
|
|
}
|
|
|
|
//--- save basico para nativos
|
|
case DOMPATH_QUERY_INS_TYPE_SAVE:
|
|
{
|
|
// [8type][28=k][28=jump]
|
|
const int k = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE) & TSN_DOMPATH_INS_MASK_INDEX_REG;
|
|
switch(m_curr.m_type)
|
|
{
|
|
case TSN_SBL_BASE_TYPE_OBJ:
|
|
{
|
|
m_reg[k].tt = DOMPATHV_TYPE_OBJ;
|
|
m_reg[k].v.ix = m_dnodes_size;
|
|
m_dnodes[m_dnodes_size++] = m_curr;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_ARR:
|
|
{
|
|
m_reg[k].tt = DOMPATHV_TYPE_ARR;
|
|
m_reg[k].v.ix = m_dnodes_size;
|
|
m_dnodes[m_dnodes_size++] = m_curr;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_INT:
|
|
{
|
|
m_reg[k].v.iv = m_curr.m_v.iv;
|
|
m_reg[k].tt = DOMPATHV_TYPE_INT;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_FLT:
|
|
{
|
|
m_reg[k].v.dv = m_curr.m_v.dv;
|
|
m_reg[k].tt = DOMPATHV_TYPE_FLT;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_BOL:
|
|
{
|
|
m_reg[k].v.bv = m_curr.m_v.bv;
|
|
m_reg[k].tt = DOMPATHV_TYPE_BOL;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_STR:
|
|
{
|
|
m_reg[k].tt = TSN_SBL_BASE_TYPE_STR;
|
|
m_reg[k].v.ix = m_sreg_s;
|
|
m_sreg[m_sreg_s++] = m_curr.m_ctx.m_string_stack[m_curr.m_v.ix];
|
|
m_ip++;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// Nota que solo los valores normales como string\int se guranda en reg
|
|
// Los otros como arr tambien pero solo se almacnea us nodo su unica utilidad es para funciones..
|
|
// Tipo invalido null
|
|
// Aqui un jump a direccion especificada
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_SAVEPTR_JUMP_BIT_START);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//---
|
|
// Las insutrccions tipo save tambin indican el final.. de un acceso
|
|
// dado que la idea es ir accediendo y luego guarda su valor
|
|
// Retrocedemos al valor base de la iteracion...
|
|
// Por ahora solo objetos luego veremos la logica para arrays.
|
|
m_curr = m_stack_it_obj[m_stack_it_curr].Val();
|
|
break;
|
|
}
|
|
|
|
//--- Version 2.. esta no resetea mantiene m_curr donde estuvo
|
|
case DOMPATH_QUERY_INS_TYPE_SAVE_NO_RESET:
|
|
{
|
|
// [8type][28=k][28=jump]
|
|
const int k = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE) & TSN_DOMPATH_INS_MASK_INDEX_REG;
|
|
switch(m_curr.m_type)
|
|
{
|
|
case TSN_SBL_BASE_TYPE_OBJ:
|
|
{
|
|
m_reg[k].tt = DOMPATHV_TYPE_OBJ;
|
|
m_reg[k].v.ix = m_dnodes_size;
|
|
m_dnodes[m_dnodes_size++] = m_curr;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_ARR:
|
|
{
|
|
m_reg[k].tt = DOMPATHV_TYPE_ARR;
|
|
m_reg[k].v.ix = m_dnodes_size;
|
|
m_dnodes[m_dnodes_size++] = m_curr;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_INT:
|
|
{
|
|
m_reg[k].v.iv = m_curr.m_v.iv;
|
|
m_reg[k].tt = DOMPATHV_TYPE_INT;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_FLT:
|
|
{
|
|
m_reg[k].v.dv = m_curr.m_v.dv;
|
|
m_reg[k].tt = DOMPATHV_TYPE_FLT;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_BOL:
|
|
{
|
|
m_reg[k].v.bv = m_curr.m_v.bv;
|
|
m_reg[k].tt = DOMPATHV_TYPE_BOL;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
case TSN_SBL_BASE_TYPE_STR:
|
|
{
|
|
m_reg[k].tt = TSN_SBL_BASE_TYPE_STR;
|
|
m_reg[k].v.ix = m_sreg_s;
|
|
m_sreg[m_sreg_s++] = m_curr.m_ctx.m_string_stack[m_curr.m_v.ix];
|
|
m_ip++;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// Nota que solo los valores normales como string\int se guranda en reg
|
|
// Los otros como arr tambien pero solo se almacnea us nodo su unica utilidad es para funciones..
|
|
// Tipo invalido null
|
|
// Aqui un jump a direccion especificada
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_SAVEPTR_JUMP_BIT_START);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
//--- math
|
|
// math entero usa 2 slots.. para sus intrucciones
|
|
// [type][28][28] | [28] [28]
|
|
// 8type 28b 28c 28a 28jump
|
|
case DOMPATH_QUERY_INS_TYPE_M_MUL:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_ALL(*)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_RES:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_ALL(-)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_DIV:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_ALL( /)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_SUM:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_SUM
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_MOD:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_INTEGER( %)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_BIT_OR:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_INTEGER( |)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_BIT_AND:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_INTEGER(&)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_BIT_XOR:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_INTEGER(^)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_BIT_DEZ_IZQ:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_INTEGER( <<)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_BIT_DEZ_DRC:
|
|
{
|
|
TSN_DOMPATH_DO_MATH_TYPED_INTEGER( >>)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_M_BIT_NOT:
|
|
{
|
|
//---
|
|
const long l = m_bytecode[m_ip];
|
|
const long l2 = m_bytecode[m_ip + 1];
|
|
|
|
//---
|
|
if(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].tt != DOMPATHV_TYPE_INT)
|
|
m_ip = int(m_bytecode[l] >> TSN_DOMPATH_BIT_INS_JUMP_START_UNARY_MATHERR); // fallo
|
|
else
|
|
{
|
|
m_reg[l2].tt = DOMPATHV_TYPE_INT;
|
|
m_reg[l2].v.iv = ~m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.iv;
|
|
m_ip += 2;
|
|
}
|
|
break;
|
|
}
|
|
|
|
//---
|
|
case DOMPATH_QUERY_INS_TYPE_M_UNARY_NOT:
|
|
{
|
|
const long l = m_bytecode[m_ip];
|
|
const long l2 = m_bytecode[m_ip + 1];
|
|
switch(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].tt)
|
|
{
|
|
case DOMPATHV_TYPE_BOL:
|
|
{
|
|
// bool a int
|
|
m_reg[l2].tt = DOMPATHV_TYPE_INT;
|
|
m_reg[l2].v.iv = -int(m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.bv);
|
|
m_ip += 2;
|
|
break;
|
|
}
|
|
case DOMPATHV_TYPE_INT:
|
|
{
|
|
// bool a int
|
|
m_reg[l2].tt = DOMPATHV_TYPE_INT;
|
|
m_reg[l2].v.iv = -m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.iv;
|
|
m_ip += 2;
|
|
break;
|
|
}
|
|
case DOMPATHV_TYPE_FLT:
|
|
{
|
|
// bool a int
|
|
m_reg[l2].tt = DOMPATHV_TYPE_FLT;
|
|
m_reg[l2].v.dv = -m_reg[TSN_DOMPATH_INS_MATH_BIT_GET_B(l)].v.dv;
|
|
m_ip += 2;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// Tipo invalido string, etc..
|
|
m_ip = int(m_bytecode[l] >> TSN_DOMPATH_BIT_INS_JUMP_START_UNARY_MATHERR); // fallo
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
//--- Operaciones de compracion
|
|
// [type][28][28] | [2][28][1]
|
|
//--- Cmp (comparaciones..)
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_EQ:
|
|
{
|
|
TSN_DOMPATH_DEFINE_BOOL_OP( ==)
|
|
//Print("Hola: ", res);
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_MENOR:
|
|
{
|
|
TSN_DOMPATH_DEFINE_BOOL_OP( <)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_MENOR_EQ:
|
|
{
|
|
TSN_DOMPATH_DEFINE_BOOL_OP( <=)
|
|
break;
|
|
}
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_IS:
|
|
{
|
|
//--- [8bytes][KIndex=28][28=Jump] | [1 bit = resultado esperado]
|
|
bool res = false;
|
|
const int k = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE) & TSN_DOMPATH_INS_MASK_INDEX_REG;
|
|
|
|
switch(m_reg[k].tt)
|
|
{
|
|
case DOMPATHV_TYPE_BOL:
|
|
res = m_reg[k].v.bv;
|
|
break;
|
|
case DOMPATHV_TYPE_INT:
|
|
res = m_reg[k].v.iv != 0;
|
|
break;
|
|
case DOMPATHV_TYPE_FLT:
|
|
res = m_reg[k].v.dv != 0;
|
|
break;
|
|
case DOMPATHV_TYPE_STR:
|
|
res = m_sreg[m_reg[k].v.ix].Length() != 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//--
|
|
//Print("is: ", res, " k: ", k);
|
|
|
|
//---
|
|
m_ip++;
|
|
if(res == bool(m_bytecode[m_ip]))
|
|
m_ip++; // sigueinte normal
|
|
else
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_JUMP_START_CMPIS_FALSE); // saltamos
|
|
break;
|
|
}
|
|
|
|
//---
|
|
case DOMPATH_QUERY_INS_TYPE_CALL:
|
|
{
|
|
// [8type][28=direecion donde empieza todo][28 numero de argumentos][Indice de la funcion]
|
|
// [indice de funcion] (slot completo)
|
|
m_reg_start_params = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE) & TSN_DOMPATH_INS_MASK_INDEX_REG;
|
|
// los parameotrs van luego de reg out siempre... van en esas direcciones
|
|
|
|
m_num_args = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_BIT_START_NARGS);
|
|
m_ip++;
|
|
|
|
//---
|
|
// Empiza aqui todo... el resultado
|
|
const int lock = m_reg_start_params + m_num_args;
|
|
|
|
//---
|
|
m_reg_s = lock + 1;
|
|
|
|
//---
|
|
m_funcs[m_bytecode[m_ip]](&this); // llamamos
|
|
//Print("Num:" , (m_reg_s - lock) - 1);
|
|
|
|
//---
|
|
m_reg[lock].tt = DOMPATHV_TYPE_INT;
|
|
m_reg[lock].v.iv = (m_reg_s - lock) - 1; // 1 dado qeu empiza...
|
|
|
|
// ahora ya se sape que la funcion escrbiio un valor en dicho registro
|
|
m_ip++; // Siguiente insturccion
|
|
break;
|
|
}
|
|
|
|
//---
|
|
case DOMPATH_QUERY_INS_TYPE_RESERVE:
|
|
{
|
|
// Esta insturccion unicamnete incremente el regsize par que el siguiente
|
|
// valor donde se ponga dciho valor sea el sigueinte slot.. dado que se reserva este
|
|
m_reg_s++;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
|
|
//--- Slicing cumpleto de array
|
|
case DOMPATH_QUERY_INS_TYPE_SLICING:
|
|
{
|
|
// En total ocupa 2 slots
|
|
// [8type | 28=jump | 28=strat]
|
|
// [28=end | 28=step]
|
|
// En caso no sea array...
|
|
// int jump_index = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE) & TSN_DOMPATH_INS_MASK_INDEX_REG;
|
|
if(m_curr.m_type != TSN_SBL_BASE_TYPE_ARR)
|
|
{
|
|
// Saltar a la direccion especificada
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE)
|
|
& TSN_DOMPATH_INS_MASK_INDEX_JMP;
|
|
break;
|
|
}
|
|
const int s = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_BIT_START_SLSTART);
|
|
const long l2 = (m_bytecode[++m_ip]);
|
|
const int e = int(l2 & TSN_DOMPATH_BIT_INS_MASK_SLMASK);
|
|
const int p = int(l2 >> TSN_DOMPATH_BIT_INS_BIT_START_SLPASO);
|
|
m_el_s += m_curr.PySlicing(elemts, m_el_s, s, e, p);
|
|
m_ip++;
|
|
break;
|
|
}
|
|
|
|
//---
|
|
case DOMPATH_QUERY_INS_TYPE_JUMP:
|
|
{
|
|
// [8byt type][28bit=jump dir]
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE);
|
|
break;
|
|
}
|
|
|
|
//---
|
|
case DOMPATH_QUERY_INS_TYPE_COPY_ALL:
|
|
{
|
|
const int t = m_curr.CopyTo(elemts, m_el_s);
|
|
if(t == -1)
|
|
{
|
|
m_ip = int(m_bytecode[m_ip] >> TSN_DOMPATH_BIT_INS_ETYPE);
|
|
break;
|
|
}
|
|
m_el_s += t;
|
|
m_ip++;
|
|
break;
|
|
}
|
|
|
|
//--- Finaes
|
|
case DOMPATH_QUERY_INS_TYPE_APPEND:
|
|
{
|
|
if(m_el_s + 1 >= m_el_r)
|
|
{
|
|
m_el_r += (m_el_s << 1) + 8;
|
|
ArrayResize(elemts, m_el_r, m_el_r);
|
|
}
|
|
elemts[m_el_s++] = m_curr; // Actual
|
|
m_ip++;
|
|
break;
|
|
}
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_SALIDA:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//---
|
|
}
|
|
|
|
|
|
//--- End namespace
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
#endif // BASESPARSERSLAN_SRC_QUERY_QUERY_MQH
|