Arithmetic evaluation: Difference between revisions

m
Line 1,183:
 
=={{header|Elena}}==
ELENA 3.4.x :
<lang elena>import system'routines.;
import extensions.;
import extensions'text.;
 
class Token
{
object theValue.;
int rprop level ::int theLevel.Level;
constructor new(int aLevellevel)
[{
theValue := StringWriter new. StringWriter();
theLevelLevel := aLevellevel + 9.;
]}
append : aChar(ch)
[{
theValue << aChar.write(ch)
]}
numberNumber = theValue .toReal.();
}
 
class Node
{
object prop object left :: theLeft.Left;
object prop object right :: theRight.Right;
int rprop level ::int theLevel.Level;
 
constructor new(int aLevellevel)
[{
theLevelLevel := aLevel.level
]}
}
 
class SummaryNode :: Node
{
constructor new(int aLevellevel)
<= new(aLevellevel + 1).;
numberNumber = theLeft numberLeft.Number + theRight numberRight.Number;
}
 
class DifferenceNode :: Node
{
constructor new(int aLevellevel)
<= new(aLevellevel + 1).;
numberNumber = theLeft numberLeft.Number - theRight numberRight.Number;
}
 
class ProductNode :: Node
{
constructor new(int aLevellevel)
<= new(aLevellevel + 2).;
numberNumber = theLeft numberLeft.Number * theRight numberRight.Number;
}
 
class FractionNode :: Node
{
constructor new(int aLevellevel)
<= new(aLevellevel + 2).;
numberNumber = theLeft numberLeft.Number / theRight numberRight.Number;
}
 
class Expression
{
int rprop level ::int theLevel.Level;
object prop object top :: theTop.Top;
constructor new(int aLevellevel)
[{
theLevelLevel := aLevellevel
]}
rightprop =object theTop.Right
{
 
set right:aNode [ theTop :=get() aNode= ]Top;
aText clear
set(object node)
{
Top := node
}
}
numberget Number() => theTop.Top;
}
 
Line 1,272 ⟶ 1,278:
{
eval(ch)
[{
ch =>
$40 [{ // (
^ target __target.newBracket; ().gotoStarting()
];}
!: [{
^ target __target.newToken; ().append:(ch; ).gotoToken()
].}
]}
}
 
Line 1,286 ⟶ 1,292:
{
eval(ch)
[{
ch =>
$41 [{ // )
^ target __target.closeBracket; ().gotoToken()
];}
$42 [{ // *
^ target __target.newProduct; ().gotoOperator()
];}
$43 [{ // +
^ target __target.newSummary; ().gotoOperator()
];}
$45 [{ // -
^ target __target.newDifference; ().gotoOperator()
];}
$47 [{ // /
^ target __target.newFraction; ().gotoOperator()
];}
!: [{
^ target __target.append:ch
].}
]}
}
 
Line 1,312 ⟶ 1,318:
{
eval(ch)
[{
ch =>
$40 [{ // (
^ target __target.newBracket; ().gotoStarting()
];}
$45 [{ // -
^ target __target.newToken; ().append:("0"; ).newDifference; ().gotoOperator()
];}
!: [{
^ target __target.newToken; ().append:ch; .gotoToken()
].}
]}
}
 
class Scope
{
object theState.;
int theLevel.;
object theParser.;
object theToken.;
object theExpression.;
constructor new:aParser(parser)
[{
theState := startState.;
theLevel := 0.;
theExpression := Expression .new(0).;
theParser := aParser.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)
[{
if((ch >= $48) && (ch < $58))
{ [ theToken append:ch ];
theToken.append:ch
[ InvalidArgumentException new:"Invalid expression"; raise ]
] }
else
{
[ InvalidArgumentException .new:"Invalid expression"; .raise ]()
}
}
append(literalstring aLiterals)
[{
aLiteral s.forEach:(:ch)[{ self .append:ch ]}
]}
gotoStarting()
[{
theState := startState
]}
gotoToken()
[{
theState := tokenState
]}
gotoOperator()
[{
theState := operatorState
]}
numberget Number() => theExpression.;
dispatch() => theState.;
}
 
class Parser
{
appendToken(object anExpressionexpression, int aLevellevel)
[{
var aTokentoken := Token .new(aLevellevel).;
anExpression topexpression.Top := self .append(anExpression topexpression.Top, aTokentoken).;
^ aTokentoken
]}
 
appendSummary(object anExpressionexpression, int aLevellevel)
[{
anExpression topexpression.Top := self .append(anExpression topexpression.Top, SummaryNode .new(aLevellevel)).
]}
 
appendDifference(object anExpressionexpression, int aLevellevel)
[{
anExpression topexpression.Top := self .append(anExpression topexpression.Top, DifferenceNode .new(aLevellevel)).
]}
 
appendProduct(object anExpressionexpression, int aLevellevel)
[{
anExpression topexpression.Top := self .append(anExpression topexpression.Top, ProductNode .new(aLevellevel)).
]}
 
appendFraction(object anExpressionexpression, int aLevellevel)
[{
anExpression topexpression.Top := self .append(anExpression topexpression.Top, FractionNode .new(aLevellevel))
]}
 
appendSubexpression(object anExpressionexpression, int aLevellevel)
[{
anExpression topexpression.Top := self .append(anExpression topexpression.Top, Expression .new(aLevellevel)).
]}
 
append(object aLastNodelastNode, object aNewNodenewNode)
[{
if(nil == aLastNodelastNode)
[{ ^ aNewNodenewNode ].};
if (aNewNode levelnewNode.Level <= aLastNode levellastNode.Level)
[{ aNewNode leftnewNode.Left := aLastNode.lastNode; ^ aNewNodenewNode ].};
var aParentparent := aLastNode.lastNode;
var aCurrentcurrent := aLastNode rightlastNode.Right;
while ((nil != aCurrent)current && (aNewNode levelnewNode.Level > aCurrent level)current.Level)
[{ aParentparent := aCurrent.current; aCurrentcurrent := aCurrent rightcurrent.Right ].};
if (nil == aCurrentcurrent)
{ [ aParent right := aNewNode. ];
[ aNewNode left := aCurrentparent. aParent rightRight := aNewNodenewNode ].
}
else
{
newNode.Left := current; parent.Right := newNode
};
^ aLastNodelastNode
]}
run : aText(text)
[{
var aScopescope := Scope .new(self).;
 
aText text.forEach:(:ch)[ aScope{ scope.eval:ch ].};
 
^ aScope numberscope.Number
]}
}
 
public program()
{
[
var aTexttext := StringWriter new. StringWriter();
var aParserparser := Parser new. Parser();
 
$while (console .readLine; ().saveTo:aText; length(text).Length > 0) doWhile:
[{
try(console printLine("=",aParser run:aText))
{
onconsole.printLine(Exception e"=",parser.run:text)
[}
catch(Exception e)
console writeLine:"Invalid Expression"
]{
} console.writeLine(e.Printable)
//console .writeLine:"Invalid Expression"
aText clear
] };
]</lang>
text.clear()
}
]}</lang>
 
=={{header|Emacs Lisp}}==
Anonymous user