import type { RPGCondition, RPGVariables } from "./types"; type ConditionOperator = '==' | '!=' | '>' | '<' | '>=' | '<=' | 'null' | '~null'; type ConditionValue = string | number | boolean | null; export interface ParsedCondition { variable: string; negate: boolean; operator?: ConditionOperator; value?: ConditionValue; } export function parseCondition(s: RPGCondition): ParsedCondition { // ~variable — falsy check, nothing else allowed if (s.startsWith('~') && !s.includes(' ')) return { variable: s.slice(1), negate: true }; const spaceIdx = s.indexOf(' '); if (spaceIdx === -1) return { variable: s, negate: false }; const variable = s.slice(0, spaceIdx); const rest = s.slice(spaceIdx + 1).trim(); if (rest === 'null') return { variable, negate: false, operator: 'null' }; if (rest === '~null') return { variable, negate: false, operator: '~null' }; const opMatch = rest.match(/^(==|!=|>=|<=|>|<)\s*(.+)$/); if (!opMatch) throw new Error(`Invalid condition: "${s}"`); const [, operator, rawValue] = opMatch; let value: ConditionValue; if (rawValue === 'null') value = null; else if (rawValue === 'true') value = true; else if (rawValue === 'false') value = false; else if (!isNaN(Number(rawValue))) value = Number(rawValue); else value = rawValue.replace(/^['"]|['"]$/g, ''); return { variable, negate: false, operator: operator as ConditionOperator, value }; } export function evaluateCondition({ variable, negate, operator, value }: ParsedCondition, variables: RPGVariables): boolean { const val = variables[variable]; if (operator === 'null') return val == null; if (operator === '~null') return val != null; if (operator === undefined) return negate ? !Boolean(val) : Boolean(val); if (operator === '==') return val === value; if (operator === '!=') return val !== value; if (typeof val !== 'number' || typeof value !== 'number') return false; if (operator === '<') return val < value; if (operator === '>') return val > value; if (operator === '<=') return val <= value; if (operator === '>=') return val >= value; return false; } export function evaluateConditions(conditions: RPGCondition[], variables: RPGVariables): boolean { return conditions.every(c => evaluateCondition(parseCondition(c), variables)); }