Created
June 3, 2014 04:54
-
-
Save Inviz/fe26de5757f518d4cd4b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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