BasesParserSLan/Src/Query/Query.mqh
Nique_372 d17d728892
2026-07-24 21:56:07 -05:00

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