//+------------------------------------------------------------------+ //| 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 //+------------------------------------------------------------------+