Arithmetic evaluation: Difference between revisions

m
Line 1,185:
 
=={{header|Elena}}==
ELENA 45.x0 :
<lang elena>import system'routines;
import extensions;
import extensions'text;
 
class Token
{
object theValue;
rprop int Level;
constructor new(int level)
{
Line 1,201:
Level := level + 9;
}
append(ch)
{
theValue.write(ch)
}
Number = theValue.toReal();
}
 
class Node
{
Line 1,215:
prop object Right;
rprop int Level;
 
constructor new(int level)
{
Line 1,221:
}
}
 
class SummaryNode : Node
{
constructor new(int level)
<= new(level + 1);
Number = Left.Number + Right.Number;
}
 
class DifferenceNode : Node
{
constructor new(int level)
<= new(level + 1);
Number = Left.Number - Right.Number;
}
 
class ProductNode : Node
{
constructor new(int level)
<= new(level + 2);
Number = Left.Number * Right.Number;
}
 
class FractionNode : Node
{
constructor new(int level)
<= new(level + 2);
Number = Left.Number / Right.Number;
}
 
class Expression
{
rprop int Level;
prop object Top;
constructor new(int level)
{
Level := level
}
prop object Right
{
get() = Top;
set(object node)
{
Line 1,273:
}
}
get Number() => Top;
}
 
singleton operatorState
{
Line 1,290:
}
}
 
singleton tokenState
{
Line 1,316:
}
}
 
singleton startState
{
Line 1,333:
}
}
 
class Scope
{
Line 1,341:
object theToken;
object theExpression;
constructor new(parser)
{
Line 1,349:
theParser := parser
}
newToken()
{
theToken := theParser.appendToken(theExpression, theLevel)
}
newSummary()
{
theToken := nil;
theParser.appendSummary(theExpression, theLevel)
}
newDifference()
{
theToken := nil;
theParser.appendDifference(theExpression, theLevel)
}
newProduct()
{
theToken := nil;
theParser.appendProduct(theExpression, theLevel)
}
newFraction()
{
theToken := nil;
theParser.appendFraction(theExpression, theLevel)
}
 
newBracket()
{
theToken := nil;
theLevel := theLevel + 10;
theParser.appendSubexpression(theExpression, theLevel)
}
 
closeBracket()
{
if (theLevel < 10)
{ InvalidArgumentException.new:"Invalid expression".raise() };
theLevel := theLevel - 10
}
append(ch)
{
Line 1,411:
}
}
append(string s)
{
s.forEach:(ch){ self.append:ch }
}
gotoStarting()
{
theState := startState
}
gotoToken()
{
theState := tokenState
}
gotoOperator()
{
theState := operatorState
}
get Number() => theExpression;
dispatch() => theState;
}
 
class Parser
{
Line 1,442:
{
var token := Token.new(level);
expression.Top := self.append(expression.Top, token);
^ token
}
 
appendSummary(object expression, int level)
{
expression.Top := self.append(expression.Top, SummaryNode.new(level))
}
 
appendDifference(object expression, int level)
{
expression.Top := self.append(expression.Top, DifferenceNode.new(level))
}
 
appendProduct(object expression, int level)
{
expression.Top := self.append(expression.Top, ProductNode.new(level))
}
 
appendFraction(object expression, int level)
{
expression.Top := self.append(expression.Top, FractionNode.new(level))
}
 
appendSubexpression(object expression, int level)
{
expression.Top := self.append(expression.Top, Expression.new(level))
}
 
append(object lastNode, object newNode)
{
if(nil == lastNode)
{ ^ newNode };
if (newNode.Level <= lastNode.Level)
{ newNode.Left := lastNode; ^ newNode };
var parent := lastNode;
var current := lastNode.Right;
while (nil != current && newNode.Level > current.Level)
{ parent := current; current := current.Right };
if (nil == current)
{
Line 1,494:
newNode.Left := current; parent.Right := newNode
};
^ lastNode
}
run(text)
{
var scope := Scope.new(self);
 
text.forEach:(ch){ scope.eval:ch };
 
^ scope.Number
}
}
 
public program()
{
var text := new StringWriter();
var parser := new Parser();
 
while (console.readLine().saveTo(text).Length > 0)
{
Line 1,521:
catch(Exception e)
{
console.writeLine(e.Printable):"Invalid Expression"
//console.writeLine:"Invalid Expression"
};
text.clear()
}
Anonymous user