2026-07-22 16:22:12 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Asm.mqh |
|
|
|
|
|
//| Copyright 2026, Niquel Mendoza. |
|
|
|
|
|
//| https://www.mql5.com |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2026, Niquel Mendoza."
|
|
|
|
|
#property link "https://www.mql5.com"
|
|
|
|
|
#property strict
|
|
|
|
|
|
2026-07-23 08:39:26 -05:00
|
|
|
#ifndef BASESPARSERSLAN_SRC_QUERY_ASM_MQH
|
|
|
|
|
#define BASESPARSERSLAN_SRC_QUERY_ASM_MQH
|
|
|
|
|
|
2026-07-22 16:22:12 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "Parser.mqh"
|
|
|
|
|
|
2026-07-23 22:03:03 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-07-23 08:39:26 -05:00
|
|
|
namespace TSN
|
|
|
|
|
{
|
2026-07-22 16:22:12 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-07-23 08:39:26 -05:00
|
|
|
#define TSN_DOMPATH_ASMPARSE_TYPE_HASH 4
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
|
2026-07-23 08:39:26 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#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; \
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//----
|
|
|
|
|
// Luego de insutrccion busqueda base..
|
2026-07-23 08:39:26 -05:00
|
|
|
#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;\
|
|
|
|
|
}\
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//--- Lugeo de terminar una instruccion buscamos mas tokens...
|
2026-07-23 22:03:03 -05:00
|
|
|
#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;\
|
|
|
|
|
}
|
2026-07-23 12:38:08 -05:00
|
|
|
|
2026-07-23 15:58:21 -05:00
|
|
|
//---
|
|
|
|
|
#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; \
|
2026-07-24 14:20:05 -05:00
|
|
|
const ulong _temp = (ulong)HASH_VAL; \
|
2026-07-23 22:03:03 -05:00
|
|
|
if(!m_hash_jumps.TryGet(_temp, _jump_out)) \
|
2026-07-23 15:58:21 -05:00
|
|
|
{ \
|
|
|
|
|
m_pendings_hashes[m_pendings_hashes_s].bytecode_pos = (SLOT_POS); \
|
2026-07-23 22:03:03 -05:00
|
|
|
m_pendings_hashes[m_pendings_hashes_s].hash = _temp; \
|
2026-07-23 15:58:21 -05:00
|
|
|
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; \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-07-22 16:22:12 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
// ASM
|
|
|
|
|
bool CSLDomQueryCompiler::CompileAsm(void)
|
|
|
|
|
{
|
2026-07-23 12:38:08 -05:00
|
|
|
//---
|
|
|
|
|
m_pos = m_offset;
|
|
|
|
|
m_pila_curr = 0;
|
|
|
|
|
m_pila_v_s = 0;
|
|
|
|
|
m_p_f = 0;
|
2026-07-23 15:58:21 -05:00
|
|
|
m_pendings_hashes_s = 0;
|
2026-07-23 22:03:03 -05:00
|
|
|
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_NOT;
|
|
|
|
|
m_sreg_s = 0; // Se resetea.. el pool de strigns empezamos de 0
|
2026-07-24 14:20:05 -05:00
|
|
|
m_hash_jumps.Clear();
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
TSN_DOMPATH_ASMPARSER_NEXT_TOKS
|
2026-07-23 12:38:08 -05:00
|
|
|
|
2026-07-22 16:22:12 -05:00
|
|
|
//---
|
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
switch(m_next)
|
|
|
|
|
{
|
2026-07-22 20:08:38 -05:00
|
|
|
case ASM_PARSER_TOK_REGISTER: // R0
|
|
|
|
|
{
|
|
|
|
|
// Avanzamos exacto
|
2026-07-23 08:39:26 -05:00
|
|
|
m_pos += 4; // %[r][e][g][aqui]
|
2026-07-22 16:22:12 -05:00
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//--- Rellenamos la pila
|
2026-07-22 20:08:38 -05:00
|
|
|
// numero puro primero
|
2026-07-24 14:20:05 -05:00
|
|
|
m_pila_ins[0] = ASM_PARSER_TOKF_NUMBER;
|
2026-07-22 20:08:38 -05:00
|
|
|
// 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 |
|
2026-07-23 12:38:08 -05:00
|
|
|
ASM_PARSER_TOKF_FALSE | ASM_PARSER_TOKF_STR | ASM_PARSER_TOKF_S_STR;
|
2026-07-22 20:08:38 -05:00
|
|
|
// luego tambien hace el registro final
|
2026-07-24 14:20:05 -05:00
|
|
|
m_pila_ins[3] = DOMPATH_QUERY_INS_TYPE_REG;
|
|
|
|
|
m_pila_ins_t = 3;
|
2026-07-22 20:08:38 -05:00
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//--- Siguientes instrucciones
|
2026-07-23 08:39:26 -05:00
|
|
|
TSN_DOMPATH_INIT_BUSQEUDA_INS
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-24 14:20:05 -05:00
|
|
|
//---
|
2026-07-23 08:39:26 -05:00
|
|
|
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..
|
|
|
|
|
{
|
2026-07-23 22:03:03 -05:00
|
|
|
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_STRING_NOT_CLOSED;
|
2026-07-23 08:39:26 -05:00
|
|
|
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..
|
|
|
|
|
{
|
2026-07-23 22:03:03 -05:00
|
|
|
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_STRING_NOT_CLOSED;
|
2026-07-23 08:39:26 -05:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-24 14:20:05 -05:00
|
|
|
//-- 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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 08:39:26 -05:00
|
|
|
case ASM_PARSER_TOK_PARSE_KEY_HASH:
|
|
|
|
|
{
|
2026-07-24 14:20:05 -05:00
|
|
|
//---
|
|
|
|
|
m_pos += 2; // luego del K, ahjora mismo en "
|
|
|
|
|
|
|
|
|
|
//---
|
2026-07-23 08:39:26 -05:00
|
|
|
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)]
|
2026-07-23 22:03:03 -05:00
|
|
|
m_pila_v[m_pila_v_s] = (long)hash;
|
2026-07-23 08:39:26 -05:00
|
|
|
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
|
2026-07-23 12:38:08 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
TSN_DOMPATH_ASMPARSE_CHECK_VALUE
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ASM_PARSER_TOK_COMMENT:
|
|
|
|
|
{
|
2026-07-24 14:20:05 -05:00
|
|
|
//---
|
|
|
|
|
m_pos++; // luego de su valor
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//--- Swar para buscar el \n
|
2026-07-23 08:39:26 -05:00
|
|
|
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)
|
|
|
|
|
{
|
2026-07-24 14:20:05 -05:00
|
|
|
// 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;
|
2026-07-23 08:39:26 -05:00
|
|
|
}
|
|
|
|
|
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.
|
2026-07-23 12:38:08 -05:00
|
|
|
if(m_p_f == 0)
|
2026-07-23 08:39:26 -05:00
|
|
|
{
|
2026-07-23 12:38:08 -05:00
|
|
|
// 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)
|
2026-07-23 08:39:26 -05:00
|
|
|
{
|
2026-07-23 12:38:08 -05:00
|
|
|
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;
|
2026-07-23 08:39:26 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
|
2026-07-23 08:39:26 -05:00
|
|
|
//---
|
2026-07-22 16:22:12 -05:00
|
|
|
break;
|
2026-07-22 20:08:38 -05:00
|
|
|
}
|
|
|
|
|
|
2026-07-23 10:54:27 -05:00
|
|
|
//---
|
2026-07-23 08:39:26 -05:00
|
|
|
case ASM_PARSER_TOK_PARSE_INS:
|
|
|
|
|
{
|
2026-07-23 11:13:47 -05:00
|
|
|
//--- Key it..
|
2026-07-23 08:39:26 -05:00
|
|
|
ulong key_hash = 14695981039346656037ULL;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
key_hash ^= m_raw[m_pos];
|
|
|
|
|
key_hash *= 1099511628211ULL;
|
|
|
|
|
m_pos++;
|
|
|
|
|
}
|
|
|
|
|
while(m_raw[m_pos] > 32);
|
2026-07-23 11:13:47 -05:00
|
|
|
|
2026-07-24 14:20:05 -05:00
|
|
|
//---
|
|
|
|
|
m_pos++; // luego
|
|
|
|
|
|
2026-07-23 11:13:47 -05:00
|
|
|
//--- Obtenemos el indice
|
|
|
|
|
const int index = (int)DomPathExtBSPLF(key_hash);
|
2026-07-24 21:56:07 -05:00
|
|
|
//Print("iNDICE: ", index);
|
2026-07-23 11:13:47 -05:00
|
|
|
if(index == -1) // fallo
|
2026-07-23 08:39:26 -05:00
|
|
|
{
|
|
|
|
|
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_INVALID_INSTRUCTION;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ahora que ya tenemos el indice
|
2026-07-24 14:20:05 -05:00
|
|
|
m_pila_ins_t = g_dompath_op_codes[index].len;
|
|
|
|
|
if(m_pila_ins_t <= 1) // Solo 1 instruccion directo al ulitmo..
|
2026-07-23 08:39:26 -05:00
|
|
|
{
|
2026-07-24 17:26:12 -05:00
|
|
|
m_pila_ins[m_pila_curr] = g_dompath_op_codes[index].ops[0]; // directo
|
2026-07-23 12:38:08 -05:00
|
|
|
m_next = ASM_PARSER_TOK_PARSE_END; // Directo end..
|
2026-07-23 08:39:26 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-07-23 12:38:08 -05:00
|
|
|
// Mas de 1 rellenamos la pila
|
2026-07-24 14:20:05 -05:00
|
|
|
for(int i = 0; i < m_pila_ins_t; i++)
|
2026-07-23 08:39:26 -05:00
|
|
|
m_pila_ins[i] = g_dompath_op_codes[index].ops[i];
|
|
|
|
|
// Llenamos de instrucciones
|
2026-07-24 14:20:05 -05:00
|
|
|
m_pila_ins_t--; // quitamos la ultima (para que curr respete)
|
2026-07-23 08:39:26 -05:00
|
|
|
|
|
|
|
|
//--- Siguiente token
|
|
|
|
|
TSN_DOMPATH_INIT_BUSQEUDA_INS
|
|
|
|
|
}
|
2026-07-22 16:22:12 -05:00
|
|
|
break;
|
2026-07-23 08:39:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ASM_PARSER_TOK_PARSE_END:
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
const uint ins = m_pila_ins[m_pila_curr]; // Ultima
|
2026-07-24 21:56:07 -05:00
|
|
|
//Print(EnumToString((ENUM_DOMPATH_QUERY_INS_TYPE)ins));
|
2026-07-23 10:54:27 -05:00
|
|
|
m_bytecode[m_bytecode_s] = ins; // type en 8
|
2026-07-23 08:39:26 -05:00
|
|
|
switch(ins)
|
|
|
|
|
{
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_KEY:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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)
|
2026-07-23 12:38:08 -05:00
|
|
|
m_bytecode_s++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_KEY_F:
|
|
|
|
|
{
|
2026-07-23 10:54:27 -05:00
|
|
|
// 0 type | 1 = guardamos el hash completo
|
2026-07-23 15:58:21 -05:00
|
|
|
m_bytecode[++m_bytecode_s] = m_pila_v[0];
|
|
|
|
|
m_bytecode_s++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_IDX:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_ACCESO_IDX_F:
|
|
|
|
|
{
|
2026-07-23 10:54:27 -05:00
|
|
|
// Indice luego del type
|
2026-07-23 12:38:08 -05:00
|
|
|
m_bytecode[m_bytecode_s++] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_INICIAR_ITERACION:
|
|
|
|
|
{
|
2026-07-23 10:54:27 -05:00
|
|
|
// Tipo permitido luego del type
|
2026-07-23 12:38:08 -05:00
|
|
|
m_bytecode[m_bytecode_s++] |= m_pila_v[0] << TSN_DOMPATH_BIT_INS_ETYPE;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_ITER_ASSING:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_EXIST:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_SAVE:
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_SAVE_NO_RESET:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 15:58:21 -05:00
|
|
|
//--- 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]
|
2026-07-23 08:39:26 -05:00
|
|
|
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:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 15:58:21 -05:00
|
|
|
// unary: v[0]=B, v[1]=jump, v[2]=A(destino)
|
|
|
|
|
// Layout: slot0=[type|B=28|Jump=28] slot1=[A=28]
|
2026-07-23 08:39:26 -05:00
|
|
|
case DOMPATH_QUERY_INS_TYPE_M_BIT_NOT:
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_M_UNARY_NOT:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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]
|
2026-07-23 08:39:26 -05:00
|
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_EQ:
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_MENOR:
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_MENOR_EQ:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 15:58:21 -05:00
|
|
|
// is: v[0]=k(reg), v[1]=jump, v[2]=esperado
|
|
|
|
|
// Layout: slot0=[type|RegistroIndex=28|JumpFailid=28] slot1=[1=Esperado]
|
2026-07-23 08:39:26 -05:00
|
|
|
case DOMPATH_QUERY_INS_TYPE_COMPARE_IS:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_CALL:
|
|
|
|
|
{
|
2026-07-23 22:03:03 -05:00
|
|
|
// v[0]=reg destino, v[1]=nargs, v[2]=nombre funcion
|
2026-07-23 15:58:21 -05:00
|
|
|
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
|
2026-07-23 22:03:03 -05:00
|
|
|
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;
|
|
|
|
|
}
|
2026-07-24 21:56:07 -05:00
|
|
|
m_bytecode[++m_bytecode_s] = m_hash_func.m_table[index].value;
|
2026-07-23 15:58:21 -05:00
|
|
|
m_bytecode_s++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_RESERVE:
|
2026-07-23 10:54:27 -05:00
|
|
|
break; // No pide namas es del acutal solo mueve valor..
|
2026-07-23 08:39:26 -05:00
|
|
|
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_SLICING:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_JUMP:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// v[0] = jump hash (incondicional)
|
|
|
|
|
TSN_DOMPATH_ASM_RESOLVE_OR_QUEUE_JUMP(m_pila_v[0], m_bytecode_s, ins)
|
|
|
|
|
m_bytecode_s++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_COPY_ALL:
|
|
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
// 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++;
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DOMPATH_QUERY_INS_TYPE_APPEND:
|
2026-07-23 15:58:21 -05:00
|
|
|
m_bytecode_s++;
|
2026-07-23 12:38:08 -05:00
|
|
|
break;
|
|
|
|
|
|
2026-07-23 08:39:26 -05:00
|
|
|
case DOMPATH_QUERY_INS_TYPE_SALIDA:
|
2026-07-23 12:38:08 -05:00
|
|
|
{
|
2026-07-23 15:58:21 -05:00
|
|
|
//--- 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..
|
|
|
|
|
}
|
2026-07-23 12:38:08 -05:00
|
|
|
|
2026-07-23 15:58:21 -05:00
|
|
|
m_bytecode_s++;
|
2026-07-23 12:38:08 -05:00
|
|
|
return true; // Salimos directo
|
|
|
|
|
}
|
2026-07-23 10:54:27 -05:00
|
|
|
|
2026-07-24 14:20:05 -05:00
|
|
|
//--- 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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 08:39:26 -05:00
|
|
|
default:
|
|
|
|
|
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_INVALID_CASE_INS;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//--- Reseteamos todo..
|
|
|
|
|
m_pila_v_s = 0;
|
|
|
|
|
m_pila_curr = 0;
|
|
|
|
|
m_p_f = 0;
|
|
|
|
|
|
|
|
|
|
//--- Buscamos mas tokens
|
|
|
|
|
TSN_DOMPATH_ASMPARSER_NEXT_TOKS
|
2026-07-23 10:54:27 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ASM_PARSER_TOK_PARSE_JUMP_S:
|
|
|
|
|
{
|
|
|
|
|
m_pos++; // luego de @
|
2026-07-23 15:58:21 -05:00
|
|
|
ulong jump_hash = 14695981039346656037ULL;
|
2026-07-23 08:39:26 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
//---
|
2026-07-23 15:58:21 -05:00
|
|
|
jump_hash ^= m_raw[m_pos];
|
|
|
|
|
jump_hash *= 1099511628211ULL;
|
2026-07-23 08:39:26 -05:00
|
|
|
m_pos++;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(m_raw[m_pos] == ':')
|
|
|
|
|
{
|
|
|
|
|
// Siguiente es espacio
|
|
|
|
|
if(m_raw[m_pos + 1] < 33)
|
2026-07-24 14:20:05 -05:00
|
|
|
{
|
|
|
|
|
m_pos++; // ahora en ws
|
2026-07-23 08:39:26 -05:00
|
|
|
break; // sale
|
2026-07-24 14:20:05 -05:00
|
|
|
}
|
2026-07-23 08:39:26 -05:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// No entonces haseamos el actual.
|
2026-07-23 15:58:21 -05:00
|
|
|
jump_hash ^= ':';
|
|
|
|
|
jump_hash *= 1099511628211ULL;
|
2026-07-23 08:39:26 -05:00
|
|
|
m_pos++; // Siguiente.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(m_pos >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_JUMP_NOT_CLOSED;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-07-23 15:58:21 -05:00
|
|
|
m_hash_jumps.Add(jump_hash, m_bytecode_s); // Siguiente..
|
2026-07-23 12:38:08 -05:00
|
|
|
|
|
|
|
|
//--- Buscamos mas toks
|
|
|
|
|
TSN_DOMPATH_ASMPARSER_NEXT_TOKS
|
2026-07-23 08:39:26 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//--- Err
|
2026-07-23 08:39:26 -05:00
|
|
|
default:
|
|
|
|
|
m_last_err_parse = ASM_DOMPATH_PARSER_ERR_INVALID_TOKEN;
|
|
|
|
|
return false;
|
2026-07-22 16:22:12 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-23 12:38:08 -05:00
|
|
|
//---
|
2026-07-22 16:22:12 -05:00
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-07-23 08:39:26 -05:00
|
|
|
#endif // BASESPARSERSLAN_SRC_QUERY_ASM_MQH
|
|
|
|
|
//+------------------------------------------------------------------+
|