Ir al contenido

Expresiones — Manual mínimo de sintaxis y uso

Una página con toda la sintaxis. Si solo necesitas los ejemplos más frecuentes, la guía rápida es más corta; si necesitas la definición exacta de la sintaxis, está en la gramática.

1. Sintaxis en 10 líneas

[Importe] * [Cantidad] * 1.21              // campos de la fila: [Nombre], admite espacios
AGG(baseImponible)                         // total precalculado del report
"Cliente: " + [Nombre]                     // texto; + concatena si hay un string
[Importe] > 1000 ? "VIP" : "normal"        // condición estilo C#...
"VIP" if [Importe] > 1000 else "normal"    // ...o estilo Python (idénticas)
[Descuento] ?? 0                           // valor por defecto si está vacío
[Fecha2] == null                           // ¿está vacío? (null o None)
[Activo] and not [Bloqueado]               // and/or/not o &&/||/!
Round([Importe] * 1.21, 2)                 // funciones permitidas (ver la guía rápida)
#2026-06-10#                               // fecha literal (por eso # NO es comentario)

Reglas de oro: números con punto decimal; comparar es == (no =); un vacío (null) se propaga como en SQL (null + 5 → null; remedio: [X] ?? 0 o Coalesce).

2. ¿Sintaxis C# o Python? No se elige: es una sola gramática

No hay selector ni modo que activar. La gramática v2 es un superset: acepta las formas C# y las Python a la vez, incluso mezcladas en la misma expresión:

[Total] > 1000 and [Activo] ? "VIP" : "normal"     // and (Python) + ?: (C#) — válido
Quieres decir...Forma C#Forma Python equivalente
y / o / no&& `\\ !`and or not
condiciónc ? a : ba if c else b
vacíonullNone
distinto!=<> (estilo SQL/Python 2)

Cada técnico escribe en el estilo que conozca; el motor las compila al mismo nodo y dan exactamente el mismo resultado. Lo guardado antes de v2 sigue funcionando sin tocar nada (superset estricto; la definición almacena GrammarVersion).

En scripts (nivel 2) solo existe hoy el estilo C# (var, ;, bloques { }): es la sintaxis natural del programador de plugins y no se eliminará. Si algún día se añade un script estilo Python (indentación), convivirá con este vía GrammarVersion — se elegiría al guardar la definición, nunca con un flag global.

3. Mayúsculas y minúsculas: dos reglas distintas

  1. Nombres (campos, funciones, palabras clave): da igual cómo se escriban.
  2. Contenido de los textos al comparar: == distingue mayúsculas

4. Evaluar desde código

var engine = new ExpressionEngine();                       // singleton en DI (cachea compilados)

var env = new EvaluationEnvironment(clock: DateTime.Now)   // reloj fijado: Now() constante
    .Set("Importe", 100.50m)                               // valores del scope
    .SetAggregate("baseImponible", 1234.5m);

var compilada = engine.CompileExpression("[Importe] * 1.21", CompileOptions.Compiled);
object? valor = compilada.Evaluate(env);                   // compila 1 vez, evalúa N filas

5. Scripts (nivel 2 — automatizaciones y plugins, nunca reports)

var env = new EvaluationEnvironment(maxLevel: LanguageLevel.Script).Set("Lineas", lista);
object? r = engine.CompileScript("""
    var total = 0;
    foreach (var x in Lineas) { if (x > 10) { total = total + x; } }
    return total;
    """).Execute(env);

var, =, if/else, while, foreach (var x in L), return, bloques { }, sentencias con ;. Presupuesto de pasos automático (un bucle infinito se corta con error claro). El entorno declara el nivel: uno de report (Expression) rechaza scripts por construcción.

6. Editor: validar sin ejecutar y autocompletar

var assistant = new ExpressionAssistant(engine);
var errores = assistant.Validate(texto, env, usuario);     // parse + binding + permisos, con posición
var sugerencias = assistant.Complete("imp", env);          // símbolos + funciones + keywords