Skip to content

Instantly share code, notes, and snippets.

@Inviz
Created June 3, 2014 04:54
Show Gist options
  • Save Inviz/fe26de5757f518d4cd4b to your computer and use it in GitHub Desktop.
Save Inviz/fe26de5757f518d4cd4b to your computer and use it in GitHub Desktop.
Registry = require('./Registry.js')
class Evaluator extends Registry
constructor: ->
@values = {}
super()
evaluate: (op, i, context, continuation) ->
method = op[0]
func = def = @[method]
# Run macro, check if property has custom evaluator (e.g. "if")
if def
if typeof def == 'function'
op.shift()
def = def.call(@, context, op[0])
func = @[def.method]
evaluate = def.evaluate
group = def.group
# Evaluate arguments. Stops if one of the values is undefined
args = []
eager = false
for arg, i in op
if arg instanceof Array
args[i] = value = (evaluate || @evaluate).call(@, arg, i, op)
else
args[i] = arg
continue
switch typeof value
when "object", "number"
eager = value
# Argument was promised to be observable at this address
when "string"
if @[arg[0]].group != group
eager = value
# The argument depends on some other values. Wait for it.
when "undefined"
return
if eager
console.info('@' + op[0], 'Resolve promise:', eager)
#return
# Handle custom commands
unless func
args.shift()
switch typeof def
# Thread commands pass through
when "boolean"
return args
# Substitute constants
when "number", "string"
return def
# Resolve value if expression isn't lazy
when "object"
if def.valueOf != Object.valueOf
func = def.valueOf
# Concat token path in lazy arguments. Groups native selectors
if group && !eager
return @toPath(def, args[0], args[1])
# Look up method on the first argument
unless func
scope = args.shift()
if typeof scope == 'object'
func = scope && scope[method]
# Execute the function
if func
result = func.apply(scope || @, args)
else if result == undefined
throw new Error("Engine Commands broke, couldn't find method: #{method}")
absolute = @toPath(result, method)
@tree[absolute] = context
return absolute
'toPath': (command, method, path) ->
if absolute = command.selector
return absolute
relative = command.prefix
relative += method if method
relative += command.suffix if command.suffix
console.error((path || command.path || '') + relative, command, method, path)
return (path || command.path || '') + relative
continuate: (arg, i, context) ->
123
module.exports = Evaluator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment