Ticket #7945: Deskcalc_factorial_and_cbrt_1.diff

File Deskcalc_factorial_and_cbrt_1.diff, 6.2 KB (added by jscipione, 13 years ago)

Patch that Adds factorial and cube root support to Deskcalc. Try it out, it is fun!

  • headers/private/shared/ExpressionParser.h

    diff --git a/headers/private/shared/ExpressionParser.h b/headers/private/shared/ExpressionParser.h
    index 5052448..9c835b3 100644
    a b class ExpressionParser {  
    5959                                    int32 argumentCount);
    6060            MAPM                _ParseFunction(const Token& token);
    6161            MAPM                _ParseAtom();
     62            MAPM                _ParseFactorial(MAPM value);
    6263
    6364            void                _EatToken(int32 type);
    6465
  • src/kits/shared/ExpressionParser.cpp

    diff --git a/src/kits/shared/ExpressionParser.cpp b/src/kits/shared/ExpressionParser.cpp
    index 549a46b..1b2658d 100644
    a b enum {  
    3333    TOKEN_MODULO,
    3434
    3535    TOKEN_POWER,
     36    TOKEN_FACTORIAL,
    3637
    3738    TOKEN_OPENING_BRACKET,
    3839    TOKEN_CLOSING_BRACKET,
    class Tokenizer {  
    230231                case '^':
    231232                    type = TOKEN_POWER;
    232233                    break;
     234                case '!':
     235                    type = TOKEN_FACTORIAL;
     236                    break;
    233237
    234238                case '(':
    235239                    type = TOKEN_OPENING_BRACKET;
    ExpressionParser::_ParseSum()  
    456460
    457461            default:
    458462                fTokenizer->RewindToken();
    459                 return value;
     463                return _ParseFactorial(value);
    460464        }
    461465    }
    462466}
    ExpressionParser::_ParseProduct()  
    491495
    492496            default:
    493497                fTokenizer->RewindToken();
    494                 return value;
     498                return _ParseFactorial(value);
    495499        }
    496500    }
    497501}
    ExpressionParser::_ParsePower()  
    506510        Token token = fTokenizer->NextToken();
    507511        if (token.type != TOKEN_POWER) {
    508512            fTokenizer->RewindToken();
    509             return value;
     513            return _ParseFactorial(value);
    510514        }
    511515        value = value.pow(_ParseUnary());
    512516    }
    MAPM  
    565569ExpressionParser::_ParseFunction(const Token& token)
    566570{
    567571    if (strcasecmp("e", token.string.String()) == 0)
    568         return MAPM(MM_E);
     572        return _ParseFactorial(MAPM(MM_E));
    569573    else if (strcasecmp("pi", token.string.String()) == 0)
    570         return MAPM(MM_PI);
     574        return _ParseFactorial(MAPM(MM_PI));
    571575
    572576    // hard coded cases for different count of arguments
    573577    // supports functions with 3 arguments at most
    ExpressionParser::_ParseFunction(const Token& token)  
    576580
    577581    if (strcasecmp("abs", token.string.String()) == 0) {
    578582        _InitArguments(values, 1);
    579         return values[0].abs();
     583        return _ParseFactorial(values[0].abs());
    580584    } else if (strcasecmp("acos", token.string.String()) == 0) {
    581585        _InitArguments(values, 1);
    582586        if (values[0] < -1 || values[0] > 1)
    583587            throw ParseException("out of domain", token.position);
    584         return values[0].acos();
     588        return _ParseFactorial(values[0].acos());
    585589    } else if (strcasecmp("asin", token.string.String()) == 0) {
    586590        _InitArguments(values, 1);
    587591        if (values[0] < -1 || values[0] > 1)
    588592            throw ParseException("out of domain", token.position);
    589         return values[0].asin();
     593        return _ParseFactorial(values[0].asin());
    590594    } else if (strcasecmp("atan", token.string.String()) == 0) {
    591595        _InitArguments(values, 1);
    592         return values[0].atan();
     596        return _ParseFactorial(values[0].atan());
    593597    } else if (strcasecmp("atan2", token.string.String()) == 0) {
    594598        _InitArguments(values, 2);
    595         return values[0].atan2(values[1]);
     599        return _ParseFactorial(values[0].atan2(values[1]));
     600    } else if (strcasecmp("cbrt", token.string.String()) == 0) {
     601        _InitArguments(values, 1);
     602        return _ParseFactorial(values[0].cbrt());
    596603    } else if (strcasecmp("ceil", token.string.String()) == 0) {
    597604        _InitArguments(values, 1);
    598         return values[0].ceil();
     605        return _ParseFactorial(values[0].ceil());
    599606    } else if (strcasecmp("cos", token.string.String()) == 0) {
    600607        _InitArguments(values, 1);
    601         return values[0].cos();
     608        return _ParseFactorial(values[0].cos());
    602609    } else if (strcasecmp("cosh", token.string.String()) == 0) {
    603610        _InitArguments(values, 1);
    604         return values[0].cosh();
     611        return _ParseFactorial(values[0].cosh());
    605612    } else if (strcasecmp("exp", token.string.String()) == 0) {
    606613        _InitArguments(values, 1);
    607         return values[0].exp();
     614        return _ParseFactorial(values[0].exp());
    608615    } else if (strcasecmp("floor", token.string.String()) == 0) {
    609616        _InitArguments(values, 1);
    610         return values[0].floor();
     617        return _ParseFactorial(values[0].floor());
    611618    } else if (strcasecmp("ln", token.string.String()) == 0) {
    612619        _InitArguments(values, 1);
    613620        if (values[0] <= 0)
    614621            throw ParseException("out of domain", token.position);
    615         return values[0].log();
     622        return _ParseFactorial(values[0].log());
    616623    } else if (strcasecmp("log", token.string.String()) == 0) {
    617624        _InitArguments(values, 1);
    618625        if (values[0] <= 0)
    619626            throw ParseException("out of domain", token.position);
    620         return values[0].log10();
     627        return _ParseFactorial(values[0].log10());
    621628    } else if (strcasecmp("pow", token.string.String()) == 0) {
    622629        _InitArguments(values, 2);
    623         return values[0].pow(values[1]);
     630        return _ParseFactorial(values[0].pow(values[1]));
    624631    } else if (strcasecmp("sin", token.string.String()) == 0) {
    625632        _InitArguments(values, 1);
    626         return values[0].sin();
     633        return _ParseFactorial(values[0].sin());
    627634    } else if (strcasecmp("sinh", token.string.String()) == 0) {
    628635        _InitArguments(values, 1);
    629         return values[0].sinh();
     636        return _ParseFactorial(values[0].sinh());
    630637    } else if (strcasecmp("sqrt", token.string.String()) == 0) {
    631638        _InitArguments(values, 1);
    632639        if (values[0] < 0)
    633640            throw ParseException("out of domain", token.position);
    634         return values[0].sqrt();
     641        return _ParseFactorial(values[0].sqrt());
    635642    } else if (strcasecmp("tan", token.string.String()) == 0) {
    636643        _InitArguments(values, 1);
    637         return values[0].tan();
     644        return _ParseFactorial(values[0].tan());
    638645    } else if (strcasecmp("tanh", token.string.String()) == 0) {
    639646        _InitArguments(values, 1);
    640         return values[0].tanh();
     647        return _ParseFactorial(values[0].tanh());
    641648    }
    642649
    643650    throw ParseException("unknown identifier", token.position);
    ExpressionParser::_ParseAtom()  
    652659        throw ParseException("unexpected end of expression", token.position);
    653660
    654661    if (token.type == TOKEN_CONSTANT)
    655         return token.value;
     662        return _ParseFactorial(token.value);
    656663
    657664    fTokenizer->RewindToken();
    658665
    ExpressionParser::_ParseAtom()  
    662669
    663670    _EatToken(TOKEN_CLOSING_BRACKET);
    664671
     672    return _ParseFactorial(value);
     673}
     674
     675
     676MAPM
     677ExpressionParser::_ParseFactorial(MAPM value)
     678{
     679    if (fTokenizer->NextToken().type == TOKEN_FACTORIAL) {
     680        fTokenizer->RewindToken();
     681        _EatToken(TOKEN_FACTORIAL);
     682        return value.factorial();
     683    }
     684
     685    fTokenizer->RewindToken();
    665686    return value;
    666687}
    667688