Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как добавить возникновение ошибок (http://www.flasher.ru/forum/showthread.php?t=99236)

Rzer 31.07.2007 19:27

Как добавить возникновение ошибок
 
Пишу модуль калькулятора на АС3 вот сам класс (может пригодится, кому надо).
Код:

package atFlashClasses.math{/*
 
        AS3 Mathcad class
  Last update: July 31, 2007 v1.1
      Author: Korablyov Anatolii.
      E-mail: rzer@mail.ru
 
 Calc Constructor:            mathcad.calc(Equation:String, objContainsConstAndFunc:Object)
 Sample usage:                        mathcad.calc("-1*sin(angle*pi/180)",{angle: 20});
 Standart operators:        +-/*^()
 Standart constants:        pi,e, rnd (Number between 0 to 1)
 Standart functions:        sin(x),cos(x),tg(x),arcsin(x), arctg(x)
                                                abs(x), min(x1,..xn), max(x1,..xn), ln(x)
 
        */
        public class Mathcad {
               
                public static var ERROR_INCORRECT_EQUATION = 1;
                public static var ERROR_DIVISION_BY_ZERO = 2;
                public static var ERROR_FUNCTION_NOT_FOUND = 3;
                public static var ERROR_CONSTANT_NOT_FOUND = 4;
                public static var ERROR_NOT_A_FUNCTION = 5;
                public static var ERROR_NOT_A_CONSTANT = 6;
                public static var ERROR_INCORRECT_NUMBER_OF_ARGUMENTS = 7;
               
                public static function calc(_str,obj:Object = null){
                  var output:Array = [];    var stack:Array = [];
          var temp:String = "";    var char:String = "";
          var unary:Boolean = true; var priority:uint;
                  var dblOpCatcher:Boolean = false;
                  var BraceCntr:Number=0;
                  /////////Преобразование в обратную польскую запись////////
          mainLoop: for(var i=0;i<_str.length;i++){
                char = _str.charAt(i);
                switch(char){             
                  case "-":
                        if (unary){ //Унарный минус? Может быть в начале строки или перед открывающей скобкой
                          dblOpCatcher=true;
                                  temp+=char; unary = false; //Забираем его как число
                          continue mainLoop;
                        }
                  case "+": case "^": case "*": case "/":
                                  if(dblOpCatcher){
                                        throw new Error("Incorrect Equation string!",1);
                                }
                                  dblOpCatcher=true;
                                  unary = false; //После знака не может быть унарного минуса 
                        if (temp) {                        //Записываем в выходную строку число или переменную,
                                output.push(temp);        //если таковая стояла до знака
                          temp="";
                    }
                                //Перенесём все знаки большего приоритета из стека в выходную строку
                    while(getPriority(char) <= getPriority(stack[stack.length-1])) output.push(stack.pop());
                    stack.push(char); //Запишем знак в стек
                          break;
                  case "(":
                                  BraceCntr++;
                                  dblOpCatcher=true;
                        unary = true; //Следующим символом может быть унарный минус
                                if (temp) {
                          stack.push(temp+"@1("); //Все символы (не знак) стоящие до скобки - имя функции
                          temp="";              //где @1 - флаг-число аргументов
                                }else stack.push("(");
                        continue mainLoop;
                        case ",":  case ")":
                                if (char==")"){
                                        BraceCntr--;
                                        if (BraceCntr<0) throw new Error ("Incorrect Equation string!",1);
                                }
                                if (char==","){
                                        if (BraceCntr==0) throw new Error ("Incorrect Equation string!",1);
                                }
                                if(dblOpCatcher){
                                        throw new Error("Incorrect Equation string!",1);
                                }
                                  if (char==",") dblOpCatcher=true;
                                if (temp) {
                          output.push(temp);
                          temp="";
                    }
                                //Перенесем все знаки, которые накопилсь после "("
                                for(var j=stack.pop(); j.indexOf("(")< 0; j=stack.pop()) {
                                        output.push(j);
                                        if (stack.length==0) throw new Error("Incorrect Equation string!",1);
                                }
                                if (char==","){ //Скобка не закончилась
                                  if (j.length==1)stack.push(j);
                                  else {
                                    j = j.split("@"); //Увиличим флаг-число аргументов на 1
                                        stack.push(j[0]+"@" + (Number(j[1].substr(-2, j[1].length-1))+1) + "(");
                                  }
                                  unary=true;
                                }else if (j.length > 1) output.push(j.substr(0,j.length-1)); //Скобка закончилась
                        continue mainLoop;
                  default : //Для всех чисел и букв образуем строку до знака или конца строки
                          dblOpCatcher=false;
                      temp+=char; unary = false;
                      continue mainLoop;
                }//End switch
          }//End mainLoop
                if (BraceCntr>0) throw new Error ("Incorrect Equation string!",1);
        if (temp) output.push(temp);
        while(stack.length>0) output.push(stack.pop()); //Переносим все оставшиеся знаки
                j="";

                // trace ("Обратная польская запись: " + output);
                 
                ///////////Вычисление результата////////////
                while(output.length>0){
                        j = output.shift();
                        if (j == "+" || j == "-" || j == "*" || j == "/" || j =="^"){
                          var a:Number; var b:Number;
                          b = getNumber(stack.pop(),obj);
                          a = getNumber(stack.pop(),obj);
                        }
                        switch(j){
                                case "+":          stack.push(a+b); break;
                                case "-":          stack.push(a-b); break;
                                case "*":  stack.push(a*b); break;
                                case "/": 
                                if (b==0) throw new Error("Division by zero!", 2);
                                stack.push(a/b); break;
                                case "^":  stack.push(Math.pow(a,b)); break;
                                default:
                                if (j.indexOf("@")>= 0) stack.push(getFunction(j,stack,obj));
                                else  stack.push(j);
                        }
                }
               
                return stack.pop();
          }//End function
        }//End class
}//End package

internal function getPriority(_str){
        switch (_str){
                case "^": return 3;
                case "+": case "-": return 1;
                case "*": case "/": return 2;
                case "(": return 0;
        }
}

internal function getNumber(_str,obj):Number{
        var uMinus:Number = 1;
        if (isNaN(Number(_str))){
                if (_str.charAt()=="-"){
                        uMinus=-1;
                        _str=_str.slice(1).toLowerCase();
                }
                switch(_str){
                        case "pi": return Math.PI*uMinus;
                        case "e": return Math.E*uMinus;
                        case "rnd": return Math.random()*uMinus;
                        default:
                                try{
                                        if (obj[_str] is Number){
                                      return obj[_str]*uMinus;
                                        } else if (obj[_str]==undefined){
                                                  throw new Error ("Constant '" + _str + "' was not found!",4);
                                        }else throw new Error ( _str + "' is not a Number!", 6);
                                } catch(e:Error) {
                                        throw new Error ("Constant '" + _str + "' was not found!",4);
                                }
                }
        }
        return Number(_str);
}

internal function getFunction(_str,stack,obj):Number{
        var args:Array = []; //Сами аргументы (стоят в стеке до оператора функции)
        var args_number = _str.split("@")[1]; //Число аргументов
        var func = _str.split("@")[0].toLowerCase(); //Имя функции
        for (var i = 1; i<=args_number;i++){
                args.unshift(getNumber(stack.pop(),obj));
        }
        var uMinus:Number = 1; //Переменная, фиксирующая есть ли в начале имени функции унарный минус
        if (func.charAt()=="-"){
                uMinus=-1;
                func=func.slice(1);
        }
        var f:Function;
        var r:Number;
        switch(func){ //Применим к функции массив аргуметов
          case "sin": f = Math.sin; break;
          case "cos": f = Math.cos; break;
          case "abs": f = Math.abs; break;
          case "arcsin": f = Math.asin; break;
          case "arctg": f = Math.atan; break;
          case "tg": f = Math.tan; break;
          case "ln": f = Math.log; break;
          case "min": f = Math.min; break;
          case "max": f = Math.max; break;
          default:
                  try{
                        if (obj[func] is Function){ //Нестандартная функция из переданного объекта
                      f=obj[func];
                        } else if (obj[func]==undefined){
                                  throw new Error ("Function '" + func + "' was not found!", 3);
                        }else throw new Error (func + "' is not a Function!", 5);
                } catch(e:Error) {
                        throw new Error ("Function '" + func + "' was not found!", 3);
                }
        }
        try{
                r = f.apply(null,args)*uMinus;
        }catch(e:Error){
                throw new Error ("Incorect number of arguments in function '"+ func +"'!", 7);
        }
        return r;
}

Как добавить к нему возникновение ошибок (Чтобы можно было отлавливать их через try...catch из вне) вместо трейса? Используя что-то вроде:

Код:

try{
Mathcad.calc("3/0");
}catch(e:Error){
trace(e.message + ' ' + e.errorID);
}


etc 31.07.2007 19:40

Метод calc должен выкидывать ошибку соответственно. (throw).

voy22 31.07.2007 20:05

Попутно хочу спросить, как напротив, ошибку сгенерить - со своим description?

etc 31.07.2007 20:08

Код:

var f:Function = function():void {
  trace('Hello');
  throw new Error("My custom Error");
}
try {
  f();
} catch(e:Error) {
  trace('Catched error: '+e);
}


Rzer 31.07.2007 20:25

2etc: Спасибо, изменил код класса. Добавил обработчик ошибки с неверным числом аргументов.
Если будут какие ошибки возникать или вовсе считать неверно будет, а строка задана правильно, отпишитесь сюда.


Часовой пояс GMT +4, время: 00:47.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.