Typescript - evaluate arithmetic expressions Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!How to evaluate a math expression given in string form?What is TypeScript and why would I use it in place of JavaScript?Constructor overload in TypeScriptHow do you explicitly set a new property on `window` in TypeScript?Type definition in object literal in TypeScriptget and set in TypeScriptAre strongly-typed functions as parameters possible in TypeScript?TypeScript Converting a String to a numberTypescript: Interfaces vs TypesHow to implement class constants in typescript?Typescript, Express, Mocha & Chai Error while testing

When I export an AI 300x60 art board it saves with bigger dimensions

Show two Lagrangians are equivalent

Are there existing rules/lore for MTG planeswalkers?

All ASCII characters with a given bit count

Writing a T-SQL stored procedure to receive 4 numbers and insert them into a table

Translate text contents of an existing file from lower to upper case and copy to a new file

Protagonist's race is hidden - should I reveal it?

`FindRoot [ ]`::jsing: Encountered a singular Jacobian at a point...WHY

Co-worker works way more than he should

Can gravitational waves pass through a black hole?

Does using the Inspiration rules for character defects encourage My Guy Syndrome?

Is it OK if I do not take the receipt in Germany?

Simulate round-robin tournament draw

Why did Europeans not widely domesticate foxes?

Will I have to go through TSA security when I return to the US after preclearance?

SQL Server placement of master database files vs resource database files

Deciphering death certificate writing

Is there a way to fake a method response using Mock or Stubs?

Married in secret, can marital status in passport be changed at a later date?

Could typically electronic sounds be generated mechanically?

Cisco DHCP Router

Does a Draconic Bloodline sorcerer's doubled proficiency bonus for Charisma checks against dragons apply to all dragon types or only the chosen one?

Coin Game with infinite paradox

Why did Israel vote against lifting the American embargo on Cuba?



Typescript - evaluate arithmetic expressions



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!How to evaluate a math expression given in string form?What is TypeScript and why would I use it in place of JavaScript?Constructor overload in TypeScriptHow do you explicitly set a new property on `window` in TypeScript?Type definition in object literal in TypeScriptget and set in TypeScriptAre strongly-typed functions as parameters possible in TypeScript?TypeScript Converting a String to a numberTypescript: Interfaces vs TypesHow to implement class constants in typescript?Typescript, Express, Mocha & Chai Error while testing



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








2















How can I evaluate arithmetic expressions in Typescript? An example is '(3+5*(-3+-1))'.



Eval(...) is forbidden.



A suggested solution is not accepted at runtime:



let input = '(3+5)';
let resultNumber = (new Function( 'return (' + input + ')'))();


The error is:




SyntaxError: Invalid or unexpected token
at new Function ()




Math.js with 136kb footprint (compressed) is too large in my for evaluating simple expressions. It could be customized by limiting the functionality.



So, do you have a small typescript file / service that can evaluate arithmetic expressions? Of course the unary minus/plus should work properly.










share|improve this question
























  • This post while asked for Java might contain some info which can help you out. Maybe you can rewrite some of the code to Javascript/Typescript?

    – Mathyn
    Mar 22 at 14:55












  • Make no mistake, if you think eval() is bad, then new Function(''); is just as bad for the exact same reasons.

    – Evert
    Mar 22 at 15:01






  • 1





    @Mathyn - GREAT - via your post I found a very compact evaluation of arithmetic expressions. Can you add this link to an Answer, and I will +1 it! stackoverflow.com/a/26227947/3143823

    – tjm1706
    Mar 22 at 15:22







  • 1





    @tjm1706 I'd love to but I'd have to rewrite the Java code to Typescript myself for it to be a proper answer.

    – Mathyn
    Mar 22 at 15:31











  • I am already rewriting the code. You pointed me the way for a solution. So you can post that answer.

    – tjm1706
    Mar 22 at 15:44

















2















How can I evaluate arithmetic expressions in Typescript? An example is '(3+5*(-3+-1))'.



Eval(...) is forbidden.



A suggested solution is not accepted at runtime:



