Arithmetic evaluation: Difference between revisions

Content added Content deleted
Line 1,183: Line 1,183:


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 3.4 :
ELENA 4.x :
<lang elena>import system'routines.
<lang elena>import system'routines;
import extensions.
import extensions;
import extensions'text.
import extensions'text;


class Token
class Token
{
{
object theValue.
object theValue;
int rprop level :: theLevel.
rprop int Level;
constructor new(int aLevel)
constructor new(int level)
[
{
theValue := StringWriter new.
theValue := new StringWriter();
theLevel := aLevel + 9.
Level := level + 9;
]
}
append : aChar
append(ch)
[
{
theValue << aChar.
theValue.write(ch)
]
}
number = theValue toReal.
Number = theValue.toReal();
}
}


class Node
class Node
{
{
object prop left :: theLeft.
prop object Left;
object prop right :: theRight.
prop object Right;
int rprop level :: theLevel.
rprop int Level;


constructor new(int aLevel)
constructor new(int level)
[
{
theLevel := aLevel.
Level := level
]
}
}
}


class SummaryNode :: Node
class SummaryNode : Node
{
{
constructor new(int aLevel)
constructor new(int level)
<= new(aLevel + 1).
<= new(level + 1);
number = theLeft number + theRight number.
Number = Left.Number + Right.Number;
}
}


class DifferenceNode :: Node
class DifferenceNode : Node
{
{
constructor new(int aLevel)
constructor new(int level)
<= new(aLevel + 1).
<= new(level + 1);
number = theLeft number - theRight number.
Number = Left.Number - Right.Number;
}
}


class ProductNode :: Node
class ProductNode : Node
{
{
constructor new(int aLevel)
constructor new(int level)
<= new(aLevel + 2).
<= new(level + 2);
number = theLeft number * theRight number.
Number = Left.Number * Right.Number;
}
}


class FractionNode :: Node
class FractionNode : Node
{
{
constructor new(int aLevel)
constructor new(int level)
<= new(aLevel + 2).
<= new(level + 2);
number = theLeft number / theRight number.
Number = Left.Number / Right.Number;
}
}


class Expression
class Expression
{
{
int rprop level :: theLevel.
rprop int Level;
object prop top :: theTop.
prop object Top;
constructor new(int aLevel)
constructor new(int level)
[
{
theLevel := aLevel
Level := level
]
}
right = theTop.
prop object Right
{

set right:aNode [ theTop := aNode ]
get() = Top;
set(object node)
{
Top := node
}
}
number => theTop.
get Number() => Top;
}
}


Line 1,272: Line 1,278:
{
{
eval(ch)
eval(ch)
[
{
ch =>
ch =>
$40 [ // (
$40 { // (
^ target newBracket; gotoStarting
^ __target.newBracket().gotoStarting()
];
}
! [
: {
^ target newToken; append:ch; gotoToken
^ __target.newToken().append(ch).gotoToken()
].
}
]
}
}
}


Line 1,286: Line 1,292:
{
{
eval(ch)
eval(ch)
[
{
ch =>
ch =>
$41 [ // )
$41 { // )
^ target closeBracket; gotoToken
^ __target.closeBracket().gotoToken()
];
}
$42 [ // *
$42 { // *
^ target newProduct; gotoOperator
^ __target.newProduct().gotoOperator()
];
}
$43 [ // +
$43 { // +
^ target newSummary; gotoOperator
^ __target.newSummary().gotoOperator()
];
}
$45 [ // -
$45 { // -
^ target newDifference; gotoOperator
^ __target.newDifference().gotoOperator()
];
}
$47 [ // /
$47 { // /
^ target newFraction; gotoOperator
^ __target.newFraction().gotoOperator()
];
}
! [
: {
^ target append:ch
^ __target.append:ch
].
}
]
}
}
}


Line 1,312: Line 1,318:
{
{
eval(ch)
eval(ch)
[
{
ch =>
ch =>
$40 [ // (
$40 { // (
^ target newBracket; gotoStarting
^ __target.newBracket().gotoStarting()
];
}
$45 [ // -
$45 { // -
^ target newToken; append:"0"; newDifference; gotoOperator
^ __target.newToken().append("0").newDifference().gotoOperator()
];
}
! [
: {
^ target newToken; append:ch; gotoToken
^ __target.newToken().append:ch.gotoToken()
].
}
]
}
}
}


