161 lines
7.5 KiB
C++
161 lines
7.5 KiB
C++
//+------------------------------------------------------------------+
| |
//| Parser.hpp |
| |
//| Copyright 2026, Niquel Mendoza. |
| |
//| https://www.mql5.com/ |
| |
//+------------------------------------------------------------------+
| |
| |
//+------------------------------------------------------------------+
| |
//| Pre-Defines |
| |
//+------------------------------------------------------------------+
| |
#pragma once
| |
#define TSNPARSERIN_CPP_DLL
| |
#define TSN_TARGET_AVX2
| |
| |
//+------------------------------------------------------------------+
| |
//| Includes |
| |
//+------------------------------------------------------------------+
| |
//--- Tipos estilo mql5 (antes de los includes de la lib)
| |
#include <cstdint>
| |
#include <climits>
| |
using ulong = uint64_t;
| |
using uint = uint32_t;
| |
using uchar = uint8_t;
| |
using ushort = uint16_t;
| |
| |
//--- Includes extra
| |
#include "..\\..\\..\\BasesParserSLan\\Src\\BaseClass\\Def.mqh"
| |
#include "..\\..\\..\\BasesParserSLan\\Src\\Utils\\Number.mqh"
| |
#include "..\\JsonCore\\JsonDefines.mqh"
| |
#include <cstdio>
| |
#include <cstring>
| |
| |
//--- Definiciones base
| |
#if defined(TSN_TARGET_AVX512)
| |
#include <immintrin.h>
| |
// kernel con __m512i, _mm512_*, 1 carga de 64 bytes
| |
| |
#elif defined(TSN_TARGET_AVX2)
| |
#include <immintrin.h>
| |
// kernel con __m256i, _mm256_*, 2 cargas de 32 bytes (lo que ya armamos)
| |
| |
#elif defined(TSN_TARGET_SSE42)
| |
#include <immintrin.h>
| |
// kernel con __m128i, _mm_*, 4 cargas de 16 bytes
| |
| |
#else
| |
#error "Debes definir TSN_TARGET_AVX512, TSN_TARGET_AVX2 o TSN_TARGET_SSE42"
| |
#endif
| |
| |
#include <cstdarg>
| |
| |
//--- mascaras
| |
#define TSNTABLES_MASK_IMPARES_F (0xAAAAAAAAAAAAAAAA)
| |
#define TSNTABLES_MASK_PARES_F (0x5555555555555555)
| |
| |
//+------------------------------------------------------------------+
| |
//| Macros |
| |
//+------------------------------------------------------------------+
| |
//---
| |
#define TSN_JSON_AUMENT curr_count++;
| |
| |
//--- finish basico
| |
#define TSN_JSON_FINISH_B \
| |
*out_cinta_pos = m_cinta_pos; \
| |
*out_pos = m_pos;
| |
| |
//--- Escribir las salidas basicas + (aqui macro ud especifica el ultimo error) (util para retruan false)
| |
#define TSN_JSON_ON_FINISH_WOUT(ERR) \
| |
*out_last_err = (ERR); \
| |
TSN_JSON_FINISH_B
| |
| |
//--- nota: esta funcion uncaite setea el error y redirige al punto comun (defualt)
| |
#define TSN_JSON_FAIL(ERR) \
| |
*out_last_err = (ERR); \
| |
goto json_err;
| |
| |
//--- make string (numeros que ya no se pueden representar bien)
| |
#define JSONPARSERBYLEO_NUM_MAKE_STRING \
| |
m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING \
| |
| uint64_t(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_STR) \
| |
| uint64_t(start) << TSN_SBL_BIT_STR_START;
| |
| |
//--- clave: start = inicio (luego del "), sp apunta al " de cierre
| |
#define TSN_JSON_PARSE_KEY \
| |
m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY \
| |
| uint64_t(m_index[sp] - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_KEY) \
| |
| uint64_t(start) << TSN_SBL_BIT_STR_START; \
| |
m_cinta_pos++; /* slot del hash (se llena en el JIT) */ \
| |
m_pos = m_index[++sp]; \
| |
sp++; /*Ahora mismo apunta al siguiente*/ \
| |
if(m_raw[m_pos++] != ':') \
| |
{ \
| |
TSN_JSON_FAIL(TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS) \
| |
}
| |
| |
//--- Se usa solo luego de un cor ini aqui peuden ir " [ { t\f\n (1-9\-) ]
| |
#define TSN_JSON_NEXT_COR_INI \
| |
{ \
| |
uchar _c = m_raw[m_pos]; \
| |
while(_c < 33) \
| |
_c = m_raw[++m_pos]; \
| |
m_next = g_table_json_tokens[_c]; \
| |
if(((1 << m_next) & TSN_JSON_F_VAL_COR) == 0) \
| |
{ \
| |
TSN_JSON_FAIL(TSN_JSON_ERR_MALFORDMED_JSON_AFTER_COR_INI) \
| |
} \
| |
}
| |
| |
//--- Luego de una coma en array \ luego de una key (el valor)
| |
// Luego de una , y KEY siempre siempre valor
| |
#define TSN_JSON_NEXT_VALUE_COMM_KEY \
| |
{ \
| |
uchar _c = m_raw[m_pos]; \
| |
while(_c < 33) \
| |
_c = m_raw[++m_pos]; \
| |
m_next = g_table_json_tokens[_c]; \
| |
if(((1 << m_next) & TSN_JSON_F_ALL_I_VAL) == 0) \
| |
{ \
| |
TSN_JSON_FAIL(TSN_JSON_ERR_MALFORDMED_JSON_FIND_VAL) \
| |
} \
| |
}
| |
| |
//--- Luego de un valor (solo estructurales)
| |
// Salta a json_after_value (en el bucle principal): ahi se mira directo el caracter
| |
// (',' o el cierre esperado) sin pasar por tabla\flags\switch.
| |
// Ahora mismo solo mira (no suma sp como tal), eso lo hace cada estrucutral.. en su case
| |
#define JSONPARSERBYLEO_GOTO_AFTERVALUE goto json_after_value;
| |
| |
//--- Cierre esperado segun el tipo del padre (T: 0=arr, 1=obj)
| |
// ']' = 93 y '}' = 125 = ']' + 32
| |
#define TSN_JSON_MAKE_CLOSER(T) uchar(']' + ((T) << 5))
| |
| |
//--- Para hacer un compare con un literal
| |
#define JSONPARSERBYLEO_CHEK_LITERAL(MACRO, ERR) \
| |
uint value; \
| |
std::memcpy(&value, m_raw + m_pos, sizeof(value)); \
| |
if(value != MACRO) \
| |
{ \
| |
TSN_JSON_FAIL(ERR) \
| |
}
| |
| |
//---
| |
#define TSN_JSON_IN_BEAK goto json_switch_start;
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
extern "C" __declspec(dllexport)
| |
// array ya allocado tambein raw solo hace falta rellenar
| |
bool __stdcall JsonParserResolve(
| |
const uint8_t* __restrict m_raw, // datos de entrada
| |
uint64_t* __restrict m_cinta, // cinta de datos
| |
int* __restrict m_index, // array de indices structurales
| |
const int len, // tamaño de raw
| |
const uint64_t jit_enabled, // valor del 2do slot de los objetos (JIT habilitado o no)
| |
| |
//--- salida
| |
int* __restrict out_last_err, // ultimo err
| |
int* __restrict out_cinta_pos, // posicion actul en la cinta
| |
int* __restrict out_pos // ultima posicion en la lecutra de raw
| |
); // retorna true en caso de exito, false de lo contrario..
| |
//+------------------------------------------------------------------+
|