ExpressEvalByLeo/Src/MathEval/StaticAst.mqh
Nique_372 68d060365e
2026-05-14 16:54:23 -05:00

733 lines
24 KiB
MQL5

//+------------------------------------------------------------------+
//| StaticAst.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372/news |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Niquel Mendoza."
#property link "https://www.mql5.com/es/users/nique_372/news"
#property strict
#ifndef EXPRESSEVALBYLEO_SRC_MATHEVAL_STATIC_AST_MQH
#define EXPRESSEVALBYLEO_SRC_MATHEVAL_STATIC_AST_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "Defines.mqh"
//---
// Este AST solo procesa operaciones estaticas (Sin valores dinamicos) @smop(10 * 29 * (10 + 20) % 30)
// Esta super optimizado para ello en cambio
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
struct pack(sizeof(int)) CMathExpresionEvalStatic
{
private:
int m_pos;
int m_size;
ENUM_MATH_EVAL_EXP_ERR_PARSE m_last_err;
int m_err_pos;
int m_para_stack;
//---
bool ParseInternalRaw(const TokenMathExp& tokens[], const int math_op, BitInterpreter &val, int& type);
//---
bool RawOp(const TokenMathExp &tokens[], const int type_op, int pos1, int pos2, BitInterpreter &bit, int &type);
bool RawOpAply(const TokenMathExp &tokens[], const int type_op, int pos2, BitInterpreter &bit, int &type);
bool RawOpSobreBits(const TokenMathExp &tokens[], const int type_op, BitInterpreter& bit, int& type, const BitInterpreter &bit2, const int type_2);
public:
CMathExpresionEvalStatic(void) {}
//~CMathExpresionEvalStatic(void) {}
//---
void CleanCache(const TokenMathExp& tokens[]);
bool ParsNoRes(const TokenMathExp &tokens[], BitInterpreter& it, int& type);
//---
__forceinline ENUM_MATH_EVAL_EXP_ERR_PARSE LastErr() const { return m_last_err; }
__forceinline int LastErrPos() const { return m_err_pos; }
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CMathExpresionEvalStatic::CleanCache(const TokenMathExp& tokens[])
{
//---
m_size = ArraySize(tokens);
m_pos = 0;
m_para_stack = 0;
m_err_pos = 0;
m_last_err = WRONG_VALUE;
//---
// ParseNoRes // 10 * 20 -
// ParseInternalRaw // 200 - 10 + 2
// ParseInternalRaw // 190 + 2 *
// ParsNoRes // 2 * 2
// ParseInternalRaw // 190 + 4
// .
// .
// 10 * 20 - 10 + 2 * 2
// 200 - 10 + 2 * 2
// 190 + 2 * 2
// 200 -
//
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CMathExpresionEvalStatic::RawOp(const TokenMathExp &tokens[], const int type_op, int pos1, int pos2, BitInterpreter &bit, int &type)
{
//---
// Se asume que pos1, pos2 son numeros
//---
const int type_number_1 = tokens[pos1].type >> AST_LOGIC_EXTRA_TYPE_START_BIT; // Tipo de numero 1
const int type_number_2 = tokens[pos2].type >> AST_LOGIC_EXTRA_TYPE_START_BIT; // Tipo de numero 2
//---
if((type_number_1 & type_number_2) == 1)
{
type = AST_LOGIC_NUMBER_INTEGER;
switch(type_op)
{
case BINARY_NODE_OP_BIT_OR:
bit.long_value = tokens[pos1].v.long_value | tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_XOR:
bit.long_value = tokens[pos1].v.long_value ^ tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_AND:
bit.long_value = tokens[pos1].v.long_value & tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_DEZPLAZAMIENTO_DRC:
bit.long_value = tokens[pos1].v.long_value >> tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_DEZPLAZAMIENTO_IZQ:
bit.long_value = tokens[pos1].v.long_value << tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_RESTA:
bit.long_value = tokens[pos1].v.long_value - tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_SUMA:
bit.long_value = tokens[pos1].v.long_value + tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_MODULO:
bit.long_value = tokens[pos1].v.long_value % tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_DIVICION:
bit.long_value = tokens[pos1].v.long_value / tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_MUL:
bit.long_value = tokens[pos1].v.long_value * tokens[pos2].v.long_value;
return true;
default:
m_last_err = MATH_EVAL_EXP_ERR_PARSE_TIPO_DE_OPERACION_MATH_DESCONOCIDA;
m_err_pos = pos2 - 1;
return false;
}
}
else
{
//---
const double left = (type_number_1 == AST_LOGIC_NUMBER_DOUBLE) ? tokens[pos1].v.double_value : (double)tokens[pos1].v.long_value;
const double right = (type_number_2 == AST_LOGIC_NUMBER_DOUBLE) ? tokens[pos2].v.double_value : (double)tokens[pos2].v.long_value;
//---
type = AST_LOGIC_NUMBER_DOUBLE;
switch(type_op)
{
case BINARY_NODE_OP_RESTA:
bit.double_value = left - right;
return true;
case BINARY_NODE_OP_SUMA:
bit.double_value = left + right;
return true;
case BINARY_NODE_OP_DIVICION:
bit.double_value = left / right;
return true;
case BINARY_NODE_OP_MUL:
bit.double_value = left * right;
return true;
default:
m_last_err = MATH_EVAL_EXP_ERR_PARSE_TIPO_DE_OPERACION_INVALIDA_PARA_DBL;
m_err_pos = pos2 - 1;
return false;
}
}
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CMathExpresionEvalStatic::RawOpAply(const TokenMathExp &tokens[], const int type_op, int pos2, BitInterpreter &bit, int &type)
{
//---
// Se asume que pos1, pos2 son numeros
//---
const int type_number_1 = type; // Tipo de numero 1
const int type_number_2 = tokens[pos2].type >> AST_LOGIC_EXTRA_TYPE_START_BIT; // Tipo de numero 2
//---
if((type_number_1 & type_number_2) == 1)
{
type = AST_LOGIC_NUMBER_INTEGER;
switch(type_op)
{
case BINARY_NODE_OP_BIT_OR:
bit.long_value |= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_XOR:
bit.long_value ^= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_AND:
bit.long_value &= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_DEZPLAZAMIENTO_DRC:
bit.long_value >>= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_BIT_DEZPLAZAMIENTO_IZQ:
bit.long_value <<= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_RESTA:
bit.long_value -= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_SUMA:
bit.long_value += tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_MODULO:
bit.long_value %= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_DIVICION:
bit.long_value /= tokens[pos2].v.long_value;
return true;
case BINARY_NODE_OP_MUL:
bit.long_value *= tokens[pos2].v.long_value;
return true;
default:
m_last_err = MATH_EVAL_EXP_ERR_PARSE_TIPO_DE_OPERACION_MATH_DESCONOCIDA;
m_err_pos = pos2 - 1;
return false;
}
}
else
{
//---
const double right = (type_number_2 == AST_LOGIC_NUMBER_DOUBLE) ? tokens[pos2].v.double_value : (double)tokens[pos2].v.long_value;
if(type == AST_LOGIC_NUMBER_INTEGER)
bit.double_value = (double)bit.long_value;
//---
type = AST_LOGIC_NUMBER_DOUBLE;
//---
switch(type_op)
{
case BINARY_NODE_OP_RESTA:
bit.double_value -= right;
return true;
case BINARY_NODE_OP_SUMA:
bit.double_value += right;
return true;
case BINARY_NODE_OP_DIVICION:
bit.double_value /= right;
return true;
case BINARY_NODE_OP_MUL:
bit.double_value *= right;
return true;
default:
m_last_err = MATH_EVAL_EXP_ERR_PARSE_TIPO_DE_OPERACION_INVALIDA_PARA_DBL;
m_err_pos = pos2 - 1;
return false;
}
}
//---
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CMathExpresionEvalStatic::RawOpSobreBits(const TokenMathExp &tokens[], const int type_op, BitInterpreter& bit, int& type, const BitInterpreter &bit2, const int type_2)
{
//--- Ambos son enteros
if((type & type_2) == 1)
{
type = AST_LOGIC_NUMBER_INTEGER;
switch(type_op)
{
case BINARY_NODE_OP_BIT_OR:
bit.long_value = bit.long_value | bit2.long_value;
return true;
case BINARY_NODE_OP_BIT_XOR:
bit.long_value = bit.long_value ^ bit2.long_value;
return true;
case BINARY_NODE_OP_BIT_AND:
bit.long_value = bit.long_value & bit2.long_value;
return true;
case BINARY_NODE_OP_BIT_DEZPLAZAMIENTO_DRC:
bit.long_value = bit.long_value >> bit2.long_value;
return true;
case BINARY_NODE_OP_BIT_DEZPLAZAMIENTO_IZQ:
bit.long_value = bit.long_value << bit2.long_value;
return true;
case BINARY_NODE_OP_RESTA:
bit.long_value = bit.long_value - bit2.long_value;
return true;
case BINARY_NODE_OP_SUMA:
bit.long_value = bit.long_value + bit2.long_value;
return true;
case BINARY_NODE_OP_MODULO:
bit.long_value = bit.long_value % bit2.long_value;
return true;
case BINARY_NODE_OP_DIVICION:
bit.long_value = bit.long_value / bit2.long_value;
return true;
case BINARY_NODE_OP_MUL:
bit.long_value = bit.long_value * bit2.long_value;
return true;
default:
m_last_err = MATH_EVAL_EXP_ERR_PARSE_TIPO_DE_OPERACION_MATH_DESCONOCIDA;
return false;
}
}
else
{
//---
const double right = (type_2 == AST_LOGIC_NUMBER_DOUBLE) ? bit2.double_value : (double)bit2.long_value;
if(type == AST_LOGIC_NUMBER_INTEGER)
bit.double_value = (double)bit.long_value;
//---
type = AST_LOGIC_NUMBER_DOUBLE;
//---
switch(type_op)
{
case BINARY_NODE_OP_RESTA:
bit.double_value -= right;
return true;
case BINARY_NODE_OP_SUMA:
bit.double_value += right;
return true;
case BINARY_NODE_OP_DIVICION:
bit.double_value /= right;
return true;
case BINARY_NODE_OP_MUL:
bit.double_value *= right;
return true;
default:
m_last_err = MATH_EVAL_EXP_ERR_PARSE_TIPO_DE_OPERACION_INVALIDA_PARA_DBL;
return false;
}
}
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CMathExpresionEvalStatic::ParsNoRes(const TokenMathExp &tokens[], BitInterpreter& it, int& type)
{
//---
// La idea con esta funcion es pase normal tal cual
//--- Extraccion
// Tipo de numero 1
int tkn_type = tokens[m_pos].type & 0xFFFF;
if(tkn_type == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_INI)
{
m_para_stack++;
m_pos++; // Le sigue un numero
//---
if((tokens[m_pos].type & 0xFFFF) != AST_TOKEN_MATH_T_VALUE_NUMBER)
{
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_VALOR;
m_err_pos = m_pos - 1; // previa a para
return false;
}
}
else
if(tkn_type != AST_TOKEN_MATH_T_VALUE_NUMBER)
{
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_VALOR;
m_err_pos = m_pos; // previa a para
return false;
}
const int pos_val_1 = m_pos++;
// NOTA: Ahora mismo solo extraemos el tipo
//---
// Check de len
// neceistmos 2 tokens mas
// [m_pos]: tipo op
// [m_pos + 1]: valor | o para ini
if(m_pos + 1 >= m_size)
{
// En este caso solo hay un valor asi que lo damos
type = tokens[pos_val_1].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
if(type == AST_LOGIC_NUMBER_INTEGER)
{
it.long_value = tokens[pos_val_1].v.long_value;
}
else
{
it.double_value = tokens[pos_val_1].v.double_value;
}
// Listo retornamos
return true;
} // Contianuamos
//---
// Tipó de op
// Aqui esta el tipo de operacion matematica
tkn_type = tokens[m_pos].type & 0xFFFF;
if(tkn_type != AST_TOKEN_MATH_T_VALUE_OPERDOR_MATEMATICO)
{
if(m_para_stack == 0)
{
// Luego de un valor siempre debe de haber un operador matematico
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_OPERADOR_MATEMATICO;
m_err_pos = m_pos;
return false;
}
else
if(tkn_type == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_END) // Para end o operador
{
m_para_stack--;
if((tkn_type = (tokens[++m_pos].type & 0xFFFF)) != AST_TOKEN_MATH_T_VALUE_OPERDOR_MATEMATICO)
{
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_OPERADOR_LUEGO_DE_PARA;
m_err_pos = m_pos - 1;
return false;
}
// Ahora mismo estamos en el operador
}
// No hay parantesis nodo abierto....
}
const int type_op_1 = tokens[m_pos++].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
//---
// Tipo de valor 2
tkn_type = tokens[m_pos].type & 0xFFFF;
if(tkn_type == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_INI)
{
//---
// En este caso lo que haremo sera parar lo que estuvimos haciendo...
type = tokens[pos_val_1].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
if(type == AST_LOGIC_NUMBER_INTEGER)
{
it.long_value = tokens[pos_val_1].v.long_value;
}
else
{
it.double_value = tokens[pos_val_1].v.double_value;
}
//---
//const int locked = m_para_stack;
BitInterpreter bit;
int bit_type;
//
if(!ParsNoRes(tokens, bit, bit_type))
return false;
//---
if(!RawOpSobreBits(tokens, type_op_1, it, type, bit, bit_type))
return false;
//Print("VALUE 1: ", (type == AST_LOGIC_NUMBER_DOUBLE ? it.double_value : it.long_value), " TYPE: ", type);
//Print("VALUE 2: ", (bit_type == AST_LOGIC_NUMBER_DOUBLE ? bit.double_value : bit.long_value), " TYPE: ", bit_type);
//---
m_para_stack--; // Restamos la idea es acabar en )
// Asi quye ahora mismo pos apunta a ello m_pos=)
if(m_pos + 2 < m_size)
{
// Necesitaremos dos espacios mas..
// Ahora misto esmtaos en = [)][Opeador][( Or Valor]
const int t = (tokens[++m_pos].type & 0xFFFF);
if(t == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_END)
{
// Para end no hay nada mas que hacer
return true;
}
else
if(t != AST_TOKEN_MATH_T_VALUE_OPERDOR_MATEMATICO)
{
// Error luego de un ) tiene que haber un operador matematico (no un numoero valor)
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_OPERADOR_LUEGO_DE_PARA;
m_err_pos = m_pos - 1;
return false;
}
// Continuamos el parseo agregando al valor actual
// pos++ para el siguiente valor seira [( or valor]
return ParseInternalRaw(tokens, (tokens[m_pos++].type >> AST_LOGIC_EXTRA_TYPE_START_BIT), it, type);
}
else
{
return true;
}
//---
}
else
if(tkn_type != AST_TOKEN_MATH_T_VALUE_NUMBER)
{
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_VALOR;
m_err_pos = m_pos; // previa a para
return false;
}
const int pos_val_2 = m_pos++; // Valores [Raw | Variable | Funcion Build-in | Funcion Custom]
//---
// Operador 2... este es opcional en caso exista haremos recursion
// 1. Ero comprobaremos si hay espacio para el token actual
// neceistamos dos tokens
// [op][val] (Dado que si hay un op si o si tinee uqe haber un val o parentesis)
bool is_closed = false;
if(m_pos + 1 >= m_size || (is_closed = ((tokens[m_pos].type & 0xFFFF) == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_END)))
{
//if(is_closed)
// m_para_stack--;
// No hay espacio, solo tenemos V X V
// Ahora la idea aqui seria calcular el resultado
return RawOp(tokens, type_op_1, pos_val_1, pos_val_2, it, type);
}
//--- Extraemos op2
tkn_type = tokens[m_pos].type & 0xFFFF;
if(tkn_type != AST_TOKEN_MATH_T_VALUE_OPERDOR_MATEMATICO)
{
// Luego de un valor siempre debe de haber un operador matematico
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_OPERADOR_MATEMATICO;
m_err_pos = m_pos;
return false;
}
const int type_op_2 = tokens[m_pos++].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
// m_pos = apunta ahora mismo al siguiente valor o () o ~
//--- En caso haya otro operador +\* etc..
// La idea sera ver cual es mas improtante el op1 uno actual?¿ o el otro
if(type_op_2 > type_op_1)
{
//---
// El operador siguiente 2 es mas impornate que el actual... enotnces lo que haremos
// Sera reducir primermente nuestor puntero de lectura para que apunte al valor 2
// [Valor][Op1][Valor2][Op2]
//--- Asignamos un valor
type = tokens[pos_val_1].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
if(type == AST_LOGIC_NUMBER_INTEGER)
{
it.long_value = tokens[pos_val_1].v.long_value;
}
else
{
it.double_value = tokens[pos_val_1].v.double_value;
}
//---
//Print("VALUE 1: ", (type == AST_LOGIC_NUMBER_DOUBLE ? it.double_value : it.long_value), " TYPE: ", type);
//--- Continuamos con op2
BitInterpreter bit;
int bit_type = tokens[pos_val_2].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
if(bit_type == AST_LOGIC_NUMBER_INTEGER)
{
bit.long_value = tokens[pos_val_2].v.long_value;
}
else
{
bit.double_value = tokens[pos_val_2].v.double_value;
}
if(!ParseInternalRaw(tokens, type_op_2, bit, bit_type))
return false;
//Print("VALUE 2: ", (bit_type == AST_LOGIC_NUMBER_DOUBLE ? bit.double_value : bit.long_value), " TYPE: ", bit_type);
//---
// Print("OP2: " , type_op_1);
//---
// Junsta ambos bits y reotrn true
return RawOpSobreBits(tokens, type_op_1, it, type, bit, bit_type);
}
else
{
// En este caso No lo es asi que aprovecharemos en dar valor a nuesto it actual
if(!RawOp(tokens, type_op_1, pos_val_1, pos_val_2, it, type))
return false;
// Luego continuareoms
return ParseInternalRaw(tokens, type_op_2, it, type);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// 200 - 10 + 2 * 2
// 190 + 2 * 2.0
bool CMathExpresionEvalStatic::ParseInternalRaw(const TokenMathExp& tokens[], const int math_op, BitInterpreter &val, int& type)
{
//---
// Ahora mismo nos ubicamos en la posicion de valor (Valor | () | ~)
//--- Valor
int tkn_type = tokens[m_pos].type & 0xFFFF;
if(tkn_type == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_INI)
{
//---
//const int locked = m_para_stack;
BitInterpreter bit;
int bit_type;
// aumenta stak
if(!ParsNoRes(tokens, bit, bit_type))
return false;
//---
if(!RawOpSobreBits(tokens, math_op, val, type, bit, bit_type))
return false;
//---
m_para_stack--; // Restamos la idea es acabar en )
// Asi quye ahora mismo pos apunta a ello m_pos=)
if(m_pos + 2 < m_size)
{
// Necesitaremos dos espacios mas..
// Ahora misto esmtaos en = [)][Opeador][( Or Valor]
const int t = (tokens[++m_pos].type & 0xFFFF);
if(t == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_END)
{
// Para end no hay nada mas que hacer
return true;
}
else
if(t != AST_TOKEN_MATH_T_VALUE_OPERDOR_MATEMATICO)
{
// Error luego de un ) tiene que haber un operador matematico (no un numoero valor)
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_OPERADOR_LUEGO_DE_PARA;
m_err_pos = m_pos - 1;
return false;
}
// Continuamos el parseo agregando al valor actual
// pos++ para el siguiente valor seira [( or valor]
return ParseInternalRaw(tokens, (tokens[m_pos++].type >> AST_LOGIC_EXTRA_TYPE_START_BIT), val, type);
}
else
{
return true;
}
}
else
if(tkn_type != AST_TOKEN_MATH_T_VALUE_NUMBER)
{
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_VALOR;
m_err_pos = m_pos; // previa a para
return false;
}
const int pos_val_2 = m_pos++; // Valores [Raw | Variable | Funcion Build-in | Funcion Custom]
//---
// Operador 2... este es opcional en caso exista haremos recursion
// 1. Ero comprobaremos si hay espacio para el token actual
// neceistamos dos tokens
// [op][val] (Dado que si hay un op si o si tinee uqe haber un val o parentesis)
bool is_closed = false;
if(m_pos + 1 >= m_size || (is_closed = ((tokens[m_pos].type & 0xFFFF) == AST_TOKEN_MATH_T_VALUE_OPERDOR_PARA_END)))
{
// if(is_closed)
// m_para_stack--;
// No hay espacio, solo tenemos V X V
// Ahora la idea aqui seria calcular el resultado
return RawOpAply(tokens, math_op, pos_val_2, val, type);
}
//--- Extraemos op2
tkn_type = tokens[m_pos].type & 0xFFFF;
if(tkn_type != AST_TOKEN_MATH_T_VALUE_OPERDOR_MATEMATICO)
{
// Luego de un valor siempre debe de haber un operador matematico
m_last_err = MATH_EVAL_EXP_ERR_PARSE_SE_ESPERABA_UN_OPERADOR_MATEMATICO;
m_err_pos = m_pos;
return false;
}
const int type_op_2 = tokens[m_pos++].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
// m_pos = apunta ahora mismo al siguiente valor o () o ~
//--- En caso haya otro operador +\* etc..
// La idea sera ver cual es mas improtante el op1 uno actual?¿ o el otro
if(type_op_2 > math_op)
{
// El operador siguiente 2 es mas impornate que el actual... enotnces lo que haremos
// Sera reducir primermente nuestor puntero de lectura para que apunte al valor 2
// m_pos -= 2; // 2 espacios [Valor2][Op2][AHORA MISMO APUNTAMOS AQUI]
// Luego
BitInterpreter bit;
int bit_type = tokens[pos_val_2].type >> AST_LOGIC_EXTRA_TYPE_START_BIT;
if(bit_type == AST_LOGIC_NUMBER_INTEGER)
{
bit.long_value = tokens[pos_val_2].v.long_value;
}
else
{
bit.double_value = tokens[pos_val_2].v.double_value;
}
if(!ParseInternalRaw(tokens, type_op_2, bit, bit_type))
return false;
//---
// Junsta ambos bits y reotrn true
return RawOpSobreBits(tokens, math_op, val, type, bit, bit_type);
}
else
{
//--- Revisamos si aun hay tokens
if(!RawOpAply(tokens, math_op, pos_val_2, val, type))
{
// No hay espacio, solo tenemos V X V
// Ahora la idea aqui seria calcular el resultado
return false;
}
return ParseInternalRaw(tokens, type_op_2, val, type); // Continuamos
}
}
//+------------------------------------------------------------------+
#endif // EXPRESSEVALBYLEO_SRC_MATHEVAL_STATIC_AST_MQH