class Scope
class Scope
{
{
object theState.
object theState;
int theLevel.
int theLevel;
object theParser.
object theParser;
object theToken.
object theToken;
object theExpression.
object theExpression;
constructor new:aParser
constructor new(parser)
[
{
theState := startState.
theState := startState;
theLevel := 0.
theLevel := 0;
theExpression := Expression new(0).
theExpression := Expression.new(0);
theParser := aParser.
theParser := parser
]
}
newToken
newToken()
[
{
theToken := theParser appendToken(theExpression, theLevel).
theToken := theParser.appendToken(theExpression, theLevel)
]
}
newSummary
newSummary()
[
{
theToken := nil.
theToken := nil;
theParser appendSummary(theExpression, theLevel).
theParser.appendSummary(theExpression, theLevel)
]
}
newDifference
newDifference()
[
{
theToken := nil.
theToken := nil;
theParser appendDifference(theExpression, theLevel)
theParser.appendDifference(theExpression, theLevel)
]
}
newProduct
newProduct()
[
{
theToken := nil.
theToken := nil;
theParser appendProduct(theExpression, theLevel)
theParser.appendProduct(theExpression, theLevel)
]
}
newFraction
newFraction()
[
{
theToken := nil.
theToken := nil;
theParser appendFraction(theExpression, theLevel)
theParser.appendFraction(theExpression, theLevel)
]
}


newBracket
newBracket()
[
{
theToken := nil.
theToken := nil;
theLevel := theLevel + 10.
theLevel := theLevel + 10;
theParser appendSubexpression(theExpression, theLevel).
theParser.appendSubexpression(theExpression, theLevel)
]
}


closeBracket
closeBracket()
[
{
if (theLevel < 10)
if (theLevel < 10)
[ InvalidArgumentException new:"Invalid expression"; raise ].
{ InvalidArgumentException.new:"Invalid expression".raise() };
theLevel := theLevel - 10
theLevel := theLevel - 10
]
}
append:ch
append(ch)
[
{
if((ch >= $48) && (ch < $58))
if(ch >= $48 && ch < $58)
[ theToken append:ch ];
{
theToken.append:ch
[ InvalidArgumentException new:"Invalid expression"; raise ]
]
}
else
{
InvalidArgumentException.new:"Invalid expression".raise()
}
}
append(literal aLiteral)
append(string s)
[
{
aLiteral forEach(:ch)[ self append:ch ]
s.forEach:(ch){ self.append:ch }
]
}
gotoStarting
gotoStarting()
[
{
theState := startState
theState := startState
]
}
gotoToken
gotoToken()
[
{
theState := tokenState
theState := tokenState
]
}
gotoOperator
gotoOperator()
[
{
theState := operatorState
theState := operatorState
]
}
number => theExpression.
get Number() => theExpression;
dispatch => theState.
dispatch() => theState;
}
}


class Parser
class Parser
{
{
appendToken(object anExpression, int aLevel)
appendToken(object expression, int level)
[
{
var aToken := Token new(aLevel).
var token := Token.new(level);
anExpression top := self append(anExpression top, aToken).
expression.Top := self.append(expression.Top, token);
^ aToken
^ token
]
}


appendSummary(object anExpression, int aLevel)
appendSummary(object expression, int level)
[
{
anExpression top := self append(anExpression top, SummaryNode new(aLevel)).
expression.Top := self.append(expression.Top, SummaryNode.new(level))
]
}


appendDifference(object anExpression, int aLevel)
appendDifference(object expression, int level)
[
{
anExpression top := self append(anExpression top, DifferenceNode new(aLevel)).
expression.Top := self.append(expression.Top, DifferenceNode.new(level))
]
}


appendProduct(object anExpression, int aLevel)
appendProduct(object expression, int level)
[
{
anExpression top := self append(anExpression top, ProductNode new(aLevel)).
expression.Top := self.append(expression.Top, ProductNode.new(level))
]
}


appendFraction(object anExpression, int aLevel)
appendFraction(object expression, int level)
[
{
anExpression top := self append(anExpression top, FractionNode new(aLevel))
expression.Top := self.append(expression.Top, FractionNode.new(level))
]
}


appendSubexpression(object anExpression, int aLevel)
appendSubexpression(object expression, int level)
[
{
anExpression top := self append(anExpression top, Expression new(aLevel)).
expression.Top := self.append(expression.Top, Expression.new(level))
]
}


append(object aLastNode, object aNewNode)
append(object lastNode, object newNode)
[
{
if(nil == aLastNode)
if(nil == lastNode)
[ ^ aNewNode ].
{ ^ newNode };
if (aNewNode level <= aLastNode level)
if (newNode.Level <= lastNode.Level)
[ aNewNode left := aLastNode. ^ aNewNode ].
{ newNode.Left := lastNode; ^ newNode };
var aParent := aLastNode.
var parent := lastNode;
var aCurrent := aLastNode right.
var current := lastNode.Right;
while ((nil != aCurrent) && (aNewNode level > aCurrent level))
while (nil != current && newNode.Level > current.Level)
[ aParent := aCurrent. aCurrent := aCurrent right. ].
{ parent := current; current := current.Right };
if (nil == aCurrent)
if (nil == current)
[ aParent right := aNewNode. ];
{
[ aNewNode left := aCurrent. aParent right := aNewNode ].
parent.Right := newNode
}
else
{
newNode.Left := current; parent.Right := newNode
};
^ aLastNode
^ lastNode
]
}
run : aText
run(text)
[
{
var aScope := Scope new(self).
var scope := Scope.new(self);


aText forEach(:ch)[ aScope eval:ch ].
text.forEach:(ch){ scope.eval:ch };


^ aScope number
^ scope.Number
]
}
}
}


public program
public program()
{
[
var aText := StringWriter new.
var text := new StringWriter();
var aParser := Parser new.
var parser := new Parser();


$(console readLine; saveTo:aText; length > 0) doWhile:
while (console.readLine().saveTo(text).Length > 0)
[
{
try(console printLine("=",aParser run:aText))
try
{
{
on(Exception e)
console.printLine("=",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}}==
=={{header|Emacs Lisp}}==