pimatic
Version:
A home automation server and framework for the Raspberry PI running on node.js
129 lines (114 loc) • 3.65 kB
text/coffeescript
###
Rules AST Builder
===========
Builds a Abstract Syntax Tree (AST) from a rule condition token sequence.
###
assert = require 'cassert'
util = require 'util'
Promise = require 'bluebird'
_ = require 'lodash'
S = require 'string'
class BoolExpression
toString: -> "#{@type.replace(' ', '')}(#{@left.toString()}, #{@right.toString()})"
class AndExpression extends BoolExpression
constructor: (, , ) ->
evaluate: (cache) ->
return .evaluate(cache).then( (val) =>
if val then .evaluate(cache) else false
)
class OrExpression extends BoolExpression
constructor: (, , ) -> #nop
evaluate: (cache) ->
return .evaluate(cache).then( (val) =>
if val then true else .evaluate(cache)
)
class PredicateExpression extends BoolExpression
constructor: () -> #nop
= "predicate"
evaluate: (cache) ->
id = .id
value = cache[id]
return (
if value? then Promise.resolve(value)
# If the trigger keyword was present then the predicate is only true of it got triggered...
else if .justTrigger is yes then Promise.resolve(false)
else .handler.getValue().then( (value) =>
# Check if the time condition is true
if .for? and value is true
return .timeAchived
else
cache[id] = value
return value
)
)
toString: -> "predicate('#{@predicate.token}')"
class BoolExpressionTreeBuilder
_nextToken: ->
if < .length
= [++]
else
= ''
build: (, ) ->
= 0
return
_buildOuterExpression: (left, inner) ->
if not inner
return
else
return left
_buildExpression: (left = null, greedy = yes, inner = false) ->
switch
when 'predicate'
predicateExpr =
return (
if greedy then
else predicateExpr
)
when 'or'
outer = new OrExpression('or', left, )
return
when 'or when'
if inner then return left
outer = new OrExpression('or when', left, )
return
when 'and'
right =
return
when 'and if'
outer = new AndExpression('and if', left, )
return
when '['
innerExpr =
assert is ']'
return (
if greedy then
else innerExpr
)
when ']', ''
return left
else
assert false
_buildPredicateExpression: ->
assert is '('
predicateIndex =
assert typeof predicateIndex is "number"
assert is ')'
predicate = [predicateIndex]
return new PredicateExpression(predicate)
module.exports = {
BoolExpression
AndExpression
OrExpression
BoolExpressionTreeBuilder
}