Arithmetic evaluation: Difference between revisions
Content added Content deleted
(added F#) |
No edit summary |
||
Line 871: | Line 871: | ||
? arithEvaluate("(1 + 2 / 2) * (5 + 5)") |
? arithEvaluate("(1 + 2 / 2) * (5 + 5)") |
||
# value: 20.0</lang> |
# 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}}== |
=={{header|Factor}}== |