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
|