let input = '(3+5)';
let resultNumber = (new Function( 'return (' + input + ')'))();


The error is:




SyntaxError: Invalid or unexpected token
at new Function ()




Math.js with 136kb footprint (compressed) is too large in my for evaluating simple expressions. It could be customized by limiting the functionality.



So, do you have a small typescript file / service that can evaluate arithmetic expressions? Of course the unary minus/plus should work properly.










share|improve this question
























  • This post while asked for Java might contain some info which can help you out. Maybe you can rewrite some of the code to Javascript/Typescript?

    – Mathyn
    Mar 22 at 14:55












  • Make no mistake, if you think eval() is bad, then new Function(''); is just as bad for the exact same reasons.

    – Evert
    Mar 22 at 15:01






  • 1





    @Mathyn - GREAT - via your post I found a very compact evaluation of arithmetic expressions. Can you add this link to an Answer, and I will +1 it! stackoverflow.com/a/26227947/3143823

    – tjm1706
    Mar 22 at 15:22







  • 1





    @tjm1706 I'd love to but I'd have to rewrite the Java code to Typescript myself for it to be a proper answer.

    – Mathyn
    Mar 22 at 15:31











  • I am already rewriting the code. You pointed me the way for a solution. So you can post that answer.

    – tjm1706
    Mar 22 at 15:44













2












2








2


1






How can I evaluate arithmetic expressions in Typescript? An example is '(3+5*(-3+-1))'.



Eval(...) is forbidden.



A suggested solution is not accepted at runtime:



let input = '(3+5)';
let resultNumber = (new Function( 'return (' + input + ')'))();


The error is:




SyntaxError: Invalid or unexpected token
at new Function ()




Math.js with 136kb footprint (compressed) is too large in my for evaluating simple expressions. It could be customized by limiting the functionality.



So, do you have a small typescript file / service that can evaluate arithmetic expressions? Of course the unary minus/plus should work properly.










share|improve this question
















How can I evaluate arithmetic expressions in Typescript? An example is '(3+5*(-3+-1))'.



Eval(...) is forbidden.



A suggested solution is not accepted at runtime:



let input = '(3+5)';
let resultNumber = (new Function( 'return (' + input + ')'))();


The error is:




SyntaxError: Invalid or unexpected token
at new Function ()




Math.js with 136kb footprint (compressed) is too large in my for evaluating simple expressions. It could be customized by limiting the functionality.



So, do you have a small typescript file / service that can evaluate arithmetic expressions? Of course the unary minus/plus should work properly.







typescript






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 23 at 11:30









halfer

14.8k759118




14.8k759118










asked Mar 22 at 14:51









tjm1706tjm1706

3,13932471




3,13932471












  • This post while asked for Java might contain some info which can help you out. Maybe you can rewrite some of the code to Javascript/Typescript?

    – Mathyn
    Mar 22 at 14:55












  • Make no mistake, if you think eval() is bad, then new Function(''); is just as bad for the exact same reasons.

    – Evert
    Mar 22 at 15:01






  • 1





    @Mathyn - GREAT - via your post I found a very compact evaluation of arithmetic expressions. Can you add this link to an Answer, and I will +1 it! stackoverflow.com/a/26227947/3143823

    – tjm1706
    Mar 22 at 15:22







  • 1





    @tjm1706 I'd love to but I'd have to rewrite the Java code to Typescript myself for it to be a proper answer.

    – Mathyn
    Mar 22 at 15:31











  • I am already rewriting the code. You pointed me the way for a solution. So you can post that answer.

    – tjm1706
    Mar 22 at 15:44

















  • This post while asked for Java might contain some info which can help you out. Maybe you can rewrite some of the code to Javascript/Typescript?

    – Mathyn
    Mar 22 at 14:55












  • Make no mistake, if you think eval() is bad, then new Function(''); is just as bad for the exact same reasons.

    – Evert
    Mar 22 at 15:01






  • 1





    @Mathyn - GREAT - via your post I found a very compact evaluation of arithmetic expressions. Can you add this link to an Answer, and I will +1 it! stackoverflow.com/a/26227947/3143823

    – tjm1706
    Mar 22 at 15:22







  • 1





    @tjm1706 I'd love to but I'd have to rewrite the Java code to Typescript myself for it to be a proper answer.

    – Mathyn
    Mar 22 at 15:31











  • I am already rewriting the code. You pointed me the way for a solution. So you can post that answer.

    – tjm1706
    Mar 22 at 15:44
















