Created
November 15, 2013 15:55
-
-
Save wellcaffeinated/7486625 to your computer and use it in GitHub Desktop.
Complex expression parser (uses scratchpad.js)
This file contains hidden or 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
!function(){ | |
var orderOfOps = ['+', '-', '*', '/']; | |
var rules = { | |
'+' : 'add', | |
'-' : 'subtract', | |
'*' : 'multiply', | |
'/' : 'divide' | |
}; | |
function trim( str ){ | |
return str.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' '); | |
} | |
var getSubs = function( expr ){ | |
var start = 0; | |
var level = 0; | |
var parts = []; | |
var count = 0; | |
var ch; | |
if (!expr) { | |
return { | |
parts: parts, | |
expr: expr | |
}; | |
} | |
for ( var i = 0, l = expr.length; i < l; i++ ){ | |
ch = expr[ i ]; | |
if ( ch === '(' ){ | |
level++; | |
if ( level === 1 ){ | |
start = i; | |
} | |
} else if ( ch === ')' ){ | |
level--; | |
if ( level === 0 ){ | |
count = parts.push( expr.substring( start + 1, i ) ) - 1; | |
expr = expr.slice( 0, start ) + '@' + count + '@' + expr.slice( i + 1 ); | |
i -= l - expr.length; | |
l = expr.length; | |
} | |
} | |
} | |
return { | |
parts: parts, | |
expr: expr | |
}; | |
}; | |
var parse = function( expr ){ | |
var idx, op, fn; | |
var left, right; | |
var subs; | |
expr = trim( expr ); | |
if (!expr){ | |
return '0'; | |
} | |
subs = getSubs( expr ); | |
if ( subs.parts.length ){ | |
return parse(subs.expr).replace(/@([0-9]+)@/g, function( str, n ){ | |
n = n|0; | |
return parse( subs.parts[ n ] ); | |
}); | |
} | |
for ( var ii = 0, l = orderOfOps.length; ii < l; ii++ ){ | |
op = orderOfOps[ ii ]; | |
fn = rules[ op ]; | |
idx = expr.indexOf( op ); | |
if ( idx > -1 ){ | |
left = expr.substr(0, idx); | |
right = expr.substr(idx + 1); | |
return 'scratch.Complex().fromRect(0,0).add(' + parse(left) + ').' + fn + '(' + parse(right) + ')'; | |
} | |
} | |
return expr; | |
}; | |
PhaseMatch.Complex.expression = function( expr ){ | |
return PhaseMatch.Scratchpad(new Function('scratch, scope', 'with(scope) return ' + parse( expr ) + '.clone()')); | |
}; | |
}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment