Arithmetic evaluation: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 25: Line 25:
=={{header|11l}}==
=={{header|11l}}==
[[wp:Pratt parser|Pratt parser]]
[[wp:Pratt parser|Pratt parser]]
<lang 11l>T Symbol
<syntaxhighlight lang=11l>T Symbol
String id
String id
Int lbp
Int lbp
Line 140: Line 140:
L(expr_str) [‘-2 / 2 + 4 + 3 * 2’,
L(expr_str) [‘-2 / 2 + 4 + 3 * 2’,
‘2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10’]
‘2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10’]
print(expr_str‘ = ’parse(expr_str).eval())</lang>
print(expr_str‘ = ’parse(expr_str).eval())</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 154: Line 154:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - A68RS has not implemented forward declarations}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - A68RS has not implemented forward declarations}}
<lang algol68>INT base=10;
<syntaxhighlight lang=algol68>INT base=10;
MODE FIXED = LONG REAL; # numbers in the format 9,999.999 #
MODE FIXED = LONG REAL; # numbers in the format 9,999.999 #


Line 295: Line 295:
index error:
index error:
printf(("Stack over flow"))
printf(("Stack over flow"))
)</lang>
)</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 303: Line 303:
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
{{works with|AutoHotkey_L}}
<lang AutoHotkey>/*
<syntaxhighlight lang=AutoHotkey>/*
hand coded recursive descent parser
hand coded recursive descent parser
expr : term ( ( PLUS | MINUS ) term )* ;
expr : term ( ( PLUS | MINUS ) term )* ;
Line 452: Line 452:
}
}


#include calclex.ahk</lang>
#include calclex.ahk</syntaxhighlight>
calclex.ahk<lang AutoHotkey>tokenize(string, lexer)
calclex.ahk<syntaxhighlight lang=AutoHotkey>tokenize(string, lexer)
{
{
stringo := string ; store original string
stringo := string ; store original string
Line 519: Line 519:
string := "pos= " token.pos "`nvalue= " token.value "`ntype= " token.type
string := "pos= " token.pos "`nvalue= " token.value "`ntype= " token.type
return string
return string
}</lang>
}</syntaxhighlight>


=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
<lang bbcbasic> Expr$ = "1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10"
<syntaxhighlight lang=bbcbasic> Expr$ = "1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10"
PRINT "Input = " Expr$
PRINT "Input = " Expr$
AST$ = FNast(Expr$)
AST$ = FNast(Expr$)
Line 580: Line 580:
ENDIF
ENDIF
UNTIL FALSE
UNTIL FALSE
= num$</lang>
= num$</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 595: Line 595:


{{libheader|Boost.Spirit|1.8.4}}
{{libheader|Boost.Spirit|1.8.4}}
<lang cpp> #include <boost/spirit.hpp>
<syntaxhighlight lang=cpp> #include <boost/spirit.hpp>
#include <boost/spirit/tree/ast.hpp>
#include <boost/spirit/tree/ast.hpp>
#include <string>
#include <string>
Line 710: Line 710:
}
}
}
}
};</lang>
};</syntaxhighlight>


=={{header|Clojure}}==
=={{header|Clojure}}==
<lang Clojure>(def precedence '{* 0, / 0
<syntaxhighlight lang=Clojure>(def precedence '{* 0, / 0
+ 1, - 1})
+ 1, - 1})


Line 765: Line 765:


user> (evaluate "1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1")
user> (evaluate "1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1")
60</lang>
60</syntaxhighlight>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Line 783: Line 783:
This implementation can read integers, and produce integral and rational values.
This implementation can read integers, and produce integral and rational values.


<lang lisp>(defun tokenize-stream (stream)
<syntaxhighlight lang=lisp>(defun tokenize-stream (stream)
(labels ((whitespace-p (char)
(labels ((whitespace-p (char)
(find char #(#\space #\newline #\return #\tab)))
(find char #(#\space #\newline #\return #\tab)))
Line 868: Line 868:
(loop for token = (tokenize-stream in)
(loop for token = (tokenize-stream in)
until (null token)
until (null token)
collect token)))))))</lang>
collect token)))))))</syntaxhighlight>
Examples
Examples
Line 912: Line 912:
=={{header|D}}==
=={{header|D}}==
After the AST tree is constructed, a visitor pattern is used to display the AST structure and calculate the expression value.
After the AST tree is constructed, a visitor pattern is used to display the AST structure and calculate the expression value.
<lang d>import std.stdio, std.string, std.ascii, std.conv, std.array,
<syntaxhighlight lang=d>import std.stdio, std.string, std.ascii, std.conv, std.array,
std.exception, std.traits;
std.exception, std.traits;


Line 1,132: Line 1,132:
immutable exp = (args.length > 1) ? args[1 .. $].join(' ') : exp0;
immutable exp = (args.length > 1) ? args[1 .. $].join(' ') : exp0;
new AST().parse(exp).CalcVis; // Should be 60.
new AST().parse(exp).CalcVis; // Should be 60.
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> ........................................................+.
<pre> ........................................................+.
Line 1,154: Line 1,154:
=={{header|Dyalect}}==
=={{header|Dyalect}}==


<lang dyalect>type Expr = Bin(op, Expr left, Expr right) or Literal(Float val)
<syntaxhighlight lang=dyalect>type Expr = Bin(op, Expr left, Expr right) or Literal(Float val)
with Lookup
with Lookup


Line 1,271: Line 1,271:
print( eval("(1+33.23)*7") )
print( eval("(1+33.23)*7") )
print( eval("1+33.23*7") )</lang>
print( eval("1+33.23*7") )</syntaxhighlight>


{{out}}
{{out}}
Line 1,282: Line 1,282:
While the task requirements specify not evaluating using the language's built-in eval, they don't say that you have to write your own ''parser''...
While the task requirements specify not evaluating using the language's built-in eval, they don't say that you have to write your own ''parser''...


<lang e>def eParser := <elang:syntax.makeEParser>
<syntaxhighlight lang=e>def eParser := <elang:syntax.makeEParser>
def LiteralExpr := <elang:evm.makeLiteralExpr>.asType()
def LiteralExpr := <elang:evm.makeLiteralExpr>.asType()
def arithEvaluate(expr :String) {
def arithEvaluate(expr :String) {
Line 1,299: Line 1,299:
return evalAST(ast)
return evalAST(ast)
}</lang>
}</syntaxhighlight>


Parentheses are handled by the parser.
Parentheses are handled by the parser.


<lang e>? arithEvaluate("1 + 2")
<syntaxhighlight lang=e>? arithEvaluate("1 + 2")
# value: 3
# value: 3


Line 1,310: Line 1,310:


? arithEvaluate("(1 + 2 / 2) * (5 + 5)")
? arithEvaluate("(1 + 2 / 2) * (5 + 5)")
# value: 20.0</lang>
# value: 20.0</syntaxhighlight>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 5.0 :
ELENA 5.0 :
<lang elena>import system'routines;
<syntaxhighlight lang=elena>import system'routines;
import extensions;
import extensions;
import extensions'text;
import extensions'text;
Line 1,654: Line 1,654:
text.clear()
text.clear()
}
}
}</lang>
}</syntaxhighlight>


=={{header|Emacs Lisp}}==
=={{header|Emacs Lisp}}==
<lang lisp>#!/usr/bin/env emacs --script
<syntaxhighlight lang=lisp>#!/usr/bin/env emacs --script
;; -*- mode: emacs-lisp; lexical-binding: t -*-
;; -*- mode: emacs-lisp; lexical-binding: t -*-
;;> ./arithmetic-evaluation '(1 + 2) * 3'
;;> ./arithmetic-evaluation '(1 + 2) * 3'
Line 1,750: Line 1,750:
(terpri)))
(terpri)))
(setq command-line-args-left nil)
(setq command-line-args-left nil)
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 1,772: Line 1,772:


=={{header|ERRE}}==
=={{header|ERRE}}==
<lang ERRE>
<syntaxhighlight lang=ERRE>
PROGRAM EVAL
PROGRAM EVAL


Line 2,006: Line 2,006:
IF NERR>0 THEN PRINT("Internal Error #";NERR) ELSE PRINT("Value is ";DB#) END IF
IF NERR>0 THEN PRINT("Internal Error #";NERR) ELSE PRINT("Value is ";DB#) END IF
END PROGRAM
END PROGRAM
</syntaxhighlight>
</lang>
This solution is based on a stack: as a plus there is a power (^) operator. Unary operator "-" is accepted. Program shows the stack after every operation and you must press a key to go on (this feature can be avoided by removing the final REPEAT..UNTIL loop at the end of "DISEGNA_STACK" procedure).
This solution is based on a stack: as a plus there is a power (^) operator. Unary operator "-" is accepted. Program shows the stack after every operation and you must press a key to go on (this feature can be avoided by removing the final REPEAT..UNTIL loop at the end of "DISEGNA_STACK" procedure).


Line 2,013: Line 2,013:


<code>AbstractSyntaxTree.fs</code>:
<code>AbstractSyntaxTree.fs</code>:
<lang fsharp>module AbstractSyntaxTree
<syntaxhighlight lang=fsharp>module AbstractSyntaxTree
type Expression =
type Expression =
Line 2,020: Line 2,020:
| Minus of Expression * Expression
| Minus of Expression * Expression
| Times of Expression * Expression
| Times of Expression * Expression
| Divide of Expression * Expression</lang>
| Divide of Expression * Expression</syntaxhighlight>


<code>Lexer.fsl</code>:
<code>Lexer.fsl</code>:
<lang fsharp>{
<syntaxhighlight lang=fsharp>{
module Lexer
module Lexer


Line 2,046: Line 2,046:
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; token lexbuf }
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; token lexbuf }
| eof { EOF }
| eof { EOF }
| _ { failwithf "unrecognized input: '%s'" <| lexeme lexbuf }</lang>
| _ { failwithf "unrecognized input: '%s'" <| lexeme lexbuf }</syntaxhighlight>


<code>Parser.fsy</code>:
<code>Parser.fsy</code>:
<lang fsharp>%{
<syntaxhighlight lang=fsharp>%{
open AbstractSyntaxTree
open AbstractSyntaxTree
%}
%}
Line 2,074: Line 2,074:
| Expr TIMES Expr { Times ($1, $3) }
| Expr TIMES Expr { Times ($1, $3) }
| Expr DIVIDE Expr { Divide ($1, $3) }
| Expr DIVIDE Expr { Divide ($1, $3) }
| LPAREN Expr RPAREN { $2 } </lang>
| LPAREN Expr RPAREN { $2 } </syntaxhighlight>


<code>Program.fs</code>:
<code>Program.fs</code>:
<lang fsharp>open AbstractSyntaxTree
<syntaxhighlight lang=fsharp>open AbstractSyntaxTree
open Lexer
open Lexer
open Parser
open Parser
Line 2,097: Line 2,097:
|> parse
|> parse
|> eval
|> eval
|> printfn "%d"</lang>
|> printfn "%d"</syntaxhighlight>


=={{header|Factor}}==
=={{header|Factor}}==
<lang factor>USING: accessors kernel locals math math.parser peg.ebnf ;
<syntaxhighlight lang=factor>USING: accessors kernel locals math math.parser peg.ebnf ;
IN: rosetta.arith
IN: rosetta.arith


Line 2,141: Line 2,141:


: evaluate ( string -- result )
: evaluate ( string -- result )
expr-ast eval-ast ;</lang>
expr-ast eval-ast ;</syntaxhighlight>


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang FreeBASIC>
<syntaxhighlight lang=FreeBASIC>
'Arithmetic evaluation
'Arithmetic evaluation
'
'
Line 2,340: Line 2,340:
if sym <> done_sym then error_msg("unexpected input")
if sym <> done_sym then error_msg("unexpected input")
loop
loop
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 2,355: Line 2,355:
=={{header|Groovy}}==
=={{header|Groovy}}==
Solution:
Solution:
<lang groovy>enum Op {
<syntaxhighlight lang=groovy>enum Op {
ADD('+', 2),
ADD('+', 2),
SUBTRACT('-', 2),
SUBTRACT('-', 2),
Line 2,498: Line 2,498:
}
}
return elements[0] instanceof List ? parse(elements[0]) : elements[0]
return elements[0] instanceof List ? parse(elements[0]) : elements[0]
}</lang>
}</syntaxhighlight>


Test:
Test:
<lang groovy>def testParse = {
<syntaxhighlight lang=groovy>def testParse = {
def ex = parse(it)
def ex = parse(it)
print """
print """
Line 2,536: Line 2,536:
try { testParse('1++') } catch (e) { println e }
try { testParse('1++') } catch (e) { println e }
try { testParse('*1') } catch (e) { println e }
try { testParse('*1') } catch (e) { println e }
try { testParse('/ 1 /') } catch (e) { println e }</lang>
try { testParse('/ 1 /') } catch (e) { println e }</syntaxhighlight>


{{out}}
{{out}}
Line 2,605: Line 2,605:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>{-# LANGUAGE FlexibleContexts #-}
<syntaxhighlight lang=haskell>{-# LANGUAGE FlexibleContexts #-}


import Text.Parsec
import Text.Parsec
Line 2,651: Line 2,651:


main :: IO ()
main :: IO ()
main = print $ solution "(1+3)*7"</lang>
main = print $ solution "(1+3)*7"</syntaxhighlight>
{{Out}}
{{Out}}
<pre>28</pre>
<pre>28</pre>
Line 2,667: Line 2,667:
* Notice that the code looks remarkably like a typical grammar, rather than being an opaque cryptic solution
* Notice that the code looks remarkably like a typical grammar, rather than being an opaque cryptic solution
* Does not rely on any library to silently solve 1/2 the problem; in fact, this code would probably suit being put into a library almost verbatim
* Does not rely on any library to silently solve 1/2 the problem; in fact, this code would probably suit being put into a library almost verbatim
<lang Icon>procedure main() #: simple arithmetical parser / evaluator
<syntaxhighlight lang=Icon>procedure main() #: simple arithmetical parser / evaluator
write("Usage: Input expression = Abstract Syntax Tree = Value, ^Z to end.")
write("Usage: Input expression = Abstract Syntax Tree = Value, ^Z to end.")
repeat {
repeat {
Line 2,767: Line 2,767:
procedure exponent()
procedure exponent()
suspend tab(any('eE')) || =("+" | "-" | "") || digits() | ""
suspend tab(any('eE')) || =("+" | "-" | "") || digits() | ""
end</lang>
end</syntaxhighlight>


{{out|Sample Output}}
{{out|Sample Output}}
Line 2,799: Line 2,799:
The implementation here uses a shift/reduce parser to build a tree structure for evaluation (a tree structure which J happens to support for evaluation):
The implementation here uses a shift/reduce parser to build a tree structure for evaluation (a tree structure which J happens to support for evaluation):


<lang j>parse=:parse_parser_
<syntaxhighlight lang=j>parse=:parse_parser_
eval=:monad define
eval=:monad define
'gerund structure'=:y
'gerund structure'=:y
Line 2,864: Line 2,864:
coerase tmp
coerase tmp
r
r
)</lang>
)</syntaxhighlight>
example use:
example use:
<lang j> eval parse '1+2*3/(4-5+6)'
<syntaxhighlight lang=j> eval parse '1+2*3/(4-5+6)'
2.2</lang>
2.2</syntaxhighlight>


You can also display the syntax tree, for example:
You can also display the syntax tree, for example:
<lang j> parse '2*3/(4-5)'
<syntaxhighlight lang=j> parse '2*3/(4-5)'
┌─────────────────────────────────────────────────────┬───────────────────┐
┌─────────────────────────────────────────────────────┬───────────────────┐
│┌───┬───────┬───┬───────┬───┬─┬───────┬───┬───────┬─┐│┌───────┬─┬───────┐│
│┌───┬───────┬───┬───────┬───┬─┬───────┬───┬───────┬─┐│┌───────┬─┬───────┐│
Line 2,879: Line 2,879:
││ │└─────┘│ │└─────┘│ │ │└─────┘│ │└─────┘│ ││ │
││ │└─────┘│ │└─────┘│ │ │└─────┘│ │└─────┘│ ││ │
│└───┴───────┴───┴───────┴───┴─┴───────┴───┴───────┴─┘│ │
│└───┴───────┴───┴───────┴───┴─┴───────┴───┴───────┴─┘│ │
└─────────────────────────────────────────────────────┴───────────────────┘</lang>
└─────────────────────────────────────────────────────┴───────────────────┘</syntaxhighlight>


At the top level, the first box is a list of terminals, and the second box represents their parsed structure within the source sentence, with numbers indexing the respective terminals. Within the list of terminals - each terminal is contained with a box. Operators are strings inside of boxes (the leading $ "operator" in this example is not really an operator - it's just a placeholder that was used to help in the parsing). Punctuation is simply the punctuation string (left or right parenthesis - these are also not really operators and are just placeholders which were used during parsing). Numeric values are a box inside of a box where the inner box carries two further boxes. The first indicates syntactic data type ('0' for arrays - here that means numbers) and the second carries the value.
At the top level, the first box is a list of terminals, and the second box represents their parsed structure within the source sentence, with numbers indexing the respective terminals. Within the list of terminals - each terminal is contained with a box. Operators are strings inside of boxes (the leading $ "operator" in this example is not really an operator - it's just a placeholder that was used to help in the parsing). Punctuation is simply the punctuation string (left or right parenthesis - these are also not really operators and are just placeholders which were used during parsing). Numeric values are a box inside of a box where the inner box carries two further boxes. The first indicates syntactic data type ('0' for arrays - here that means numbers) and the second carries the value.
Line 2,887: Line 2,887:
Uses the [[Arithmetic/Rational/Java|BigRational class]] to handle arbitrary-precision numbers (rational numbers since basic arithmetic will result in rational values).
Uses the [[Arithmetic/Rational/Java|BigRational class]] to handle arbitrary-precision numbers (rational numbers since basic arithmetic will result in rational values).


<lang java>import java.util.Stack;
<syntaxhighlight lang=java>import java.util.Stack;


public class ArithmeticEvaluation {
public class ArithmeticEvaluation {
Line 3,051: Line 3,051:
}
}
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,066: Line 3,066:
Spaces are removed, expressions like <code>5--1</code> are treated as <code>5 - -1</code>
Spaces are removed, expressions like <code>5--1</code> are treated as <code>5 - -1</code>


<lang javascript>function evalArithmeticExp(s) {
<syntaxhighlight lang=javascript>function evalArithmeticExp(s) {
s = s.replace(/\s/g,'').replace(/^\+/,'');
s = s.replace(/\s/g,'').replace(/^\+/,'');
var rePara = /\([^\(\)]*\)/;
var rePara = /\([^\(\)]*\)/;
Line 3,120: Line 3,120:
}
}
}
}
}</lang>
}</syntaxhighlight>




Line 3,136: Line 3,136:


=== PEG operations ===
=== PEG operations ===
<lang jq>def star(E): (E | star(E)) // .;
<syntaxhighlight lang=jq>def star(E): (E | star(E)) // .;
def plus(E): E | (plus(E) // . );
def plus(E): E | (plus(E) // . );
def optional(E): E // .;
def optional(E): E // .;
def amp(E): . as $in | E | $in;
def amp(E): . as $in | E | $in;
def neg(E): select( [E] == [] );</lang>
def neg(E): select( [E] == [] );</syntaxhighlight>




=== Helper functions ===
=== Helper functions ===
<lang jq>def literal($s):
<syntaxhighlight lang=jq>def literal($s):
select(.remainder | startswith($s))
select(.remainder | startswith($s))
| .result += [$s]
| .result += [$s]
Line 3,165: Line 3,165:
def parseNumber($re):
def parseNumber($re):
consume($re)
consume($re)
| .result = .result + [.match|tonumber] ;</lang>
| .result = .result + [.match|tonumber] ;</syntaxhighlight>


=== PEG Grammar ===
=== PEG Grammar ===
The PEG grammar for arithmetic expressions follows the one given at the Raku entry.<lang jq>def Expr:
The PEG grammar for arithmetic expressions follows the one given at the Raku entry.<syntaxhighlight lang=jq>def Expr:


def ws: consume(" *");
def ws: consume(" *");
Line 3,180: Line 3,180:
Product | ws | star( (literal("+") // literal("-")) | Product);
Product | ws | star( (literal("+") // literal("-")) | Product);


Sum;</lang>
Sum;</syntaxhighlight>


=== Evaluation ===
=== Evaluation ===
<lang jq># Left-to-right evaluation
<syntaxhighlight lang=jq># Left-to-right evaluation
def eval:
def eval:
if type == "array" then
if type == "array" then
Line 3,204: Line 3,204:
{remainder: String}
{remainder: String}
| Expr.result
| Expr.result
| eval;</lang>
| eval;</syntaxhighlight>


=== Example ===
=== Example ===
Line 3,214: Line 3,214:
From Javascript entry.
From Javascript entry.


<lang javascript>/* Arithmetic evaluation, in Jsish */
<syntaxhighlight lang=javascript>/* Arithmetic evaluation, in Jsish */
function evalArithmeticExp(s) {
function evalArithmeticExp(s) {
s = s.replace(/\s/g,'').replace(/^\+/,'');
s = s.replace(/\s/g,'').replace(/^\+/,'');
Line 3,290: Line 3,290:
evalArithmeticExp('2*-3--4+-0.25') ==> -2.25
evalArithmeticExp('2*-3--4+-0.25') ==> -2.25
=!EXPECTEND!=
=!EXPECTEND!=
*/</lang>
*/</syntaxhighlight>


{{out}}
{{out}}
Line 3,303: Line 3,303:
=={{header|Julia}}==
=={{header|Julia}}==
Julia's homoiconic nature and strong metaprogramming facilities make AST/Expression parsing and creation as accessible and programmatic as other language features
Julia's homoiconic nature and strong metaprogramming facilities make AST/Expression parsing and creation as accessible and programmatic as other language features
<lang julia>julia> expr="2 * (3 -1) + 2 * 5"
<syntaxhighlight lang=julia>julia> expr="2 * (3 -1) + 2 * 5"
"2 * (3 -1) + 2 * 5"
"2 * (3 -1) + 2 * 5"


Line 3,343: Line 3,343:


julia> eval(parse("2 * (3 + ((5) / (7 - 11)))"))
julia> eval(parse("2 * (3 + ((5) / (7 - 11)))"))
3.5</lang>
3.5</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|JavaScript}}
{{trans|JavaScript}}
<lang scala>// version 1.2.10
<syntaxhighlight lang=scala>// version 1.2.10


