BasesParserSLan/Src/ExtraDef/Pointer/Cpiler.mqh

262 lines
7.8 KiB
MQL5

2026-10-05 17:54:12 -05:00
//+------------------------------------------------------------------+
//| Pointer.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_EXTRADEF_POINTER_CPILER_MQH
#define BASESPARSERSLAN_SRC_EXTRADEF_POINTER_CPILER_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "Def.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
struct BSFLPointerCompiler
{
public:
uchar m_raw[]; // raw
int m_pos; // posicion de lecutra curr
int m_len; // tamaño de raw
int m_offset; // offset de lecutra
int m_w; // posicion de escritura
public:
BSFLPointerCompiler();
2026-10-05 21:57:35 -05:00
//--- Asignacion
2026-10-05 17:54:12 -05:00
__forceinline void Assing(const string& str, uint cp = CP_ACP);
__forceinline void CalcLen() { m_len = ArraySize(m_raw); }
void CorrectPadding();
2026-10-05 21:57:35 -05:00
//--- Reserva
2026-10-05 17:54:12 -05:00
void CalcReserve(ulong& ins[]);
2026-10-05 21:57:35 -05:00
//--- Compilacion
ENUM_BSFL_POINTER_PARSE_RES Compile(ulong& ins[]); // metodo de bajo nivel
BSFLPointerQuery Compile(); // devuelve uno
bool Compile(BSFLPointerQuery& query); // toma uno ya existente
2026-10-05 17:54:12 -05:00
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
BSFLPointerCompiler::BSFLPointerCompiler(void)
: m_pos(0), m_len(0), m_offset(0), m_w(0)
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__forceinline void BSFLPointerCompiler::Assing(const string &str, uint cp)
{
m_len = StringToCharArray(str, m_raw, 0, WHOLE_ARRAY, cp);
2026-10-05 21:57:35 -05:00
m_len -= (m_len != -1);
2026-10-05 17:54:12 -05:00
m_offset = 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void BSFLPointerCompiler::CorrectPadding(void)
{
ArrayResize(m_raw, m_len + 2);
m_raw[m_len] = '/'; // para forzar cierre / o luego del ~(algo) se cierre bien
m_raw[m_len + 1] = '/'; // en el pero caso luego del ~(algo) neceista un char mas.. asi que usarmoes esto
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void BSFLPointerCompiler::CalcReserve(ulong &ins[])
{
// Ahora toca caluclar el len loq ue sabes es uqe si o si por cada token neeismtos dos ulongs
// enotnces "lo peorsito" /a que impliciaria un solo token "" requeria 2..
// lo cual = len
// o por jeemplo /a
const int req = m_w + m_len;
if(ArraySize(ins) < req)
ArrayResize(ins, req);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
BSFLPointerQuery BSFLPointerCompiler::Compile(void)
{
2026-10-05 21:57:35 -05:00
//---
// usuairo ya se encarga de llenra el buffer y correct padding
2026-10-05 17:54:12 -05:00
//---
ulong ins[];
CalcReserve(ins);
const ENUM_BSFL_POINTER_PARSE_RES res = Compile(ins);
if(res) // hay errores
return BSFLPointerQuery::EMPTY_QUERY;
2026-10-05 21:57:35 -05:00
//---
ArrayResize(m_raw, ArraySize(m_raw) - 2); // quitamos padding
m_len = 0; // viene de 0
m_w = 0;
2026-10-05 17:54:12 -05:00
//---
return BSFLPointerQuery(ins, m_w, m_raw);
}
2026-10-05 21:57:35 -05:00
//+------------------------------------------------------------------+
bool BSFLPointerCompiler::Compile(BSFLPointerQuery& query)
{
//---
CalcReserve(query.m_ins);
const ENUM_BSFL_POINTER_PARSE_RES res = Compile(query.m_ins);
if(res) // hay errores
return false;
//---
// size
query.m_size = m_w;
// raw
ArrayResize(m_raw, ArraySize(m_raw) - 2); // quitamos padding
m_len = ArraySize(query.m_raw);
ArraySwap(m_raw, query.m_raw);
//---
m_w = 0;
//---
return true;
}
2026-10-05 17:54:12 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// Las intrucciones de salida van de aparares
// slot 0 = numero [0-31 bits [32 bit = hash que viene es valido o no?¿]
// slot 1 = hash completo de FNV1A64
2026-10-05 21:57:35 -05:00
//---notas
// m_w no se reinica tu eres el encagaro de dalre un valor antes y luego reicniarlo de su uso
// en caso desea reusarlo... puede ponerlo en 0 por jemeplo poara uqe eimpziar a esicbri desde la proxima ahi
2026-10-05 17:54:12 -05:00
ENUM_BSFL_POINTER_PARSE_RES BSFLPointerCompiler::Compile(ulong& ins[])
{
//---
m_pos = m_offset;
//---
if(m_raw[m_pos++] != '/')
return BSFL_POINTER_PARSE_RES_ERR_QUERY_MUST_START_WITH_BR;
//---
while(m_pos < m_len)
{
uchar ch = m_raw[m_pos] ^ '0';
2026-10-05 21:57:35 -05:00
//Print(CharToString(m_raw[m_pos]));
2026-10-05 17:54:12 -05:00
ulong v;
if(ch < 10)
{
const int l = m_pos;
v = 0; // reiniciamos
//---
while(true)
{
DOMBASEUTIL_PARSE_NUM_U1(v)
if(!v) // leading zeros
{
v = INT_MAX;
break;
}
//---
DOMBASEUTIL_PARSE_NUM_UNROLLED_8(v)
STRCONV_TOV_ALG(v, ch)
if((ch = m_raw[++m_pos] ^ '0') > 9 && v < INT_MAX) // pass
break;
//---
v = INT_MAX; // error no cumple
break;
}
//--- ponemos el numero INT_MAX invalido o el valor que haya..
ins[m_w] = v;
//--- vale entonces es invalido este numero.. pongamolos al dia
// en caso sigamos.. aun.. o fallo....
// primero resolvemos esto
const int t = m_pos;
m_pos = l;
v = 14695981039346656037ULL;
ch = m_raw[m_pos];
2026-10-05 21:57:35 -05:00
// start
2026-10-05 17:54:12 -05:00
ins[m_w] |= ulong(m_pos) << BSFLPOINTER_BIT_START_H;
//---
while(m_pos < t)
{
v ^= ch;
v *= 1099511628211ULL;
2026-10-05 21:57:35 -05:00
ch = m_raw[++m_pos];
2026-10-05 17:54:12 -05:00
}
}
else
{
ins[m_w] = INT_MAX | ulong(m_pos) << BSFLPOINTER_BIT_START_H;
ch ^= '0'; // deshace
v = 14695981039346656037ULL;
}
//---
while(ch != '/')
{
2026-10-05 21:57:35 -05:00
//Print(CharToString(ch), " ", ch);
//---
m_pos++;
//---
2026-10-05 17:54:12 -05:00
if(ch == '~')
{
2026-10-05 21:57:35 -05:00
const uchar n = m_raw[m_pos++] ^ '0';
2026-10-05 17:54:12 -05:00
if(n > 1)
return BSFL_POINTER_PARSE_RES_ERR_INVALID_ESCAPE;
//---
ch = (n == 1) ? '/' : '~';
}
//---
v ^= ch;
v *= 1099511628211ULL;
2026-10-05 21:57:35 -05:00
ch = m_raw[m_pos];
2026-10-05 17:54:12 -05:00
}
//---
const ulong start = (ins[m_w] >> BSFLPOINTER_BIT_START_H);
2026-10-05 21:57:35 -05:00
//Print(CharArrayToString(m_raw, start, (m_pos - start)));
2026-10-05 17:54:12 -05:00
ins[m_w++] |= ulong(m_pos - start) << BSFLPOINTER_BIT_START_LEN;
ins[m_w++] = v;
2026-10-05 21:57:35 -05:00
//---
m_pos++; // luego del '/'
2026-10-05 17:54:12 -05:00
}
//---
return BSFL_POINTER_PARSE_RES_EXITO;
}
//--- end namespace
}
//+------------------------------------------------------------------+
#endif // BASESPARSERSLAN_SRC_EXTRADEF_POINTER_CPILER_MQH