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

993 lines
31 KiB
MQL5

//+------------------------------------------------------------------+
//| Asm.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com"
#property strict
#ifndef BASESPARSERSLAN_SRC_QUERY_ASM_MQH
#define BASESPARSERSLAN_SRC_QUERY_ASM_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "Parser.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define TSN_DOMPATH_ASMPARSE_TYPE_HASH 4
//+------------------------------------------------------------------+
#define TSN_DOMPATH_ASMPARSE_CHECK_VALUE \
m_pila_curr++;\
if(m_pila_curr < m_pila_ins_t) \
{\
m_p_f = m_pila_ins[m_pila_curr] | ASM_PARSER_TOKF_COMMENT; \
while(true)\
{\
const uchar _c = m_raw[m_pos];\
if(_c < 33)\
{\
m_pos++;\
continue;\
}\
m_next = g_dompath_asm_toks[_c];\
if((m_p_f & (1 << m_next)) == 0)\
{\
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_MALFORMERD_ASM;\
return false;\
}\
break;\
}\
}\
else\
{\
m_next = ASM_PARSER_TOK_PARSE_END; \
}
//----
// Luego de insutrccion busqueda base..
#define TSN_DOMPATH_INIT_BUSQEUDA_INS \
m_p_f = m_pila_ins[m_pila_curr] | ASM_PARSER_TOKF_COMMENT; \
while(true)\
{\
const uchar _c = m_raw[m_pos];\
if(_c < 33)\
{\
m_pos++;\
continue;\
}\
m_next = g_dompath_asm_toks[_c];\
if((m_p_f & (1 << m_next)) == 0)\
{\
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_MALFORMERD_ASM;\
return false;\
}\
break;\
}\
//--- Lugeo de terminar una instruccion buscamos mas tokens...
#define TSN_DOMPATH_ASMPARSER_NEXT_TOKS \
while(true)\
{\
const uchar _c = m_raw[m_pos];\
if(_c < 33)\
{\
m_pos++;\
continue;\
}\
m_next = g_dompath_asm_toks[_c];\
if((ASM_PARSER_ALL_VALID_NORMAL & (1 << m_next)) == 0)\
{\
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_MALFORMERD_ASM_CTX_GEN;\
return false;\
}\
break;\
}
//---
#define TSN_DOMPATH_ASM_CHECK_R_PHASHES \
if(m_pendings_hashes_s >= m_pendings_hashes_r) \
{ \
m_pendings_hashes_r <<= 1; \
ArrayResize(m_pendings_hashes, m_pendings_hashes_r, m_pendings_hashes_r); \
}
//--- Resuelve un jump ya (si el alias ya fue visto) o lo encola como pendiente
#define TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(HASH_VAL, SLOT_POS, OPINDEX) \
{ \
int _jump_out; \
const ulong _temp = (ulong)HASH_VAL; \
if(!m_hash_jumps.TryGet(_temp, _jump_out)) \
{ \
m_pendings_hashes[m_pendings_hashes_s].bytecode_pos = (SLOT_POS); \
m_pendings_hashes[m_pendings_hashes_s].hash = _temp; \
m_pendings_hashes[m_pendings_hashes_s].mask = g_dompath_op_codes[(OPINDEX)].mask; \
m_pendings_hashes[m_pendings_hashes_s++].bit_start_mask = g_dompath_op_codes[(OPINDEX)].bit_start; \
TSN_DOMPATH_ASM_CHECK_R_PHASHES \
} \
else \
{ \
m_bytecode[(SLOT_POS)] |= long(_jump_out) << g_dompath_op_codes[(OPINDEX)].bit_start; \
} \
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// ASM
bool CSLDomQueryCompiler::CompileAsm(void)
{
//---
m_pos = m_offset;
m_pila_curr = 0;
m_pila_v_s = 0;
m_p_f = 0;
m_pendings_hashes_s = 0;
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_NOT;
m_sreg_s = 0; // Se resetea.. el pool de strigns empezamos de 0
m_hash_jumps.Clear();
//---
TSN_DOMPATH_ASMPARSER_NEXT_TOKS
//---
while(true)
{
switch(m_next)
{
case ASM_PARSER_TOK_REGISTER: // R0
{
// Avanzamos exacto
m_pos += 4; // %[r][e][g][aqui]
//--- Rellenamos la pila
// numero puro primero
m_pila_ins[0] = ASM_PARSER_TOKF_NUMBER;
// soporta eq primero
m_pila_ins[1] = ASM_PARSER_TOKF_EQ;
// luego busca un valor
m_pila_ins[2] = ASM_PARSER_TOKF_TRUE | ASM_PARSER_TOKF_NUMBER |
ASM_PARSER_TOKF_FALSE | ASM_PARSER_TOKF_STR | ASM_PARSER_TOKF_S_STR;
// luego tambien hace el registro final
m_pila_ins[3] = DOMPATH_QUERY_INS_TYPE_REG;
m_pila_ins_t = 3;
//--- Siguientes instrucciones
TSN_DOMPATH_INIT_BUSQEUDA_INS
break;
}
//---
case ASM_PARSER_TOK_NUMBER:
{
//---
long v = 0;
//--- Validamos signo
long mask = 0;
uchar ch = m_raw[m_pos];
if(ch == '-')
{
mask = -1;
m_pos++; // Ahora en numero
ch = m_raw[m_pos];
}
//---
ch ^= '0';
//---
while(true)
{
//---
v = (v << 3) + (v << 1) + ch;
//--- *
m_pos++;
//---
ch = m_raw[m_pos] ^ '0';
//---
if(ch < 10)
{
continue;
}
else
if(ch == 30 || (ch | 0x20) == 117) // .
{
//---
double val = double(v);
if(ch == 30)
{
m_pos++;
long frac_int = 0;
int fract_digits = 0;
//---
while(true)
{
const uchar c = m_raw[m_pos] ^ '0';
if(c > 9)
break;
frac_int = (frac_int << 3) + (frac_int << 1) + c;
fract_digits++;
m_pos++;
}
//---
val += frac_int * g_Exp10[fract_digits];
}
//--- 10e50.02500140
if((m_raw[m_pos] | 0x20) == 'e') // e or E
{
//---
m_pos++;
bool exp_sign = true;
uchar _c = m_raw[m_pos];
if(_c == '-')
{
exp_sign = false;
m_pos++;
}
else
if(_c == '+')
{
m_pos++;
}
//---
_c = m_raw[m_pos] ^ '0';
int exp_val = 0;
//---
while(true)
{
exp_val = (exp_val << 3) + (exp_val << 1) + _c;
//---
m_pos++;
_c = m_raw[m_pos] ^ '0';
if(_c > 9)
break;
}
//---
val *= (exp_sign) ? g_Pow10[exp_val] : g_Exp10[exp_val];
}
//---
static BitInterpreter bit;
bit.double_value = val;
bit.long_value ^= (mask & (1LL << 63));
m_pila_v[m_pila_v_s] = bit.long_value;
m_pila_v_t[m_pila_v_s++] = DOMPATHV_TYPE_FLT;
break;
}
else
{
m_pila_v[m_pila_v_s] = (v ^ mask) - mask;
m_pila_v_t[m_pila_v_s++] = DOMPATHV_TYPE_INT;
break; // Fin
}
}
//---
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
case ASM_PARSER_TOK_TRUE:
{
//
m_pos += 4;
m_pila_v[m_pila_v_s] = 1;
m_pila_v_t[m_pila_v_s++] = DOMPATHV_TYPE_BOL;
//---
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
case ASM_PARSER_TOK_FALSE:
{
//
m_pos += 5;
m_pila_v[m_pila_v_s] = 0;
m_pila_v_t[m_pila_v_s++] = DOMPATHV_TYPE_BOL;
//---
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
case ASM_PARSER_TOK_STRING:
{
//---
m_pos++; // luego del S
const int start = ++m_pos;
//----
while(true)
{
// PrintFormat("Analizando: '%s'", CharArrayToString(m_raw, m_pos, 8));
const ulong chunk = (ulong)m_raw[m_pos]
| (ulong)m_raw[m_pos + 1] << 8
| (ulong)m_raw[m_pos + 2] << 16
| (ulong)m_raw[m_pos + 3] << 24
| (ulong)m_raw[m_pos + 4] << 32
| (ulong)m_raw[m_pos + 5] << 40
| (ulong)m_raw[m_pos + 6] << 48
| (ulong)m_raw[m_pos + 7] << 56;
//---
const ulong x_bs = chunk ^ TSNTABLES_SWAR_MASK_BACK_SLASH;
ulong has_bs = TSNTABLES_SWAR_HAS(x_bs);
const ulong x_qt = chunk ^ TSNTABLES_SWAR_MASK_COMILLA;
const ulong has_qt = TSNTABLES_SWAR_HAS(x_qt);
//---
if((has_bs | has_qt) == 0) // Caso comun. .. ninguno de los dos.. continuamos..
{
m_pos += 8;
if((m_pos + 7) >= m_len) // Ultimas 8 posicinoes son " " asi que seria invalido ya..
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_STRING_NOT_CLOSED;
return false;
}
continue;
}
//---
if(has_bs == 0) // Si not iene bs (pero confirmamos que no es 0)
// Entonces no tirne bs pero si qt salimos de una..
{
const ulong flag_real = TSNTABLES_SWAR_64_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
//---
m_pos += TSNTABLES_SWAR_64_GET_BYTE(flag_real);
m_pila_v[m_pila_v_s] = (long)start | long(m_pos - start) << 32;
m_pila_v_t[m_pila_v_s++] = DOMPATHV_TYPE_STR;
//---
m_pos++; // Luego del "
break;
}
//--- Hay bs si o si pero tambien puede haber "
const uchar compacted_bs = TSNTABLES_COMPACT_UL(has_bs);
// Aislamos los bits donde empeizan las rachas de \
const uchar starts = compacted_bs & ~(compacted_bs << 1);
// sumas especiifca para impar
const ushort sum_impar_wide = (ushort)compacted_bs + ushort(starts & TSNTABLES_MASK_IMPARES);
// Obtenemos finales de ambos...
const uchar end_par = (compacted_bs + (starts & TSNTABLES_MASK_PARES)) & ~compacted_bs;
const uchar end_impar = uchar(sum_impar_wide & 0xFF) & ~compacted_bs;
// Ahora ya sabemos donde esta los finaes impares..
const uchar end_final = (end_impar & TSNTABLES_MASK_PARES) | (end_par & TSNTABLES_MASK_IMPARES);
const uchar compacted_qt = TSNTABLES_COMPACT_UL(has_qt);
const uchar qt_final = compacted_qt & ~end_final;
//Print("nada");
//---
if(qt_final != 0) // Hay un qt real de cierre
{
// Avanzamos y cerramos..
m_pos += g_table_i8[qt_final];
m_pila_v[m_pila_v_s] = (long)start | long(m_pos - start) << 32;
m_pila_v_t[m_pila_v_s++] = DOMPATHV_TYPE_STR;
//----
m_pos++; // Luego del "
break;
}
else
{
m_pos += 8;
// Print(CharToString(m_raw[m_pos]));
if((sum_impar_wide & 0x100) != 0) // Overflow el ultimo char es \ y el siguiente escapa
{
//Print("siuu");
m_pos++; // Uno mas.. luego del currend
}
// No hay ... o es escapado en caso exista
if((m_pos + 7) >= m_len) // Ultimas 8 posicinoes son " " asi que seria invalido ya..
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_STRING_NOT_CLOSED;
return false;
}
}
}
//---
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
//---
case ASM_PARSER_TOK_S_STRING:
{
const int start = ++m_pos;
do
{
const uchar c = m_raw[m_pos];
//---
if(c == '\\')
{
m_pos += 2;
continue;
}
if(c == '"')
{
// STRING 1 slot: [tipo(4)|len(28low)|start(32high)]
m_pila_v[m_pila_v_s] = (long)start | long(m_pos - start) << 32;
m_pila_v_t[m_pila_v_s++] = DOMPATHV_TYPE_STR;
// curr_end = INT_MAX;
m_pos++;
break;
}
//---
m_pos++;
}
while(m_pos < m_len);
//---
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
case ASM_PARSER_TOK_EQ:
{
// Ahora mismo en =
m_pos++;
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
//-- Hash de un jump ''
case ASM_PARSER_TOK_STR_HASH:
{
// JUMP Hash "hola"
ulong jump_hash = 14695981039346656037ULL;
const uchar cierre = m_raw[m_pos++]; // luego del "
uchar _c = m_raw[m_pos];
//---
while(true)
{
//---
jump_hash ^= _c;
jump_hash *= 1099511628211ULL;
//---
m_pos++;
if(m_pos >= m_len)
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_STR_HASH_NOT_CLOSED;
return false;
}
//---
_c = m_raw[m_pos];
if(_c == cierre)
break;
}
//---
m_pila_v[m_pila_v_s] = (long)jump_hash;
m_pila_v_t[m_pila_v_s++] = TSN_DOMPATH_ASMPARSE_TYPE_HASH;
//---
m_pos++; // luego
//---
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
case ASM_PARSER_TOK_PARSE_KEY_HASH:
{
//---
m_pos += 2; // luego del K, ahjora mismo en "
//---
ulong hash = 14695981039346656037ULL;
#ifndef TSN_DOMPATH_ASMPARSE_HABILITE_ESCAPE_KEYS
do
{
const uchar c = m_raw[m_pos];
//---
if(c == '\\')
{
hash ^= (ulong)'\\';
hash *= 1099511628211ULL;
m_pos++;
hash ^= (ulong)m_raw[m_pos++];
hash *= 1099511628211ULL;
continue;
}
if(c == '"')
{
// STRING 1 slot: [tipo(4)|len(28low)|start(32high)]
m_pila_v[m_pila_v_s] = (long)hash;
m_pila_v_t[m_pila_v_s++] = TSN_DOMPATH_ASMPARSE_TYPE_HASH;
// curr_end = INT_MAX;
m_pos++;
break;
}
//---
hash ^= (ulong)c;
hash *= 1099511628211ULL;
//---
m_pos++;
}
while(m_pos < m_len);
#else // TSN_DOMPATH_ASMPARSE_HABILITE_ESCAPE_KEYS
// Place holder
#endif // TSN_DOMPATH_ASMPARSE_HABILITE_ESCAPE_KEYS
//---
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
break;
}
case ASM_PARSER_TOK_COMMENT:
{
//---
m_pos++; // luego de su valor
//--- Swar para buscar el \n
while(true)
{
const ulong chunk = (ulong)m_raw[m_pos]
| (ulong)m_raw[m_pos + 1] << 8
| (ulong)m_raw[m_pos + 2] << 16
| (ulong)m_raw[m_pos + 3] << 24
| (ulong)m_raw[m_pos + 4] << 32
| (ulong)m_raw[m_pos + 5] << 40
| (ulong)m_raw[m_pos + 6] << 48
| (ulong)m_raw[m_pos + 7] << 56;
//---
const ulong x = chunk ^ TSNTABLES_SWAR_MASK_NEW_LINE;
const ulong has_x = TSNTABLES_SWAR_HAS(x);
//---
if(has_x == 0)
{
m_pos += 8;
if(m_pos + 7 >= m_len)
{
// Chekeamos en la pila si hay algo...
if(m_p_f != 0)
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_COMENTARIO_NO_CERRO_Y_AUN_QUEDA_ALGO;
return false;
}
// Sale completo
return true;
}
continue;
}
//---
const ulong flag_real = TSNTABLES_SWAR_64_DEJAR_SOLO_MINUS_SIG_BYTE(has_x);
m_pos += TSNTABLES_SWAR_64_GET_BYTE(flag_real); // ya en \n
m_pos++; // siguiente
//---
break;
}
//--- Siguiente.
if(m_p_f == 0)
{
// Nada no estamos asi que buscamos con normalidad tokens
TSN_DOMPATH_ASMPARSER_NEXT_TOKS
}
else
{
// Si no es 0 es pro qeu etamos en una cadena de insturcciones asi qeu lo usamos...
while(true)
{
const uchar _c = m_raw[m_pos];
if(_c < 33)
{
m_pos++;
continue;
}
m_next = g_dompath_asm_toks[_c];
if((m_p_f & (1 << m_next)) == 0)
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_MALFORMERD_ASM;
return false;
}
break;
}
}
//---
break;
}
//---
case ASM_PARSER_TOK_PARSE_INS:
{
//--- Key it..
ulong key_hash = 14695981039346656037ULL;
do
{
key_hash ^= m_raw[m_pos];
key_hash *= 1099511628211ULL;
m_pos++;
}
while(m_raw[m_pos] > 32);
//---
m_pos++; // luego
//--- Obtenemos el indice
const int index = (int)DomPathExtBSPLF(key_hash);
//Print("iNDICE: ", index);
if(index == -1) // fallo
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_INVALID_INSTRUCTION;
return false;
}
// Ahora que ya tenemos el indice
m_pila_ins_t = g_dompath_op_codes[index].len;
if(m_pila_ins_t <= 1) // Solo 1 instruccion directo al ulitmo..
{
m_pila_ins[m_pila_curr] = g_dompath_op_codes[index].ops[0]; // directo
m_next = ASM_PARSER_TOK_PARSE_END; // Directo end..
}
else
{
// Mas de 1 rellenamos la pila
for(int i = 0; i < m_pila_ins_t; i++)
m_pila_ins[i] = g_dompath_op_codes[index].ops[i];
// Llenamos de instrucciones
m_pila_ins_t--; // quitamos la ultima (para que curr respete)
//--- Siguiente token
TSN_DOMPATH_INIT_BUSQEUDA_INS
}
break;
}
case ASM_PARSER_TOK_PARSE_END:
{
//---
const uint ins = m_pila_ins[m_pila_curr]; // Ultima
//Print(EnumToString((ENUM_DOMPATH_QUERY_INS_TYPE)ins));
m_bytecode[m_bytecode_s] = ins; // type en 8
switch(ins)
{
case DOMPATH_QUERY_INS_TYPE_ACCESO_KEY:
{
// v[0] = hash jump (alias @Alias) | v[1] = hash key ("key")
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[0], m_bytecode_s, ins)
m_bytecode[++m_bytecode_s] = m_pila_v[1]; // hash key completo (64 bits, slot propio)
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_ACCESO_KEY_F:
{
// 0 type | 1 = guardamos el hash completo
m_bytecode[++m_bytecode_s] = m_pila_v[0];
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_ACCESO_IDX:
{
// v[0] = index | v[1] = jump hash. Layout slot0: [type|Index=28|Jump=28]
m_bytecode[m_bytecode_s] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE;
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[1], m_bytecode_s, ins)
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_ACCESO_IDX_F:
{
// Indice luego del type
m_bytecode[m_bytecode_s++] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE;
break;
}
case DOMPATH_QUERY_INS_TYPE_INICIAR_ITERACION:
{
// Tipo permitido luego del type
m_bytecode[m_bytecode_s++] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE;
break;
}
case DOMPATH_QUERY_INS_TYPE_ITER_ASSING:
{
// v[0] = jump hash. Layout: [type|JumpCuandoTermina=28]
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[0], m_bytecode_s, ins)
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_EXIST:
{
// v[0] = jump hash | v[1] = hash key completo (64 bits, slot propio)
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[0], m_bytecode_s, ins)
m_bytecode[++m_bytecode_s] = m_pila_v[1];
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_SAVE:
case DOMPATH_QUERY_INS_TYPE_SAVE_NO_RESET:
{
// v[0] = indice de registro | v[1] = jump hash. Layout: [type|IndexRegistro=28|JumpFailed=28]
m_bytecode[m_bytecode_s] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE;
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[1], m_bytecode_s, ins)
m_bytecode_s++;
break;
}
//--- math: v[0]=B, v[1]=C, v[2]=A(destino), v[3]=jump
// Layout: slot0=[type|B=28|C=28] slot1=[A=28|JumpFailed=28]
case DOMPATH_QUERY_INS_TYPE_M_MUL:
case DOMPATH_QUERY_INS_TYPE_M_RES:
case DOMPATH_QUERY_INS_TYPE_M_DIV:
case DOMPATH_QUERY_INS_TYPE_M_SUM:
case DOMPATH_QUERY_INS_TYPE_M_MOD:
case DOMPATH_QUERY_INS_TYPE_M_BIT_OR:
case DOMPATH_QUERY_INS_TYPE_M_BIT_AND:
case DOMPATH_QUERY_INS_TYPE_M_BIT_XOR:
case DOMPATH_QUERY_INS_TYPE_M_BIT_DEZ_IZQ:
case DOMPATH_QUERY_INS_TYPE_M_BIT_DEZ_DRC:
{
m_bytecode[m_bytecode_s] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE; // B
m_bytecode[m_bytecode_s] |= m_pila_v[1] << TSN_DOMPATH_INS_MATH_BIT_START_REG_2; // C
const int slot2 = ++m_bytecode_s;
m_bytecode[slot2] = m_pila_v[2]; // A (destino), bits bajos
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[3], slot2, ins)
m_bytecode_s++;
break;
}
// unary: v[0]=B, v[1]=jump, v[2]=A(destino)
// Layout: slot0=[type|B=28|Jump=28] slot1=[A=28]
case DOMPATH_QUERY_INS_TYPE_M_BIT_NOT:
case DOMPATH_QUERY_INS_TYPE_M_UNARY_NOT:
{
m_bytecode[m_bytecode_s] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE; // B
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[1], m_bytecode_s, ins)
m_bytecode[++m_bytecode_s] = m_pila_v[2]; // A (destino)
m_bytecode_s++;
break;
}
// cmp: v[0]=B, v[1]=C, v[2]=esperado(bool), v[3]=jump
// Layout: slot0=[type|B=28|C=28] slot1=[esperado=1|JumpFailed=28]
case DOMPATH_QUERY_INS_TYPE_COMPARE_EQ:
case DOMPATH_QUERY_INS_TYPE_COMPARE_MENOR:
case DOMPATH_QUERY_INS_TYPE_COMPARE_MENOR_EQ:
{
m_bytecode[m_bytecode_s] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE; // B
m_bytecode[m_bytecode_s] |= m_pila_v[1] << TSN_DOMPATH_INS_MATH_BIT_START_REG_2; // C
const int slot2 = ++m_bytecode_s;
m_bytecode[slot2] = m_pila_v[2] & TSN_DOMPATH_BIT_INS_MASK_CMP; // esperado (bit 0)
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[3], slot2, ins)
m_bytecode_s++;
break;
}
// is: v[0]=k(reg), v[1]=jump, v[2]=esperado
// Layout: slot0=[type|RegistroIndex=28|JumpFailid=28] slot1=[1=Esperado]
case DOMPATH_QUERY_INS_TYPE_COMPARE_IS:
{
m_bytecode[m_bytecode_s] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE; // k
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[1], m_bytecode_s, ins)
m_bytecode[++m_bytecode_s] = m_pila_v[2]; // esperado
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_CALL:
{
// v[0]=reg destino, v[1]=nargs, v[2]=nombre funcion
m_bytecode[m_bytecode_s] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE; // reg destino
m_bytecode[m_bytecode_s] |= m_pila_v[1] << TSN_DOMPATH_BIT_INS_BIT_START_NARGS; // nargs
const int index = m_hash_func.FindByHash((ulong)m_pila_v[2]);
if(index == -1)
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_FUNCTION_NOT_EXIST;
return false;
}
m_bytecode[++m_bytecode_s] = m_hash_func.m_table[index].value;
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_RESERVE:
break; // No pide namas es del acutal solo mueve valor..
case DOMPATH_QUERY_INS_TYPE_SLICING:
{
// v[0]=jump, v[1]=start, v[2]=end, v[3]=step
// Layout: slot0=[type|Jump=28|Start=28] slot1=[End=28|Step=28]
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[0], m_bytecode_s, ins)
m_bytecode[m_bytecode_s] |= m_pila_v[1] << TSN_DOMPATH_BIT_INS_BIT_START_SLSTART; // start
const int slot2 = ++m_bytecode_s;
m_bytecode[slot2] = m_pila_v[2] & TSN_DOMPATH_BIT_INS_MASK_SLMASK; // end
m_bytecode[slot2] |= m_pila_v[3] << TSN_DOMPATH_BIT_INS_BIT_START_SLPASO; // step
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_JUMP:
{
// v[0] = jump hash (incondicional)
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[0], m_bytecode_s, ins)
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_COPY_ALL:
{
// v[0] = jump hash (si m_curr no es array)
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[0], m_bytecode_s, ins)
m_bytecode_s++;
break;
}
case DOMPATH_QUERY_INS_TYPE_APPEND:
m_bytecode_s++;
break;
case DOMPATH_QUERY_INS_TYPE_SALIDA:
{
//--- Iteramos por todos los pendientes..
for(int i = 0; i < m_pendings_hashes_s; i++)
{
int out;
if(!m_hash_jumps.TryGet(m_pendings_hashes[i].hash, out))
{
// No existe
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_INVALID_JUMP_KEY;
return false;
}
const int k = m_pendings_hashes[i].bytecode_pos;
m_bytecode[k] =
(m_bytecode[k] & m_pendings_hashes[i].mask) | // limpaimos y dejamos los bits de la mascara en 0
(long(out) << m_pendings_hashes[i].bit_start_mask); // a esos bits le damos su valor..
}
m_bytecode_s++;
return true; // Salimos directo
}
//--- Creamos un registro
case DOMPATH_QUERY_INS_TYPE_REG:
{
// toma el valor de la pila 0 y 1 para hacer su valor
// 0 siempre es integer
const int i = (int)m_pila_v[0];
m_reg[i].tt = m_pila_v_t[1];
switch(m_pila_v_t[1])
{
case DOMPATHV_TYPE_BOL:
{
m_reg[i].v.bv = m_pila_v[1] != 0;
break;
}
case DOMPATHV_TYPE_INT:
{
m_reg[i].v.iv = m_pila_v[1];
break;
}
case DOMPATHV_TYPE_FLT:
{
static BitInterpreter bit;
bit.long_value = m_pila_v[1];
m_reg[i].v.dv = bit.double_value;
break;
}
case DOMPATHV_TYPE_STR:
m_reg[i].v.ix = MakeString(int(m_pila_v[1] & 0xfffffff), int(m_pila_v[1] >> 32));
break;
default:
break;
}
//---
break;
}
default:
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_INVALID_CASE_INS;
return false;
}
//--- Reseteamos todo..
m_pila_v_s = 0;
m_pila_curr = 0;
m_p_f = 0;
//--- Buscamos mas tokens
TSN_DOMPATH_ASMPARSER_NEXT_TOKS
//---
break;
}
case ASM_PARSER_TOK_PARSE_JUMP_S:
{
m_pos++; // luego de @
ulong jump_hash = 14695981039346656037ULL;
//---
while(true)
{
//---
jump_hash ^= m_raw[m_pos];
jump_hash *= 1099511628211ULL;
m_pos++;
//---
if(m_raw[m_pos] == ':')
{
// Siguiente es espacio
if(m_raw[m_pos + 1] < 33)
{
m_pos++; // ahora en ws
break; // sale
}
else
{
// No entonces haseamos el actual.
jump_hash ^= ':';
jump_hash *= 1099511628211ULL;
m_pos++; // Siguiente.
}
}
//---
if(m_pos >= m_len)
{
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_JUMP_NOT_CLOSED;
return false;
}
}
//---
m_hash_jumps.Add(jump_hash, m_bytecode_s); // Siguiente..
//--- Buscamos mas toks
TSN_DOMPATH_ASMPARSER_NEXT_TOKS
break;
}
//--- Err
default:
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_INVALID_TOKEN;
return false;
}
}
}
//---
}
//+------------------------------------------------------------------+
#endif // BASESPARSERSLAN_SRC_QUERY_ASM_MQH
//+------------------------------------------------------------------+