/* if string is empty, returns zero */
/* if string is empty, returns zero */
Line 3,432: Line 3,432:
"1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1"
"1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1"
).forEach { println("$it = ${evalArithmeticExp(it)}") }
).forEach { println("$it = ${evalArithmeticExp(it)}") }
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,449: Line 3,449:


=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
<syntaxhighlight lang=lb>
<lang lb>
'[RC] Arithmetic evaluation.bas
'[RC] Arithmetic evaluation.bas
'Buld the tree (with linked nodes, in array 'cause LB has no pointers)
'Buld the tree (with linked nodes, in array 'cause LB has no pointers)
Line 3,685: Line 3,685:
addOpNode = newNode
addOpNode = newNode
end function
end function
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 3,703: Line 3,703:
=={{header|Lua}}==
=={{header|Lua}}==


<lang lua>require"lpeg"
<syntaxhighlight lang=lua>require"lpeg"


P, R, C, S, V = lpeg.P, lpeg.R, lpeg.C, lpeg.S, lpeg.V
P, R, C, S, V = lpeg.P, lpeg.R, lpeg.C, lpeg.S, lpeg.V
Line 3,742: Line 3,742:
end
end


print(eval{expression:match(io.read())})</lang>
print(eval{expression:match(io.read())})</syntaxhighlight>


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
Line 3,748: Line 3,748:
All visible variables can be used, and all known functions, internal and user (if they are visible at that point). Global variables and functions are always visible.
All visible variables can be used, and all known functions, internal and user (if they are visible at that point). Global variables and functions are always visible.


