Arithmetic evaluation: Difference between revisions

no edit summary
(added F#)
No edit summary
Line 871:
? arithEvaluate("(1 + 2 / 2) * (5 + 5)")
# value: 20.0</lang>
 
=={{header|Elena}}==
<lang elena>#define basic'* = std'basic'*.
#define ctrl'* = std'patterns'*.
#define io'* = ext'io'*.
 
#subject parse_order.
 
#class Token
{
#field theValue.
#method parse_order'get = 0.
#method += aChar
[
theValue += aChar.
]
#method + aNode
[
^ aNode += self.
]
#method new
[
theValue := basic'String.
]
#method real'get = basic'RealType evaluate:theValue.
}
 
#class Node
{
#field theLeft.
#field theRight.
#role Empty
{
#method += aNode
[
theLeft := aNode.
$self $setLeftAssigned.
]
}
#role LeftAssigned
{
#method += aNode
[
theRight := aNode.
#shift.
]
}
#method $setLeftAssigned
[
#shift LeftAssigned.
]
#method + aNode
[
#if (self parse_order > aNode parse_order)?
[
self += aNode.
]
| [
aNode += self.
^ aNode.
].
]
#method += aNode
[
#if (theRight parse_order > aNode parse_order)?
[
theRight += aNode.
]
| [
theRight := aNode += theRight.
].
]
#method new
[
#shift Empty.
]
}
 
#class SummaryNode (Node)
{
#method parse_order'get = 2.
#method real'get = theLeft real'get + theRight real'get.
}
 
#class DifferenceNode (Node)
{
#method parse_order'get = 2.
#method real'get = theLeft real'get - theRight real'get.
}
 
#class ProductNode (Node)
{
#method parse_order'get = 1.
#method real'get = theLeft real'get * theRight real'get.
}
 
#class FractionNode (Node)
{
#method parse_order'get = 1.
#method real'get = theLeft real'get / theRight real'get.
}
 
#class SubExpression
{
#field theParser.
#field theCounter.
#role EOF
{
#method eof'is []
#method += aChar [ $self fail. ]
}
#method parse_order'get = 0.
#method + aNode
[
^ aNode += self.
]
#method += aChar
[
#if ctrl'Control if:(aChar == 41)
[
theCounter -= 1.
]
| if:(aChar == 40)
[
theCounter += 1.
].
#if(theCounter == 0)?
[ #shift EOF. ^ $self. ].
 
theParser evaluate:aChar.
]
#method real'get = theParser real.
#method new
[
theParser := arithmeval'Parser.
theCounter := basic'Integer << 1.
]
}
 
#class Parser
{
#field theToken.
#field theTopNode.
#role Start
{
#method evaluate : aChar
[
#if (aChar == 40)?
[
theToken := SubExpression.
theTopNode := theToken.
$self $setBrackets.
]
| [
theToken := Token.
theTopNode := theToken.
theToken += aChar.
#shift.
].
]
}
#role Operator
{
#method evaluate : aChar
[
#if ctrl'Control if:(aChar > 48) if:(aChar < 58)
[
theToken := (Token += aChar).
theTopNode += theToken.
]
| [ $self fail. ].
#shift.
]
}
#role Brackets
{
#method evaluate : aChar
[
theToken += aChar.
#if theToken eof'is
[
#shift.
].
]
}
#method real'get = theTopNode real.
#method evaluate : aChar
[
#if ctrl'Control if:(aChar > 48) if:(aChar < 58)
[
theToken += aChar.
]
| if:(aChar == 42) // *
[
theTopNode := theTopNode + ProductNode.
#shift Operator.
]
| if:(aChar == 47) // /
[
theTopNode := theTopNode + FractionNode.
#shift Operator.
]
| if:(aChar == 43) // +
[
theTopNode := theTopNode + SummaryNode.
#shift Operator.
]
| if:(aChar == 45) // -
[
theTopNode := theTopNode + DifferenceNode.
#shift Operator.
]
| if:(aChar == 40)
[
theToken := SubExpression.
theTopNode := theToken.
#shift Brackets.
]
| [ $self fail. ].
]
#method new
[
#shift Start.
]
#method $setBrackets
[
#shift Brackets.
]
}
 
#symbol Program =>
[
#var aText := basic'String.
#loop ((io'Console >> aText) length > 0)?
[
#var aParser := Parser.
io'Console << "=" << ctrl'Control do: =>
[
ctrl'Control run &literal:aText &foreach: aParser.
^ aParser real.
]
| back:"Invalid Expression".
io'Console << "%n".
].
].
</lang>
 
=={{header|Factor}}==
Anonymous user