This post while asked for Java might contain some info which can help you out. Maybe you can rewrite some of the code to Javascript/Typescript?

– Mathyn
Mar 22 at 14:55






This post while asked for Java might contain some info which can help you out. Maybe you can rewrite some of the code to Javascript/Typescript?

– Mathyn
Mar 22 at 14:55














Make no mistake, if you think eval() is bad, then new Function(''); is just as bad for the exact same reasons.

– Evert
Mar 22 at 15:01





Make no mistake, if you think eval() is bad, then new Function(''); is just as bad for the exact same reasons.

– Evert
Mar 22 at 15:01




1




1





@Mathyn - GREAT - via your post I found a very compact evaluation of arithmetic expressions. Can you add this link to an Answer, and I will +1 it! stackoverflow.com/a/26227947/3143823

– tjm1706
Mar 22 at 15:22






@Mathyn - GREAT - via your post I found a very compact evaluation of arithmetic expressions. Can you add this link to an Answer, and I will +1 it! stackoverflow.com/a/26227947/3143823

– tjm1706
Mar 22 at 15:22





1




1





@tjm1706 I'd love to but I'd have to rewrite the Java code to Typescript myself for it to be a proper answer.

– Mathyn
Mar 22 at 15:31





@tjm1706 I'd love to but I'd have to rewrite the Java code to Typescript myself for it to be a proper answer.

– Mathyn
Mar 22 at 15:31













I am already rewriting the code. You pointed me the way for a solution. So you can post that answer.

– tjm1706
Mar 22 at 15:44





I am already rewriting the code. You pointed me the way for a solution. So you can post that answer.

– tjm1706
Mar 22 at 15:44












2 Answers
2






active

oldest

votes


















2














Thanks to @Mathyn I found a piece of good Java code created by @Boann. I migrated it to Typescript, there you have it.



Below you also find the Karma test code, so you can see what is possible: +, -, (unary), *, ^, /, braces, (value), sin, cos, tan, sqrt, etc.



How to use it? In Angular, you can access it via dependency injection. Otherwise you can create an object. You can specify via a boolean (here 'true') to get the result as an integer.



arithmeticExpressionEvaluator.evaluate('10 + 2 * 6') // shows 22.0
arithmeticExpressionEvaluator.evaluate('10 + 2 * 6', true) // shows 22 (integer only)


The complete Typescript source code is:



export class ArithmeticExpressionEvaluator 
static INVALID_NUMBER = -1234567.654;
str: string;
pos = -1;
ch: string;

evaluate(expression: string): number
return this.evaluateAll(expression, false);


evaluateAll(expression: string, resultIsInteger: boolean): number
this.str = expression;
pos = -1;
const outcome = this.parse();
if (resultIsInteger)
return Math.round(outcome);

return outcome;


nextChar()
this.ch = (++this.pos < this.str.length) ? this.str.charAt(this.pos) : null;


eat(charToEat: string): boolean
while (this.ch === ' ')
this.nextChar();

if (this.ch === charToEat)
this.nextChar();
return true;

return false;


parse(): number
this.nextChar();
const x = this.parseExpression();
if (this.pos < this.str.length)
return ArithmeticExpressionEvaluator.INVALID_NUMBER;

return x;


parseExpression(): number
let x = this.parseTerm();
for (; ; )
if (this.eat('+')) // addition
x += this.parseTerm();
else if (this.eat('-')) // subtraction
x -= this.parseTerm();
else
return x;




parseTerm(): number
let x = this.parseFactor();
for (; ;)
if (this.eat('*')) // multiplication
x *= this.parseFactor();
else if (this.eat('/')) // division
x /= this.parseFactor();
else
return x;




parseFactor(): number

