Skift Operator 2...
Flash Nyhed!...Eller hvad der i virkeligheden er en fantastisk udvidelse af den ellers begrænsede actionScript\'s eval() funktion til noget der kan bruges som javaScript\'s eval().
Spørgsmålet omkring hvordan man kan få Flash til at evaluere en streng så som
\" 1 + 5*2\"
til en værdi = 11 har været op og vende på dette forum før. se evt. [Skift Operator] http://www.eksperten.dk/spm/103070
Dette tilsynladene simple spørgsmål kunne dog ikke besvares uden at man måtte ty til javaScript kald. Andre Flash /ActionScript forum har også haft dette emne op i deres diskusioner og igår fik man langt om læange, en færdig, velfungerende ActionScript løsning på Flash Coders (man kan tilmeldes mailinglisten her http://chattyfig.figleaf.com/ ).
Følgende .as kode er reproduceret i sin helhed her med tilladelse fra RALF BOKELBERG som har skrevet actionen.
En enkel Flash demo kan ses ved at følge linket under \'Experiments\' >> Math.eval på http://www.bokelberg.de/actionscript
eller mere direkte
http://www.bokelberg.de/actionscript/experiments/eval.html
Der har man også mulighed for at downloade den seneste version af .as filen
Håber at dette kan blive til gavn for alle Flashere på eksperten!
mvh geo
///////////////////////////////////////////////////////////////////////////////////////////////////
//implementation of Math.eval for mathematical expressions
//
//<addexpr> ::= <mulExpr> ((+|-) <mulExpr>)*
//<mulexpr> ::= <unaryExpr> ((*|/|%) <unaryExpr>)*
//<unaryExpr> ::= [+|-]<primaryExpr>
//<primaryExp> ::= <number> | ( addExpr ) | <functionId>(exprList)
//<functionId> ::= [Math.]( sin | cos | pow | sqrt | tan | atan | ...)
//<exprList> ::= [<addExpr>(,<addExpr>)*]
//<number> ::= <decNumber> | <floatNumber>
//nov. 2001 ralf bokelberg v0.01111704
//actionscript@bokelberg.de
//new versions can be found at http://www.bokelberg.de/actionscript
// Disclaimer
// THIS SOFTWARE IS PROVIDED BY RALF BOKELBERG ``AS IS\'\' AND ANY
// EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF BOKELBERG OR ITS
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
Math.eval = function(stringExpression){
//returns the calculated value of stringExpression, eg.
//trace(Math.eval(\"2+3\"));
//trace(Math.eval(\"2+(3*100)\"));
//trace(Math.eval(\"round(sin(2)+random()*1000)\"));
Math.eval.iError = 0;
Math.eval.iErrorMsg = \"\";
Math.eval.sExpr = stringExpression.toLowerCase();
Math.eval.iLen = stringExpression.length;
Math.eval.iPos = -1;
Math.eval.sTok = \"\";
Math.eval.sTokType = \"\";
Math.eval.nextToken();
if( Math.eval.addExpr()){
if(Math.eval.iPos >= Math.eval.iLen){
return Math.eval.tVal;
} else {
Math.eval.error(\"eval: too many tokens\");
}
}
return Math.eval.iErrorMsg;
}
Math.eval.error = function(msg){
if(this.iError == 0){
this.iErrorMsg = \"ERROR at \" + this.iPos + \": \" + msg;
trace(this.iErrorMsg);
this.iError = 1;
}
return false;
}
Math.eval.isFunctionIDChar = function(ch){
return (\"abcdefghijklmnopqrstuvwxyz.\").indexOf(ch) >= 0
}
Math.eval.isOperatorChar = function( ch){
return (\"+-*/%()\").indexOf(ch) >= 0
}
Math.eval.isNumberChar = function( ch){
return (\"0123456789.e\").indexOf(ch) >= 0
}
Math.eval.nextToken = function(){
var ch;
// skip whitespace
do{
this.iPos++;
} while(this.iPos < this.iLen && (this.sTok = this.sExpr.charAt(this.iPos)) <= \" \");
if(this.iPos >= this.iLen){
trace(\"nextToken: iPos > sExpr.length\");
return false;
}
// is it a operator ?
if(this.isOperatorChar(this.sTok)){
trace(\"nextToken: operator: \" + this.sTok + \" rest:\" + this.sExpr.substring(this.iPos+1) + \":end\");
return true;
}
// is it a function identifier ?
if(this.sTok >= \"a\" && this.sTok <= \"z\"){
do{
this.iPos++;
if(this.iPos >= this.iLen) break;
ch = this.sExpr.charAt(this.iPos);
if(! this.isFunctionIDChar(ch)) break;
this.sTok += ch;
} while (1);
this.iPos--;
this.sTokType = \"functionId\";
if(this.sTok.indexOf(\"math.\") == 0){
this.sTok = this.sTok.substring(5);
}
trace(\"nextToken: functionID: \" + this.sTok + \" rest:\" + this.sExpr.substring(this.iPos+1) + \":end\");
return true;
}
//is it a number ?
if((this.sTok >= \"0\" && this.sTok <= \"9\") || this.sTok == \".\"){
do{
this.iPos++;
if(this.iPos >= this.iLen) break;
ch = this.sExpr.charAt(this.iPos);
if(! this.isNumberChar(ch)) break;
this.sTok += ch;
} while (1);
this.iPos--;
trace(\"sTok: \" + this.sTok);
this.sTok = Number(this.sTok);
this.sTokType = typeof(this.sTok);
trace(\"nextToken: \" + this.sTokType + \": \" + this.sTok + \" rest:\" + this.sExpr.substring(this.iPos+1) + \":end\");
return (this.sTokType == \"number\");
}
return this.error(\"nextToken: no more tokens available\");
}
Math.eval.addExpr = function(){
trace(\"addExpr\");
var r1, r2;
if(this.mulExpr()){
while(1){
r1 = this.tVal;
if(this.sTok == \"+\"){
if(! this.nextToken()) return this.error(\"addExpr: 1 expression expected\");
if(this.mulExpr()){
r2 = this.tVal;
this.tVal = r1 + r2;
trace(\"addExpr: result: \" + r1 + \"+\" + r2 + \"=\" + this.tVal);
} else {
return this.error(\"addExpr: 2 expression expected\");
}
} else if(this.sTok == \"-\"){
if(! this.nextToken()) return this.error(\"addExpr: 3 expression expected\");
if(this.mulExpr()){
r2 = this.tVal;
this.tVal = r1 - r2;
trace(\"addExpr: result: \" + r1 + \"+\" + r2 + \"=\" + this.tVal);
} else {
return this.error(\"addExpr: 4 expression expected\");
}
} else {
break
}
}
trace(\"addExpr: result: \" + this.tVal);
return true;
} else {
return this.error(\"addExpr: 6 expression expected\");
}
}
Math.eval.mulExpr = function(){
trace(\"mulExpr\");
var r1, r2;
if( this.unaryExpr()){
while(1){
r1 = this.tVal;
if(this.sTok == \"*\"){
if(! this.nextToken()) return this.error(\"mulExpr: 1 expression expected\");
if(this.unaryExpr()){
r2 = this.tVal;
this.tVal = r1 * r2;
trace(\"mulExpr: result: \" + r1 + \"*\" + r2 + \"=\" + this.tVal);
} else {
return this.error(\"mulExp: 2 expression expected\");
}
} else if(this.sTok == \"/\"){
if(! this.nextToken()) return this.error(\"mulExpr: 3 expression expected\");
if(this.unaryExpr()){
r2 = this.tVal;
this.tVal = r1 / r2;
trace(\"mulExpr: result: \" + r1 + \"/\" + r2 + \"=\" + this.tVal);
} else {
return this.error(\"mulExp: 4 expression expected\");
}
} else if(this.sTok == \"%\"){
if(! this.nextToken()) return this.error(\"mulExpr: 5 expression expected\");
if(this.unaryExpr()){
r2 = this.tVal;
this.tVal = r1 % r2;
trace(\"mulExpr: result: \" + r1 + \"%\" + r2 + \"=\" + this.tVal);
} else {
return this.error(\"mulExp: 6 expression expected\");
}
} else break;
}
trace(\"mulExpr: result: \" + this.tVal);
return true
} else {
return this.error(\"mulExp: 7 expression expected\");
}
}
Math.eval.unaryExpr = function(){
trace(\"unaryExpr\");
if(this.sTok == \"+\"){
if(! this.nextToken()) return this.error(\"unaryExpr: 1 expression expected\");
if(this.unaryExpr()){
return true;
} else {
return this.error(\"unaryExpr: 2 expression expected\");
}
} else if(this.sTok == \"-\"){
if(! this.nextToken()) return this.error(\"unaryExpr: 3 expression expected\");
if(this.unaryExpr()){
this.tVal *= -1;
return true;
} else {
return this.error(\"unaryExpr: 4 expression expected\");
}
} else if(this.primaryExpr()){
return true;
} else {
return this.error(\"unaryExpr: 3 expression expected\");
}
}
Math.eval.primaryExpr = function(){
trace(\"primaryExpr\");
var r1, r2, r3;
if(this.sTok == \"(\"){
if(! this.nextToken()) return this.error(\"primaryExpr: 1 expression expected\");
if(this.addExpr()){
r1 = this.tVal;
if(this.sTok == \")\"){
this.nextToken();
this.tVal = r1;
return true;
} else {
return this.error(\"primaryExpr: 2 \')\' expected\");
}
} else {
return this.error(\"primaryExpr: 3 expression expected\");
}
} else if( this.sTokType == \"number\"){
this.tVal = this.sTok;
trace(\"primaryExpr: number: \" + this.tVal);
this.nextToken();
return true;
} else if(this.sTokType == \"functionId\"){
r1 = this.sTok;
this.tValArray = [];
if( this.nextToken() && this.sTok == \"(\"){
if(! this.nextToken()) return this.error(\"primaryExpr: 4 token expected\");
if(this.sTok == \")\"){
this.nextToken();
return this.evaluateFunction(r1);
} else if( this.exprList()){
if(this.sTok == \")\"){
this.nextToken();
return this.evaluateFunction(r1);
} else {
return this.error(\"primaryExpr: 5 \')\' expected\");
}
} else {
return this.error(\"primaryExpr: 6 exprList expected\");
}
} else {
return this.error(\"primaryExpr: 7 \'(\' expected\");
}
} else {
return this.error(\"primaryExpr: 8 expression expected\");
}
}
Math.eval.exprList = function(){
trace(\"exprList\");
while(this.addExpr()){
this.tValArray.push(this.tVal);
if(this.sTok != \",\") break;
if(! this.nextToken()) return this.error(\"exprList: 1 expression expected\");
}
return true;
}
Math.eval.evaluateFunction = function(name){
trace(\"evaluateFunction\");
var r1;
var nrOfArguments = {abs:1, acos:1, asin:1, atan:1, atan2:2, ceil:1, cos:1, exp:1, floor:1, log:1, max:2, min:2, pow:2, random:0, round:1, sin:1, sqrt:1, tan:1};
if((r1 = nrOfarguments[name]) == undefined){
return this.error(\"evaluateFunction: 1 function not defined\");
}
if(r1 != this.tValArray.length){
return this.error(\"evaluateFunction: 2 wrong number of arguments\");
}
if(r1 == 1){
this.tVal = eval(\"Math.\" + name)(this.tValArray[0]);
trace(\"evaluateFunction: result: \" + name + \"(\" + this.tValArray[0] + \") = \" + this.tVal);
return true;
} else if( r1 == 2){
this.tVal = eval(\"Math.\" + name)(this.tValArray[0], this.tValArray[1]);
trace(\"evaluateFunction: result: \" + name + \"(\" + this.tValArray[0] + \", \" + this.tValArray[1] + \") = \" + this.tVal);
return true;
} else if( r1 == 0){
this.tVal = eval(\"Math.\" + name)();
trace(\"evaluateFunction: result: \" + name + \"() = \" + this.tVal);
return true;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
