@@ 15,7 15,7 @@ function checkMatch (data, match, refs=[]) {
name: match.value, value: data
}]) }
} else if (match.type === OBJ) {
- if (typeof data !== 'object') {
+ if (!data || typeof data !== 'object') {
return false
}
return Object.keys(match.value).reduce((r, key) => {
@@ 72,20 72,24 @@ function handleOp(result, refs, defs) {
sub: (a, b) => a - b,
mul: (a, b) => a * b,
div: (a, b) => a / b,
+ // TODO: check equality by value, not by reference
+ eq: (a, b) => a === b,
+ gt: (a, b) => a > b,
+ lt: (a, b) => a < b,
+ gte: (a, b) => a >= b,
+ lte: (a, b) => a <= b,
+ and: (a, b) => a && b,
+ or: (a, b) => a || b,
}[result.op]
- const id = {
- add: 0, sub: 0, mul: 1, div: 1
- }
if (!func) {
throw new Error(`Operation not recognized: ${result.op}`)
}
- return result.operands.map(
- operand => buildResult(operand, refs, defs)
- ).reduce((r, v) => {
- return r.flatMap(result => v.flatMap(
- value => func(value, result)
- ))
- }, [id[result.op]])
+ const allOperands = buildResult(result.operands, refs, defs)
+ const val = allOperands.flatMap(([a, ...rest]) => {
+ // This doesn't make sense to reduce for many operations, oops
+ return rest.reduce(func, a)
+ })
+ return val
}
function buildResult (result, refs, defs) {
@@ 151,6 155,14 @@ function handlePipe (data, pipe, definitions) {
if (!match.matched) {
return []
}
+ if (pipe.condition) {
+ const condition = buildResult(pipe.condition, match.refs, definitions)
+ // Just check if there is any returned scenario which is strictly true
+ // Sidestep js truthy weirdness
+ if (!condition.some(c => c === true)) {
+ return []
+ }
+ }
return buildResult(pipe.result, match.refs, definitions)
}
throw new Error(`Pipe type not recognized: ${pipe.type}`)
@@ 159,30 171,20 @@ function handlePipe (data, pipe, definitions) {
function getOpDef (op) {
return {
type: PATTERN,
- match: {
- type: LIST,
- value: [
- { type: REF, value: 'a' },
- { type: REF, value: 'b' },
- ]
- },
+ match: { type: REF, value: 'operands' },
result: {
type: OP,
op,
- operands: [
- { type: REF, value: 'a' },
- { type: REF, value: 'b' },
- ]
+ operands: { type: REF, value: 'operands' }
}
}
}
-const standardDefinitions = {
- add: [[getOpDef('add')]],
- sub: [[getOpDef('sub')]],
- mul: [[getOpDef('mul')]],
- div: [[getOpDef('div')]],
-}
+const standardDefinitions = [
+ 'add', 'sub', 'mul', 'div',
+ 'eq', 'gt', 'lt', 'gte',
+ 'and', 'or'
+].reduce((r, op) => ({...r, [op]: [[getOpDef(op)]]}), {})
// Run a payload through the program
function send (data, patterns, definitions) {