degreesToRadians(degrees: number): number
const pi = Math.PI;
return degrees * (pi / 180);




The Karma test code is:



import ArithmeticExpressionEvaluator from './arithmetic-expression-evaluator.service';

describe('Arithmetic Expression Evaluation', () =>
let arithmeticExpressionEvaluator: ArithmeticExpressionEvaluator;
beforeEach(() =>
arithmeticExpressionEvaluator = new ArithmeticExpressionEvaluator();
);
it('Arithmetic Expression Evaluation - double result', () =>
expect(arithmeticExpressionEvaluator.evaluate('10 + 2 * 6')).toBe(22.0);
expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + 12')).toBe(212.0);
expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + -12')).toBe(188.0);
expect(arithmeticExpressionEvaluator.evaluate('100 * (2) + -12')).toBe(188.0);
expect(arithmeticExpressionEvaluator.evaluate('-100 * 2 + 12')).toBe(-188.0);
expect(arithmeticExpressionEvaluator.evaluate('100 * 2 ^ 12')).toBe(409600.0);
expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 )')).toBe(1400.0);
expect(arithmeticExpressionEvaluator.evaluate('(100) * (( 2 ) + (12) )')).toBe(1400.0);
expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 ) / 14')).toBe(100.0);
);
it('Arithmetic Expression Evaluation - integer result', () =>
expect(arithmeticExpressionEvaluator.evaluateAll('10 + 2 * 6', true)).toBe(22);
expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + 12' , true)).toBe(212);
expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + -12', true)).toBe(188);
expect(arithmeticExpressionEvaluator.evaluateAll('100 * (2) + -12', true)).toBe(188);
expect(arithmeticExpressionEvaluator.evaluateAll('-100 * 2 + 12' , true)).toBe(-188);
expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 ^ 12', true)).toBe(409600);
expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 )', true)).toBe(1400);
expect(arithmeticExpressionEvaluator.evaluateAll('(100) * (( 2 ) + (12) )', true)).toBe(1400);
expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 ) / 14', true)).toBe(100);
);
);