<lang M2000 Interpreter>
<syntaxhighlight lang=M2000 Interpreter>
y=100
y=100
Module CheckEval {
Module CheckEval {
Line 3,761: Line 3,761:
}
}
Call CheckEval
Call CheckEval
</syntaxhighlight>
</lang>


From BBC BASIC. In M2000 we can't call a user function which isn't a child function, so here we make all functions as members of same group, so now they call each other. A function as a member in a group can use other members, using a dot or This and a dot, so .Ast$() is same as This.Ast$().
From BBC BASIC. In M2000 we can't call a user function which isn't a child function, so here we make all functions as members of same group, so now they call each other. A function as a member in a group can use other members, using a dot or This and a dot, so .Ast$() is same as This.Ast$().


<lang M2000 Interpreter>
<syntaxhighlight lang=M2000 Interpreter>
Module CheckAst {
Module CheckAst {
Group Eval {
Group Eval {
Line 3,819: Line 3,819:
}
}
CheckAst
CheckAst
</syntaxhighlight>
</lang>


=={{header|Mathematica}} / {{header|Wolfram Language}}==
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<lang Mathematica>(*parsing:*)
<syntaxhighlight lang=Mathematica>(*parsing:*)
parse[string_] :=
parse[string_] :=
Module[{e},
Module[{e},
Line 3,855: Line 3,855:
evaluate[{"*", a_, b_}] := evaluate[a]*evaluate[b];
evaluate[{"*", a_, b_}] := evaluate[a]*evaluate[b];
evaluate[{"/", a_, b_}] := evaluate[a]/evaluate[b];
evaluate[{"/", a_, b_}] := evaluate[a]/evaluate[b];
evaluate[string_String] := evaluate[parse[string]]</lang>
evaluate[string_String] := evaluate[parse[string]]</syntaxhighlight>


Example use:
Example use:
<lang Mathematica>parse["-1+2(3+4*-5/6)"]
<syntaxhighlight lang=Mathematica>parse["-1+2(3+4*-5/6)"]
evaluate["-1+2(3+4*-5/6)"]</lang>
evaluate["-1+2(3+4*-5/6)"]</syntaxhighlight>


{{out}}
{{out}}
Line 3,866: Line 3,866:


=={{header|MiniScript}}==
=={{header|MiniScript}}==
<lang MiniScript>Expr = {}
<syntaxhighlight lang=MiniScript>Expr = {}
Expr.eval = 0
Expr.eval = 0


Line 3,928: Line 3,928:
print ast.eval
print ast.eval
end while
end while
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>Enter expression: 200*42
<pre>Enter expression: 200*42
Line 3,947: Line 3,947:
This implementation uses a Pratt parser.
This implementation uses a Pratt parser.


<lang nim>import strutils
<syntaxhighlight lang=nim>import strutils
import os
import os


Line 4,097: Line 4,097:


# In the end, we print out the result.
# In the end, we print out the result.
echo ==ast</lang>
echo ==ast</syntaxhighlight>


=={{header|OCaml}}==
=={{header|OCaml}}==


<lang ocaml>type expression =
<syntaxhighlight lang=ocaml>type expression =
| Const of float
| Const of float
| Sum of expression * expression (* e1 + e2 *)
| Sum of expression * expression (* e1 + e2 *)
Line 4,139: Line 4,139:
let parse_expression = parser [< e = parse_expr; _ = Stream.empty >] -> e
let parse_expression = parser [< e = parse_expr; _ = Stream.empty >] -> e


let read_expression s = parse_expression(lexer(Stream.of_string s))</lang>
let read_expression s = parse_expression(lexer(Stream.of_string s))</syntaxhighlight>


Using the function <code>read_expression</code> in an interactive loop:
Using the function <code>read_expression</code> in an interactive loop:


<lang ocaml>let () =
<syntaxhighlight lang=ocaml>let () =
while true do
while true do
print_string "Expression: ";
print_string "Expression: ";
Line 4,151: Line 4,151:
let res = eval expr in
let res = eval expr in
Printf.printf " = %g\n%!" res;
Printf.printf " = %g\n%!" res;
done</lang>
done</syntaxhighlight>


Compile with:
Compile with:
Line 4,157: Line 4,157:


=={{header|ooRexx}}==
=={{header|ooRexx}}==
<lang ooRexx>
<syntaxhighlight lang=ooRexx>
expressions = .array~of("2+3", "2+3/4", "2*3-4", "2*(3+4)+5/6", "2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10", "2*-3--4+-.25")
expressions = .array~of("2+3", "2+3/4", "2*3-4", "2*(3+4)+5/6", "2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10", "2*-3--4+-.25")
loop input over expressions
loop input over expressions
Line 4,393: Line 4,393:
raise syntax 98.900 array("Invalid expression")
raise syntax 98.900 array("Invalid expression")
return expression
return expression
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 4,410: Line 4,410:
The <code>Do</code> procedure automatically threads the input state through a sequence of procedure calls.
The <code>Do</code> procedure automatically threads the input state through a sequence of procedure calls.


<lang oz>declare
<syntaxhighlight lang=oz>declare


fun {Expr X0 ?X}
fun {Expr X0 ?X}
Line 4,497: Line 4,497:
{Inspector.configure widgetShowStrings true}
{Inspector.configure widgetShowStrings true}
{Inspect AST}
{Inspect AST}
{Inspect {Eval AST}}</lang>
{Inspect {Eval AST}}</syntaxhighlight>


To improve performance, the number of choice points should be limited, for example by reading numbers deterministically instead.
To improve performance, the number of choice points should be limited, for example by reading numbers deterministically instead.
Line 4,506: Line 4,506:


=={{header|Perl}}==
=={{header|Perl}}==
<lang perl>sub ev
<syntaxhighlight lang=perl>sub ev
# Evaluates an arithmetic expression like "(1+3)*7" and returns
# Evaluates an arithmetic expression like "(1+3)*7" and returns
# its value.
# its value.
Line 4,566: Line 4,566:
my ($op, @operands) = @$ast;
my ($op, @operands) = @$ast;
$_ = ev_ast($_) foreach @operands;
$_ = ev_ast($_) foreach @operands;
return $ops{$op}->(@operands);}}</lang>
return $ops{$op}->(@operands);}}</syntaxhighlight>


