import { isComparable } from '../drop/icomparable' import { isFunction } from '../util/underscore' import { isTruthy } from '../render/boolean' export const precedence = { '==': 1, '!=': 1, '>': 1, '<': 1, '>=': 1, '<=': 1, 'contains': 1, 'and': 0, 'or': 0 } export const operatorImpls: {[key: string]: (lhs: any, rhs: any) => boolean} = { '==': (l: any, r: any) => { if (isComparable(l)) return l.equals(r) if (isComparable(r)) return r.equals(l) return l === r }, '!=': (l: any, r: any) => { if (isComparable(l)) return !l.equals(r) if (isComparable(r)) return !r.equals(l) return l !== r }, '>': (l: any, r: any) => { if (isComparable(l)) return l.gt(r) if (isComparable(r)) return r.lt(l) return l > r }, '<': (l: any, r: any) => { if (isComparable(l)) return l.lt(r) if (isComparable(r)) return r.gt(l) return l < r }, '>=': (l: any, r: any) => { if (isComparable(l)) return l.geq(r) if (isComparable(r)) return r.leq(l) return l >= r }, '<=': (l: any, r: any) => { if (isComparable(l)) return l.leq(r) if (isComparable(r)) return r.geq(l) return l <= r }, 'contains': (l: any, r: any) => { return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false }, 'and': (l: any, r: any) => isTruthy(l) && isTruthy(r), 'or': (l: any, r: any) => isTruthy(l) || isTruthy(r) } const list = Object.keys(precedence) export function isOperator (token: string) { return list.includes(token) }