share|improve this answer
































    0














    If eval() is off the table, you need to write a custom DSL and write your own parser. To some extend you will build what eval() already does for you, but presumably a more restricted version without all the javascript features.



    Alternatively find an existing NPM package.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55302276%2ftypescript-evaluate-arithmetic-expressions%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2














      Thanks to @Mathyn I found a piece of good Java code created by @Boann. I migrated it to Typescript, there you have it.



      Below you also find the Karma test code, so you can see what is possible: +, -, (unary), *, ^, /, braces, (value), sin, cos, tan, sqrt, etc.



      How to use it? In Angular, you can access it via dependency injection. Otherwise you can create an object. You can specify via a boolean (here 'true') to get the result as an integer.



      arithmeticExpressionEvaluator.evaluate('10 + 2 * 6') // shows 22.0
      arithmeticExpressionEvaluator.evaluate('10 + 2 * 6', true) // shows 22 (integer only)


      The complete Typescript source code is:



      export class ArithmeticExpressionEvaluator 
      static INVALID_NUMBER = -1234567.654;
      str: string;
      pos = -1;
      ch: string;

      evaluate(expression: string): number
      return this.evaluateAll(expression, false);


      evaluateAll(expression: string, resultIsInteger: boolean): number
      this.str = expression;
      pos = -1;
      const outcome = this.parse();
      if (resultIsInteger)
      return Math.round(outcome);

      return outcome;


      nextChar()
      this.ch = (++this.pos < this.str.length) ? this.str.charAt(this.pos) : null;


      eat(charToEat: string): boolean
      while (this.ch === ' ')
      this.nextChar();

      if (this.ch === charToEat)
      this.nextChar();
      return true;

      return false;


      parse(): number
      this.nextChar();
      const x = this.parseExpression();
      if (this.pos < this.str.length)
      return ArithmeticExpressionEvaluator.INVALID_NUMBER;

      return x;


      parseExpression(): number
      let x = this.parseTerm();
      for (; ; )
      if (this.eat('+')) // addition
      x += this.parseTerm();
      else if (this.eat('-')) // subtraction
      x -= this.parseTerm();
      else
      return x;




      parseTerm(): number
      let x = this.parseFactor();
      for (; ;)
      if (this.eat('*')) // multiplication
      x *= this.parseFactor();
      else if (this.eat('/')) // division
      x /= this.parseFactor();
      else
      return x;




      parseFactor(): number

      degreesToRadians(degrees: number): number
      const pi = Math.PI;
      return degrees * (pi / 180);




      The Karma test code is:



      import ArithmeticExpressionEvaluator from './arithmetic-expression-evaluator.service';

      describe('Arithmetic Expression Evaluation', () =>
      let arithmeticExpressionEvaluator: ArithmeticExpressionEvaluator;
      beforeEach(() =>
      arithmeticExpressionEvaluator = new ArithmeticExpressionEvaluator();
      );
      it('Arithmetic Expression Evaluation - double result', () =>
      expect(arithmeticExpressionEvaluator.evaluate('10 + 2 * 6')).toBe(22.0);
      expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + 12')).toBe(212.0);
      expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + -12')).toBe(188.0);
      expect(arithmeticExpressionEvaluator.evaluate('100 * (2) + -12')).toBe(188.0);
      expect(arithmeticExpressionEvaluator.evaluate('-100 * 2 + 12')).toBe(-188.0);
      expect(arithmeticExpressionEvaluator.evaluate('100 * 2 ^ 12')).toBe(409600.0);
      expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 )')).toBe(1400.0);
      expect(arithmeticExpressionEvaluator.evaluate('(100) * (( 2 ) + (12) )')).toBe(1400.0);
      expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 ) / 14')).toBe(100.0);
      );
      it('Arithmetic Expression Evaluation - integer result', () =>
      expect(arithmeticExpressionEvaluator.evaluateAll('10 + 2 * 6', true)).toBe(22);
      expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + 12' , true)).toBe(212);
      expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + -12', true)).toBe(188);
      expect(arithmeticExpressionEvaluator.evaluateAll('100 * (2) + -12', true)).toBe(188);
      expect(arithmeticExpressionEvaluator.evaluateAll('-100 * 2 + 12' , true)).toBe(-188);
      expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 ^ 12', true)).toBe(409600);
      expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 )', true)).toBe(1400);
      expect(arithmeticExpressionEvaluator.evaluateAll('(100) * (( 2 ) + (12) )', true)).toBe(1400);
      expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 ) / 14', true)).toBe(100);
      );
      );





      share|improve this answer





























        2














        Thanks to @Mathyn I found a piece of good Java code created by @Boann. I migrated it to Typescript, there you have it.



        Below you also find the Karma test code, so you can see what is possible: +, -, (unary), *, ^, /, braces, (value), sin, cos, tan, sqrt, etc.



        How to use it? In Angular, you can access it via dependency injection. Otherwise you can create an object. You can specify via a boolean (here 'true') to get the result as an integer.



        arithmeticExpressionEvaluator.evaluate('10 + 2 * 6') // shows 22.0
        arithmeticExpressionEvaluator.evaluate('10 + 2 * 6', true) // shows 22 (integer only)


        The complete Typescript source code is:



        export class ArithmeticExpressionEvaluator 
        static INVALID_NUMBER = -1234567.654;
        str: string;
        pos = -1;
        ch: string;

        evaluate(expression: string): number
        return this.evaluateAll(expression, false);


        evaluateAll(expression: string, resultIsInteger: boolean): number
        this.str = expression;
        pos = -1;
        const outcome = this.parse();
        if (resultIsInteger)
        return Math.round(outcome);

        return outcome;


        nextChar()
        this.ch = (++this.pos < this.str.length) ? this.str.charAt(this.pos) : null;


        eat(charToEat: string): boolean
        while (this.ch === ' ')
        this.nextChar();

        if (this.ch === charToEat)
        this.nextChar();
        return true;

        return false;


        parse(): number
        this.nextChar();
        const x = this.parseExpression();
        if (this.pos < this.str.length)
        return ArithmeticExpressionEvaluator.INVALID_NUMBER;

        return x;


        parseExpression(): number
        let x = this.parseTerm();
        for (; ; )
        if (this.eat('+')) // addition
        x += this.parseTerm();
        else if (this.eat('-')) // subtraction
        x -= this.parseTerm();
        else
        return x;




        parseTerm(): number
        let x = this.parseFactor();
        for (; ;)
        if (this.eat('*')) // multiplication
        x *= this.parseFactor();
        else if (this.eat('/')) // division
        x /= this.parseFactor();
        else
        return x;




        parseFactor(): number

        degreesToRadians(degrees: number): number
        const pi = Math.PI;
        return degrees * (pi / 180);




        The Karma test code is:



        import ArithmeticExpressionEvaluator from './arithmetic-expression-evaluator.service';

        describe('Arithmetic Expression Evaluation', () =>
        let arithmeticExpressionEvaluator: ArithmeticExpressionEvaluator;
        beforeEach(() =>
        arithmeticExpressionEvaluator = new ArithmeticExpressionEvaluator();
        );
        it('Arithmetic Expression Evaluation - double result', () =>
        expect(arithmeticExpressionEvaluator.evaluate('10 + 2 * 6')).toBe(22.0);
        expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + 12')).toBe(212.0);
        expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + -12')).toBe(188.0);
        expect(arithmeticExpressionEvaluator.evaluate('100 * (2) + -12')).toBe(188.0);
        expect(arithmeticExpressionEvaluator.evaluate('-100 * 2 + 12')).toBe(-188.0);
        expect(arithmeticExpressionEvaluator.evaluate('100 * 2 ^ 12')).toBe(409600.0);
        expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 )')).toBe(1400.0);
        expect(arithmeticExpressionEvaluator.evaluate('(100) * (( 2 ) + (12) )')).toBe(1400.0);
        expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 ) / 14')).toBe(100.0);
        );
        it('Arithmetic Expression Evaluation - integer result', () =>
        expect(arithmeticExpressionEvaluator.evaluateAll('10 + 2 * 6', true)).toBe(22);
        expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + 12' , true)).toBe(212);
        expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + -12', true)).toBe(188);
        expect(arithmeticExpressionEvaluator.evaluateAll('100 * (2) + -12', true)).toBe(188);
        expect(arithmeticExpressionEvaluator.evaluateAll('-100 * 2 + 12' , true)).toBe(-188);
        expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 ^ 12', true)).toBe(409600);
        expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 )', true)).toBe(1400);
        expect(arithmeticExpressionEvaluator.evaluateAll('(100) * (( 2 ) + (12) )', true)).toBe(1400);
        expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 ) / 14', true)).toBe(100);
        );
        );





        share|improve this answer



























          2












          2








          2







          Thanks to @Mathyn I found a piece of good Java code created by @Boann. I migrated it to Typescript, there you have it.



          Below you also find the Karma test code, so you can see what is possible: +, -, (unary), *, ^, /, braces, (value), sin, cos, tan, sqrt, etc.



          How to use it? In Angular, you can access it via dependency injection. Otherwise you can create an object. You can specify via a boolean (here 'true') to get the result as an integer.



          arithmeticExpressionEvaluator.evaluate('10 + 2 * 6') // shows 22.0
          arithmeticExpressionEvaluator.evaluate('10 + 2 * 6', true) // shows 22 (integer only)


          The complete Typescript source code is:



          export class ArithmeticExpressionEvaluator 
          static INVALID_NUMBER = -1234567.654;
          str: string;
          pos = -1;
          ch: string;

          evaluate(expression: string): number
          return this.evaluateAll(expression, false);


          evaluateAll(expression: string, resultIsInteger: boolean): number
          this.str = expression;
          pos = -1;
          const outcome = this.parse();
          if (resultIsInteger)
          return Math.round(outcome);

          return outcome;


          nextChar()
          this.ch = (++this.pos < this.str.length) ? this.str.charAt(this.pos) : null;


          eat(charToEat: string): boolean
          while (this.ch === ' ')
          this.nextChar();

          if (this.ch === charToEat)
          this.nextChar();
          return true;

          return false;


          parse(): number
          this.nextChar();
          const x = this.parseExpression();
          if (this.pos < this.str.length)
          return ArithmeticExpressionEvaluator.INVALID_NUMBER;

          return x;


          parseExpression(): number
          let x = this.parseTerm();
          for (; ; )
          if (this.eat('+')) // addition
          x += this.parseTerm();
          else if (this.eat('-')) // subtraction
          x -= this.parseTerm();
          else
          return x;




          parseTerm(): number
          let x = this.parseFactor();
          for (; ;)
          if (this.eat('*')) // multiplication
          x *= this.parseFactor();
          else if (this.eat('/')) // division
          x /= this.parseFactor();
          else
          return x;




          parseFactor(): number

          degreesToRadians(degrees: number): number
          const pi = Math.PI;
          return degrees * (pi / 180);




          The Karma test code is:



          import ArithmeticExpressionEvaluator from './arithmetic-expression-evaluator.service';

          describe('Arithmetic Expression Evaluation', () =>
          let arithmeticExpressionEvaluator: ArithmeticExpressionEvaluator;
          beforeEach(() =>
          arithmeticExpressionEvaluator = new ArithmeticExpressionEvaluator();
          );
          it('Arithmetic Expression Evaluation - double result', () =>
          expect(arithmeticExpressionEvaluator.evaluate('10 + 2 * 6')).toBe(22.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + 12')).toBe(212.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + -12')).toBe(188.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * (2) + -12')).toBe(188.0);
          expect(arithmeticExpressionEvaluator.evaluate('-100 * 2 + 12')).toBe(-188.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * 2 ^ 12')).toBe(409600.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 )')).toBe(1400.0);
          expect(arithmeticExpressionEvaluator.evaluate('(100) * (( 2 ) + (12) )')).toBe(1400.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 ) / 14')).toBe(100.0);
          );
          it('Arithmetic Expression Evaluation - integer result', () =>
          expect(arithmeticExpressionEvaluator.evaluateAll('10 + 2 * 6', true)).toBe(22);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + 12' , true)).toBe(212);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + -12', true)).toBe(188);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * (2) + -12', true)).toBe(188);
          expect(arithmeticExpressionEvaluator.evaluateAll('-100 * 2 + 12' , true)).toBe(-188);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 ^ 12', true)).toBe(409600);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 )', true)).toBe(1400);
          expect(arithmeticExpressionEvaluator.evaluateAll('(100) * (( 2 ) + (12) )', true)).toBe(1400);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 ) / 14', true)).toBe(100);
          );
          );





          share|improve this answer















          Thanks to @Mathyn I found a piece of good Java code created by @Boann. I migrated it to Typescript, there you have it.



          Below you also find the Karma test code, so you can see what is possible: +, -, (unary), *, ^, /, braces, (value), sin, cos, tan, sqrt, etc.



          How to use it? In Angular, you can access it via dependency injection. Otherwise you can create an object. You can specify via a boolean (here 'true') to get the result as an integer.



          arithmeticExpressionEvaluator.evaluate('10 + 2 * 6') // shows 22.0
          arithmeticExpressionEvaluator.evaluate('10 + 2 * 6', true) // shows 22 (integer only)


          The complete Typescript source code is:



          export class ArithmeticExpressionEvaluator 
          static INVALID_NUMBER = -1234567.654;
          str: string;
          pos = -1;
          ch: string;

          evaluate(expression: string): number
          return this.evaluateAll(expression, false);


          evaluateAll(expression: string, resultIsInteger: boolean): number
          this.str = expression;
          pos = -1;
          const outcome = this.parse();
          if (resultIsInteger)
          return Math.round(outcome);

          return outcome;


          nextChar()
          this.ch = (++this.pos < this.str.length) ? this.str.charAt(this.pos) : null;


          eat(charToEat: string): boolean
          while (this.ch === ' ')
          this.nextChar();

          if (this.ch === charToEat)
          this.nextChar();
          return true;

          return false;


          parse(): number
          this.nextChar();
          const x = this.parseExpression();
          if (this.pos < this.str.length)
          return ArithmeticExpressionEvaluator.INVALID_NUMBER;

          return x;


          parseExpression(): number
          let x = this.parseTerm();
          for (; ; )
          if (this.eat('+')) // addition
          x += this.parseTerm();
          else if (this.eat('-')) // subtraction
          x -= this.parseTerm();
          else
          return x;




          parseTerm(): number
          let x = this.parseFactor();
          for (; ;)
          if (this.eat('*')) // multiplication
          x *= this.parseFactor();
          else if (this.eat('/')) // division
          x /= this.parseFactor();
          else
          return x;




          parseFactor(): number

          degreesToRadians(degrees: number): number
          const pi = Math.PI;
          return degrees * (pi / 180);




          The Karma test code is:



          import ArithmeticExpressionEvaluator from './arithmetic-expression-evaluator.service';

          describe('Arithmetic Expression Evaluation', () =>
          let arithmeticExpressionEvaluator: ArithmeticExpressionEvaluator;
          beforeEach(() =>
          arithmeticExpressionEvaluator = new ArithmeticExpressionEvaluator();
          );
          it('Arithmetic Expression Evaluation - double result', () =>
          expect(arithmeticExpressionEvaluator.evaluate('10 + 2 * 6')).toBe(22.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + 12')).toBe(212.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * 2 + -12')).toBe(188.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * (2) + -12')).toBe(188.0);
          expect(arithmeticExpressionEvaluator.evaluate('-100 * 2 + 12')).toBe(-188.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * 2 ^ 12')).toBe(409600.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 )')).toBe(1400.0);
          expect(arithmeticExpressionEvaluator.evaluate('(100) * (( 2 ) + (12) )')).toBe(1400.0);
          expect(arithmeticExpressionEvaluator.evaluate('100 * ( 2 + 12 ) / 14')).toBe(100.0);
          );
          it('Arithmetic Expression Evaluation - integer result', () =>
          expect(arithmeticExpressionEvaluator.evaluateAll('10 + 2 * 6', true)).toBe(22);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + 12' , true)).toBe(212);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 + -12', true)).toBe(188);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * (2) + -12', true)).toBe(188);
          expect(arithmeticExpressionEvaluator.evaluateAll('-100 * 2 + 12' , true)).toBe(-188);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * 2 ^ 12', true)).toBe(409600);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 )', true)).toBe(1400);
          expect(arithmeticExpressionEvaluator.evaluateAll('(100) * (( 2 ) + (12) )', true)).toBe(1400);
          expect(arithmeticExpressionEvaluator.evaluateAll('100 * ( 2 + 12 ) / 14', true)).toBe(100);
          );
          );






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 23 at 21:15

























          answered Mar 22 at 18:27









          tjm1706tjm1706

          3,13932471




          3,13932471























              0














              If eval() is off the table, you need to write a custom DSL and write your own parser. To some extend you will build what eval() already does for you, but presumably a more restricted version without all the javascript features.



              Alternatively find an existing NPM package.






              share|improve this answer



























                0














                If eval() is off the table, you need to write a custom DSL and write your own parser. To some extend you will build what eval() already does for you, but presumably a more restricted version without all the javascript features.



                Alternatively find an existing NPM package.






                share|improve this answer

























                  0












                  0








                  0







                  If eval() is off the table, you need to write a custom DSL and write your own parser. To some extend you will build what eval() already does for you, but presumably a more restricted version without all the javascript features.



                  Alternatively find an existing NPM package.






                  share|improve this answer













                  If eval() is off the table, you need to write a custom DSL and write your own parser. To some extend you will build what eval() already does for you, but presumably a more restricted version without all the javascript features.



                  Alternatively find an existing NPM package.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 22 at 14:57









                  EvertEvert

                  42.7k1572127




                  42.7k1572127



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55302276%2ftypescript-evaluate-arithmetic-expressions%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

                      용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

                      155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해