=={{header|Phix}}==
=={{header|Phix}}==
Line 4,573: Line 4,573:
plus this as asked for has an AST, whereas Phix uses cross-linked flat IL.
plus this as asked for has an AST, whereas Phix uses cross-linked flat IL.
See also [[Arithmetic_evaluation/Phix]] for a translation of the D entry.
See also [[Arithmetic_evaluation/Phix]] for a translation of the D entry.
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Arithmetic_evaluation.exw</span>
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Arithmetic_evaluation.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,793: Line 4,793:
<span style="color: #0000FF;">?</span><span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">opstack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">opstack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
I added a flag (for this task) to store the ast nodes as op_p_p, p_op_p, or p_p_op, whichever you prefer.
I added a flag (for this task) to store the ast nodes as op_p_p, p_op_p, or p_p_op, whichever you prefer.
{{out}}
{{out}}
Line 4,867: Line 4,867:


=={{header|Picat}}==
=={{header|Picat}}==
<lang Picat>main =>
<syntaxhighlight lang=Picat>main =>
print("Enter an expression: "),
print("Enter an expression: "),
Str = read_line(),
Str = read_line(),
Line 4,873: Line 4,873:
Res is Exp,
Res is Exp,
printf("Result = %w\n", Res).
printf("Result = %w\n", Res).
</syntaxhighlight>
</lang>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Line 4,879: Line 4,879:
(numbers and transient symbols). From that, a recursive descendent parser can
(numbers and transient symbols). From that, a recursive descendent parser can
build an expression tree, resulting in directly executable Lisp code.
build an expression tree, resulting in directly executable Lisp code.
<lang PicoLisp>(de ast (Str)
<syntaxhighlight lang=PicoLisp>(de ast (Str)
(let *L (str Str "")
(let *L (str Str "")
(aggregate) ) )
(aggregate) ) )
Line 4,901: Line 4,901:
((= "+" X) (term))
((= "+" X) (term))
((= "-" X) (list '- (term)))
((= "-" X) (list '- (term)))
((= "(" X) (prog1 (aggregate) (pop '*L)))) ) )</lang>
((= "(" X) (prog1 (aggregate) (pop '*L)))) ) )</syntaxhighlight>
{{out}}
{{out}}
<lang PicoLisp>: (ast "1+2+3*-4/(1+2)")
<syntaxhighlight lang=PicoLisp>: (ast "1+2+3*-4/(1+2)")
-> (+ (+ 1 2) (/ (* 3 (- 4)) (+ 1 2)))
-> (+ (+ 1 2) (/ (* 3 (- 4)) (+ 1 2)))


: (ast "(1+2+3)*-4/(1+2)")
: (ast "(1+2+3)*-4/(1+2)")
-> (/ (* (+ (+ 1 2) 3) (- 4)) (+ 1 2))</lang>
-> (/ (* (+ (+ 1 2) 3) (- 4)) (+ 1 2))</syntaxhighlight>


=={{header|Pop11}}==
=={{header|Pop11}}==


<lang pop11>/* Scanner routines */
<syntaxhighlight lang=pop11>/* Scanner routines */
/* Uncomment the following to parse data from standard input
/* Uncomment the following to parse data from standard input


Line 5,059: Line 5,059:


;;; Test it
;;; Test it
arith_eval(do_expr()) =></lang>
arith_eval(do_expr()) =></syntaxhighlight>


=={{header|Prolog}}==
=={{header|Prolog}}==
{{works with|SWI Prolog 8.1.19}}
{{works with|SWI Prolog 8.1.19}}
<lang prolog>% Lexer
<syntaxhighlight lang=prolog>% Lexer
numeric(X) :- 48 =< X, X =< 57.
numeric(X) :- 48 =< X, X =< 57.
not_numeric(X) :- 48 > X ; X > 57.
not_numeric(X) :- 48 > X ; X > 57.
Line 5,113: Line 5,113:
% Example use
% Example use
% calculator("(3+50)*7-9", X).</lang>
% calculator("(3+50)*7-9", X).</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
Line 5,119: Line 5,119:
<br>A subsequent example uses Pythons' ast module to generate the abstract syntax tree.
<br>A subsequent example uses Pythons' ast module to generate the abstract syntax tree.


<lang python>import operator
<syntaxhighlight lang=python>import operator


class AstNode(object):
class AstNode(object):
Line 5,234: Line 5,234:
expr = raw_input("Expression:")
expr = raw_input("Expression:")
astTree = Lex( expr, Yaccer())
astTree = Lex( expr, Yaccer())
print expr, '=',astTree.eval()</lang>
print expr, '=',astTree.eval()</syntaxhighlight>


===ast standard library module===
===ast standard library module===
Python comes with its own [http://docs.python.org/3.1/library/ast.html#module-ast ast] module as part of its standard libraries. The module compiles Python source into an AST tree that can in turn be compiled to bytecode then executed.
Python comes with its own [http://docs.python.org/3.1/library/ast.html#module-ast ast] module as part of its standard libraries. The module compiles Python source into an AST tree that can in turn be compiled to bytecode then executed.
<lang python>>>> import ast
<syntaxhighlight lang=python>>>> import ast
>>>
>>>
>>> expr="2 * (3 -1) + 2 * 5"
>>> expr="2 * (3 -1) + 2 * 5"
Line 5,261: Line 5,261:
>>> code_object = compile(node, filename='<string>', mode='eval')
>>> code_object = compile(node, filename='<string>', mode='eval')
>>> eval(code_object)
>>> eval(code_object)
16</lang>
16</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==


<lang racket>#lang racket
<syntaxhighlight lang=racket>#lang racket


(require parser-tools/yacc
(require parser-tools/yacc
Line 5,300: Line 5,300:
(displayln (parse (λ () (lex i)))))
(displayln (parse (λ () (lex i)))))


(calc "(1 + 2 * 3) - (1+2)*-3")</lang>
(calc "(1 + 2 * 3) - (1+2)*-3")</syntaxhighlight>


=={{header|Raku}}==
=={{header|Raku}}==
Line 5,306: Line 5,306:
{{Works with|rakudo|2018.03}}
{{Works with|rakudo|2018.03}}


<lang perl6>sub ev (Str $s --> Numeric) {
<syntaxhighlight lang=perl6>sub ev (Str $s --> Numeric) {


grammar expr {
grammar expr {
Line 5,349: Line 5,349:
say ev '1 + 2 - 3 * 4 / 5'; # 0.6
say ev '1 + 2 - 3 * 4 / 5'; # 0.6
say ev '1 + 5*3.4 - .5 -4 / -2 * (3+4) -6'; # 25.5
say ev '1 + 5*3.4 - .5 -4 / -2 * (3+4) -6'; # 25.5
say ev '((11+15)*15)* 2 + (3) * -4 *1'; # 768</lang>
say ev '((11+15)*15)* 2 + (3) * -4 *1'; # 768</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
Line 5,366: Line 5,366:
:::* &nbsp; 12.3D+44 &nbsp; &nbsp; &nbsp; ("double" precision)
:::* &nbsp; 12.3D+44 &nbsp; &nbsp; &nbsp; ("double" precision)
:::* &nbsp; 12.3Q+44 &nbsp; &nbsp; &nbsp; ("extended" or "quad" precision)
:::* &nbsp; 12.3Q+44 &nbsp; &nbsp; &nbsp; ("extended" or "quad" precision)
<lang rexx>/*REXX program evaluates an infix─type arithmetic expression and displays the result.*/
<syntaxhighlight lang=rexx>/*REXX program evaluates an infix─type arithmetic expression and displays the result.*/
nchars = '0123456789.eEdDqQ' /*possible parts of a number, sans ± */
nchars = '0123456789.eEdDqQ' /*possible parts of a number, sans ± */
e='***error***'; $=" "; doubleOps= '&|*/'; z= /*handy─dandy variables.*/
e='***error***'; $=" "; doubleOps= '&|*/'; z= /*handy─dandy variables.*/
Line 5,481: Line 5,481:
return substr(x, Nj, 1) /* [↑] ignore any blanks in expression*/
return substr(x, Nj, 1) /* [↑] ignore any blanks in expression*/
end /*Nj*/
end /*Nj*/
return $ /*reached end-of-tokens, return $. */</lang>
return $ /*reached end-of-tokens, return $. */</syntaxhighlight>
To view a version of the above REXX program, see this version which has much more whitespace: &nbsp; ──► &nbsp; [[Arithmetic_evaluation/REXX]]. <br>
To view a version of the above REXX program, see this version which has much more whitespace: &nbsp; ──► &nbsp; [[Arithmetic_evaluation/REXX]]. <br>
<br>
<br>
Line 5,492: Line 5,492:
=={{header|Ruby}}==
=={{header|Ruby}}==
Function to convert infix arithmetic expression to binary tree. The resulting tree knows how to print and evaluate itself. Assumes expression is well-formed (matched parens, all operators have 2 operands). Algorithm: http://www.seas.gwu.edu/~csci131/fall96/exp_to_tree.html
Function to convert infix arithmetic expression to binary tree. The resulting tree knows how to print and evaluate itself. Assumes expression is well-formed (matched parens, all operators have 2 operands). Algorithm: http://www.seas.gwu.edu/~csci131/fall96/exp_to_tree.html
<lang ruby>$op_priority = {"+" => 0, "-" => 0, "*" => 1, "/" => 1}
<syntaxhighlight lang=ruby>$op_priority = {"+" => 0, "-" => 0, "*" => 1, "/" => 1}


class TreeNode
class TreeNode
Line 5,591: Line 5,591:
node_stack.last
node_stack.last
end</lang>
end</syntaxhighlight>
Testing:
Testing:
<lang ruby>exp = "1 + 2 - 3 * (4 / 6)"
<syntaxhighlight lang=ruby>exp = "1 + 2 - 3 * (4 / 6)"
puts("Original: " + exp)
puts("Original: " + exp)


Line 5,600: Line 5,600:
puts("Infix: " + tree.to_s(:infix))
puts("Infix: " + tree.to_s(:infix))
puts("Postfix: " + tree.to_s(:postfix))
puts("Postfix: " + tree.to_s(:postfix))
puts("Result: " + tree.eval.to_s)</lang>
puts("Result: " + tree.eval.to_s)</syntaxhighlight>
{{out}}
{{out}}
<pre>Original: 1 + 2 - 3 * (4 / 6)
<pre>Original: 1 + 2 - 3 * (4 / 6)
Line 5,609: Line 5,609:


=={{header|Rust}}==
=={{header|Rust}}==
<lang rust>//! Simple calculator parser and evaluator
<syntaxhighlight lang=rust>//! Simple calculator parser and evaluator




Line 5,782: Line 5,782:
}
}


</syntaxhighlight>
</lang>


=={{header|Scala}}==
=={{header|Scala}}==
Line 5,788: Line 5,788:
is practically non-existent, to avoid obscuring the code.
is practically non-existent, to avoid obscuring the code.


<lang scala>
<syntaxhighlight lang=scala>
package org.rosetta.arithmetic_evaluator.scala
package org.rosetta.arithmetic_evaluator.scala


Line 5,835: Line 5,835:
}
}
}
}
</syntaxhighlight>
</lang>


Example:
Example:
Line 5,864: Line 5,864:
The parse function uses a recursive-descent parser to follow the precedence rules.
The parse function uses a recursive-descent parser to follow the precedence rules.


<lang scheme>
<syntaxhighlight lang=scheme>
(import (scheme base)
(import (scheme base)
(scheme char)
(scheme char)
Line 5,960: Line 5,960:
(newline))
(newline))
'("1 + 2" "20+4*5" "1/2+5*(6-3)" "(1+3)/4-1" "(1 - 5) * 2 / (20 + 1)"))
'("1 + 2" "20+4*5" "1/2+5*(6-3)" "(1+3)/4-1" "(1 - 5) * 2 / (20 + 1)"))
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 5,974: Line 5,974:
=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|JavaScript}}
{{trans|JavaScript}}
<lang ruby>func evalArithmeticExp(s) {
<syntaxhighlight lang=ruby>func evalArithmeticExp(s) {


func evalExp(s) {
func evalExp(s) {
Line 6,029: Line 6,029:


return Number(evalExp(s))
return Number(evalExp(s))
}</lang>
}</syntaxhighlight>


Testing the function:
Testing the function:
<lang ruby>for expr,res in [
<syntaxhighlight lang=ruby>for expr,res in [
['2+3' => 5],
['2+3' => 5],
['-4-3' => -7],
['-4-3' => -7],
Line 6,044: Line 6,044:
assert_eq(num, res)
assert_eq(num, res)
"%-45s == %10g\n".printf(expr, num)
"%-45s == %10g\n".printf(expr, num)
}</lang>
}</syntaxhighlight>


=={{header|Standard ML}}==
=={{header|Standard ML}}==
This implementation uses a [https://en.wikipedia.org/wiki/Recursive_descent_parser recursive descent parser]. It first lexes the input. The parser builds a Abstract Syntax Tree (AST) and the evaluator evaluates it. The parser uses sub categories.
This implementation uses a [https://en.wikipedia.org/wiki/Recursive_descent_parser recursive descent parser]. It first lexes the input. The parser builds a Abstract Syntax Tree (AST) and the evaluator evaluates it. The parser uses sub categories.
The parsing is a little bit tricky because the grammar is left recursive.
The parsing is a little bit tricky because the grammar is left recursive.
<lang sml>(* AST *)
<syntaxhighlight lang=sml>(* AST *)
datatype expression =
datatype expression =
Con of int (* constant *)
Con of int (* constant *)
Line 6,117: Line 6,117:
case parseE (lex (explode str)) of
case parseE (lex (explode str)) of
(exp, nil) => eval exp
(exp, nil) => eval exp
| _ => raise Error "not parseable stuff at the end"</lang>
| _ => raise Error "not parseable stuff at the end"</syntaxhighlight>


=={{header|Tailspin}}==
=={{header|Tailspin}}==
<lang tailspin>
<syntaxhighlight lang=tailspin>
def ops: ['+','-','*','/'];
def ops: ['+','-','*','/'];


Line 6,147: Line 6,147:
'$ast -> evaluateArithmetic;
'$ast -> evaluateArithmetic;
' -> !OUT::write
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 6,155: Line 6,155:


If we don't need to get the AST, we could just evaluate right away:
If we don't need to get the AST, we could just evaluate right away:
<lang tailspin>
<syntaxhighlight lang=tailspin>
composer calculator
composer calculator
(<WS>?) <addition|multiplication|term> (<WS>?)
(<WS>?) <addition|multiplication|term> (<WS>?)
Line 6,173: Line 6,173:
'
'
' -> !OUT::write
' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>16</pre>
<pre>16</pre>
Line 6,182: Line 6,182:
in a form that it can be immediately eval-led,
in a form that it can be immediately eval-led,
using Tcl's prefix operators.
using Tcl's prefix operators.
<lang Tcl>namespace import tcl::mathop::*
<syntaxhighlight lang=Tcl>namespace import tcl::mathop::*


proc ast str {
proc ast str {
Line 6,225: Line 6,225:
} \n] {
} \n] {
puts "$test ..... [eval $test] ..... [eval [eval $test]]"
puts "$test ..... [eval $test] ..... [eval [eval $test]]"
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 6,241: Line 6,241:
Use TXR text pattern matching to parse expression to a Lisp AST, then evaluate with <code>eval</code>:
Use TXR text pattern matching to parse expression to a Lisp AST, then evaluate with <code>eval</code>:


<lang txr>@(next :args)
<syntaxhighlight lang=txr>@(next :args)
@(define space)@/ */@(end)
@(define space)@/ */@(end)
@(define mulop (nod))@\
@(define mulop (nod))@\
Line 6,293: Line 6,293:
erroneous suffix "@bad"
erroneous suffix "@bad"
@ (end)
@ (end)
@(end)</lang>
@(end)</syntaxhighlight>


Run:
Run:
Line 6,307: Line 6,307:
=={{header|Ursala}}==
=={{header|Ursala}}==
with no error checking other than removal of spaces
with no error checking other than removal of spaces
<lang Ursala>#import std
<syntaxhighlight lang=Ursala>#import std
#import nat
#import nat
#import flo
#import flo
Line 6,324: Line 6,324:
traverse = *^ ~&v?\%ep ^H\~&vhthPX '+-*/'-$<plus,minus,times,div>@dh
traverse = *^ ~&v?\%ep ^H\~&vhthPX '+-*/'-$<plus,minus,times,div>@dh


evaluate = traverse+ parse+ lex</lang>
evaluate = traverse+ parse+ lex</syntaxhighlight>


test program:
test program:
<lang Ursala>#cast %eL
<syntaxhighlight lang=Ursala>#cast %eL


test = evaluate*t
test = evaluate*t
Line 6,343: Line 6,343:
5-3*2
5-3*2
(1+1)*(2+3)
(1+1)*(2+3)
(2-4)/(3+5*(8-1))]-</lang>
(2-4)/(3+5*(8-1))]-</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 6,363: Line 6,363:
{{trans|Kotlin}}
{{trans|Kotlin}}
{{libheader|Wren-pattern}}
{{libheader|Wren-pattern}}
<lang ecmascript>import "/pattern" for Pattern
<syntaxhighlight lang=ecmascript>import "/pattern" for Pattern


/* if string is empty, returns zero */
/* if string is empty, returns zero */
Line 6,452: Line 6,452:
"1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10",
"1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10",
"1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1"
"1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1"
].each { |s| System.print("%(s) = %(evalArithmeticExp.call(s))") }</lang>
].each { |s| System.print("%(s) = %(evalArithmeticExp.call(s))") }</syntaxhighlight>


{{out}}
{{out}}
Line 6,470: Line 6,470:
=={{header|zkl}}==
=={{header|zkl}}==
In zkl, the compiler stack is part of the language and is written in zkl so ...
In zkl, the compiler stack is part of the language and is written in zkl so ...
<lang zkl>Compiler.Parser.parseText("(1+3)*7").dump();
<syntaxhighlight lang=zkl>Compiler.Parser.parseText("(1+3)*7").dump();
Compiler.Parser.parseText("1+3*7").dump();</lang>
Compiler.Parser.parseText("1+3*7").dump();</syntaxhighlight>
The ASTs look like
The ASTs look like
{{out}}
{{out}}
Line 6,493: Line 6,493:
</pre>
</pre>
Evaluating them is just moving up the stack:
Evaluating them is just moving up the stack:
<lang zkl>Compiler.Compiler.compileText("(1+3)*7").__constructor(); vm.regX;
<syntaxhighlight lang=zkl>Compiler.Compiler.compileText("(1+3)*7").__constructor(); vm.regX;
Compiler.Compiler.compileText("1+3*7").__constructor(); vm.regX;</lang>
Compiler.Compiler.compileText("1+3*7").__constructor(); vm.regX;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 6,502: Line 6,502:


=={{header|ZX Spectrum Basic}}==
=={{header|ZX Spectrum Basic}}==
<lang zxbasic>10 PRINT "Use integer numbers and signs"'"+ - * / ( )"''
<syntaxhighlight lang=zxbasic>10 PRINT "Use integer numbers and signs"'"+ - * / ( )"''
20 LET s$="": REM last symbol
20 LET s$="": REM last symbol
30 LET pc=0: REM parenthesis counter
30 LET pc=0: REM parenthesis counter
Line 6,533: Line 6,533:
300 PRINT FLASH 1;"Invalid symbol ";c$;" detected in pos ";n: BEEP 1,-25
300 PRINT FLASH 1;"Invalid symbol ";c$;" detected in pos ";n: BEEP 1,-25
310 STOP
310 STOP
</syntaxhighlight>
</lang>