September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
|
|
@ -1,324 +1,343 @@
|
|||
import system'routines.
|
||||
import extensions.
|
||||
import extensions'text.
|
||||
import system'routines;
|
||||
import extensions;
|
||||
import extensions'text;
|
||||
|
||||
class Token
|
||||
{
|
||||
object theValue.
|
||||
object theValue;
|
||||
|
||||
int rprop level :: theLevel.
|
||||
rprop int Level;
|
||||
|
||||
constructor new(int aLevel)
|
||||
[
|
||||
theValue := StringWriter new.
|
||||
theLevel := aLevel + 9.
|
||||
]
|
||||
constructor new(int level)
|
||||
{
|
||||
theValue := new StringWriter();
|
||||
Level := level + 9;
|
||||
}
|
||||
|
||||
append : aChar
|
||||
[
|
||||
theValue << aChar.
|
||||
]
|
||||
append(ch)
|
||||
{
|
||||
theValue.write(ch)
|
||||
}
|
||||
|
||||
number = theValue toReal.
|
||||
Number = theValue.toReal();
|
||||
}
|
||||
|
||||
class Node
|
||||
{
|
||||
object prop left :: theLeft.
|
||||
object prop right :: theRight.
|
||||
int rprop level :: theLevel.
|
||||
prop object Left;
|
||||
prop object Right;
|
||||
rprop int Level;
|
||||
|
||||
constructor new(int aLevel)
|
||||
[
|
||||
theLevel := aLevel.
|
||||
]
|
||||
constructor new(int level)
|
||||
{
|
||||
Level := level
|
||||
}
|
||||
}
|
||||
|
||||
class SummaryNode :: Node
|
||||
class SummaryNode : Node
|
||||
{
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 1).
|
||||
constructor new(int level)
|
||||
<= new(level + 1);
|
||||
|
||||
number = theLeft number + theRight number.
|
||||
Number = Left.Number + Right.Number;
|
||||
}
|
||||
|
||||
class DifferenceNode :: Node
|
||||
class DifferenceNode : Node
|
||||
{
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 1).
|
||||
constructor new(int level)
|
||||
<= new(level + 1);
|
||||
|
||||
number = theLeft number - theRight number.
|
||||
Number = Left.Number - Right.Number;
|
||||
}
|
||||
|
||||
class ProductNode :: Node
|
||||
class ProductNode : Node
|
||||
{
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 2).
|
||||
constructor new(int level)
|
||||
<= new(level + 2);
|
||||
|
||||
number = theLeft number * theRight number.
|
||||
Number = Left.Number * Right.Number;
|
||||
}
|
||||
|
||||
class FractionNode :: Node
|
||||
class FractionNode : Node
|
||||
{
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 2).
|
||||
constructor new(int level)
|
||||
<= new(level + 2);
|
||||
|
||||
number = theLeft number / theRight number.
|
||||
Number = Left.Number / Right.Number;
|
||||
}
|
||||
|
||||
class Expression
|
||||
{
|
||||
int rprop level :: theLevel.
|
||||
object prop top :: theTop.
|
||||
rprop int Level;
|
||||
prop object Top;
|
||||
|
||||
constructor new(int aLevel)
|
||||
[
|
||||
theLevel := aLevel
|
||||
]
|
||||
constructor new(int level)
|
||||
{
|
||||
Level := level
|
||||
}
|
||||
|
||||
right = theTop.
|
||||
prop object Right
|
||||
{
|
||||
get() = Top;
|
||||
|
||||
set right:aNode [ theTop := aNode ]
|
||||
set(object node)
|
||||
{
|
||||
Top := node
|
||||
}
|
||||
}
|
||||
|
||||
number => theTop.
|
||||
get Number() => Top;
|
||||
}
|
||||
|
||||
singleton operatorState
|
||||
{
|
||||
eval(ch)
|
||||
[
|
||||
{
|
||||
ch =>
|
||||
$40 [ // (
|
||||
^ target newBracket; gotoStarting
|
||||
];
|
||||
! [
|
||||
^ target newToken; append:ch; gotoToken
|
||||
].
|
||||
]
|
||||
$40 { // (
|
||||
^ __target.newBracket().gotoStarting()
|
||||
}
|
||||
: {
|
||||
^ __target.newToken().append(ch).gotoToken()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
singleton tokenState
|
||||
{
|
||||
eval(ch)
|
||||
[
|
||||
{
|
||||
ch =>
|
||||
$41 [ // )
|
||||
^ target closeBracket; gotoToken
|
||||
];
|
||||
$42 [ // *
|
||||
^ target newProduct; gotoOperator
|
||||
];
|
||||
$43 [ // +
|
||||
^ target newSummary; gotoOperator
|
||||
];
|
||||
$45 [ // -
|
||||
^ target newDifference; gotoOperator
|
||||
];
|
||||
$47 [ // /
|
||||
^ target newFraction; gotoOperator
|
||||
];
|
||||
! [
|
||||
^ target append:ch
|
||||
].
|
||||
]
|
||||
$41 { // )
|
||||
^ __target.closeBracket().gotoToken()
|
||||
}
|
||||
$42 { // *
|
||||
^ __target.newProduct().gotoOperator()
|
||||
}
|
||||
$43 { // +
|
||||
^ __target.newSummary().gotoOperator()
|
||||
}
|
||||
$45 { // -
|
||||
^ __target.newDifference().gotoOperator()
|
||||
}
|
||||
$47 { // /
|
||||
^ __target.newFraction().gotoOperator()
|
||||
}
|
||||
: {
|
||||
^ __target.append:ch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
singleton startState
|
||||
{
|
||||
eval(ch)
|
||||
[
|
||||
{
|
||||
ch =>
|
||||
$40 [ // (
|
||||
^ target newBracket; gotoStarting
|
||||
];
|
||||
$45 [ // -
|
||||
^ target newToken; append:"0"; newDifference; gotoOperator
|
||||
];
|
||||
! [
|
||||
^ target newToken; append:ch; gotoToken
|
||||
].
|
||||
]
|
||||
$40 { // (
|
||||
^ __target.newBracket().gotoStarting()
|
||||
}
|
||||
$45 { // -
|
||||
^ __target.newToken().append("0").newDifference().gotoOperator()
|
||||
}
|
||||
: {
|
||||
^ __target.newToken().append:ch.gotoToken()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Scope
|
||||
{
|
||||
object theState.
|
||||
int theLevel.
|
||||
object theParser.
|
||||
object theToken.
|
||||
object theExpression.
|
||||
object theState;
|
||||
int theLevel;
|
||||
object theParser;
|
||||
object theToken;
|
||||
object theExpression;
|
||||
|
||||
constructor new:aParser
|
||||
[
|
||||
theState := startState.
|
||||
theLevel := 0.
|
||||
theExpression := Expression new(0).
|
||||
theParser := aParser.
|
||||
]
|
||||
constructor new(parser)
|
||||
{
|
||||
theState := startState;
|
||||
theLevel := 0;
|
||||
theExpression := Expression.new(0);
|
||||
theParser := parser
|
||||
}
|
||||
|
||||
newToken
|
||||
[
|
||||
theToken := theParser appendToken(theExpression, theLevel).
|
||||
]
|
||||
newToken()
|
||||
{
|
||||
theToken := theParser.appendToken(theExpression, theLevel)
|
||||
}
|
||||
|
||||
newSummary
|
||||
[
|
||||
theToken := nil.
|
||||
newSummary()
|
||||
{
|
||||
theToken := nil;
|
||||
|
||||
theParser appendSummary(theExpression, theLevel).
|
||||
]
|
||||
theParser.appendSummary(theExpression, theLevel)
|
||||
}
|
||||
|
||||
newDifference
|
||||
[
|
||||
theToken := nil.
|
||||
newDifference()
|
||||
{
|
||||
theToken := nil;
|
||||
|
||||
theParser appendDifference(theExpression, theLevel)
|
||||
]
|
||||
theParser.appendDifference(theExpression, theLevel)
|
||||
}
|
||||
|
||||
newProduct
|
||||
[
|
||||
theToken := nil.
|
||||
newProduct()
|
||||
{
|
||||
theToken := nil;
|
||||
|
||||
theParser appendProduct(theExpression, theLevel)
|
||||
]
|
||||
theParser.appendProduct(theExpression, theLevel)
|
||||
}
|
||||
|
||||
newFraction
|
||||
[
|
||||
theToken := nil.
|
||||
newFraction()
|
||||
{
|
||||
theToken := nil;
|
||||
|
||||
theParser appendFraction(theExpression, theLevel)
|
||||
]
|
||||
theParser.appendFraction(theExpression, theLevel)
|
||||
}
|
||||
|
||||
newBracket
|
||||
[
|
||||
theToken := nil.
|
||||
newBracket()
|
||||
{
|
||||
theToken := nil;
|
||||
|
||||
theLevel := theLevel + 10.
|
||||
theLevel := theLevel + 10;
|
||||
|
||||
theParser appendSubexpression(theExpression, theLevel).
|
||||
]
|
||||
theParser.appendSubexpression(theExpression, theLevel)
|
||||
}
|
||||
|
||||
closeBracket
|
||||
[
|
||||
closeBracket()
|
||||
{
|
||||
if (theLevel < 10)
|
||||
[ InvalidArgumentException new:"Invalid expression"; raise ].
|
||||
{ InvalidArgumentException.new:"Invalid expression".raise() };
|
||||
|
||||
theLevel := theLevel - 10
|
||||
]
|
||||
}
|
||||
|
||||
append:ch
|
||||
[
|
||||
if((ch >= $48) && (ch < $58))
|
||||
[ theToken append:ch ];
|
||||
[ InvalidArgumentException new:"Invalid expression"; raise ]
|
||||
]
|
||||
append(ch)
|
||||
{
|
||||
if(ch >= $48 && ch < $58)
|
||||
{
|
||||
theToken.append:ch
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidArgumentException.new:"Invalid expression".raise()
|
||||
}
|
||||
}
|
||||
|
||||
append(literal aLiteral)
|
||||
[
|
||||
aLiteral forEach(:ch)[ self append:ch ]
|
||||
]
|
||||
append(string s)
|
||||
{
|
||||
s.forEach:(ch){ self.append:ch }
|
||||
}
|
||||
|
||||
gotoStarting
|
||||
[
|
||||
gotoStarting()
|
||||
{
|
||||
theState := startState
|
||||
]
|
||||
}
|
||||
|
||||
gotoToken
|
||||
[
|
||||
gotoToken()
|
||||
{
|
||||
theState := tokenState
|
||||
]
|
||||
}
|
||||
|
||||
gotoOperator
|
||||
[
|
||||
gotoOperator()
|
||||
{
|
||||
theState := operatorState
|
||||
]
|
||||
}
|
||||
|
||||
number => theExpression.
|
||||
get Number() => theExpression;
|
||||
|
||||
dispatch => theState.
|
||||
dispatch() => theState;
|
||||
}
|
||||
|
||||
class Parser
|
||||
{
|
||||
appendToken(object anExpression, int aLevel)
|
||||
[
|
||||
var aToken := Token new(aLevel).
|
||||
appendToken(object expression, int level)
|
||||
{
|
||||
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)
|
||||
[
|
||||
anExpression top := self append(anExpression top, SummaryNode new(aLevel)).
|
||||
]
|
||||
appendSummary(object expression, int level)
|
||||
{
|
||||
expression.Top := self.append(expression.Top, SummaryNode.new(level))
|
||||
}
|
||||
|
||||
appendDifference(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression top := self append(anExpression top, DifferenceNode new(aLevel)).
|
||||
]
|
||||
appendDifference(object expression, int level)
|
||||
{
|
||||
expression.Top := self.append(expression.Top, DifferenceNode.new(level))
|
||||
}
|
||||
|
||||
appendProduct(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression top := self append(anExpression top, ProductNode new(aLevel)).
|
||||
]
|
||||
appendProduct(object expression, int level)
|
||||
{
|
||||
expression.Top := self.append(expression.Top, ProductNode.new(level))
|
||||
}
|
||||
|
||||
appendFraction(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression top := self append(anExpression top, FractionNode new(aLevel))
|
||||
]
|
||||
appendFraction(object expression, int level)
|
||||
{
|
||||
expression.Top := self.append(expression.Top, FractionNode.new(level))
|
||||
}
|
||||
|
||||
appendSubexpression(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression top := self append(anExpression top, Expression new(aLevel)).
|
||||
]
|
||||
appendSubexpression(object expression, int level)
|
||||
{
|
||||
expression.Top := self.append(expression.Top, Expression.new(level))
|
||||
}
|
||||
|
||||
append(object aLastNode, object aNewNode)
|
||||
[
|
||||
if(nil == aLastNode)
|
||||
[ ^ aNewNode ].
|
||||
append(object lastNode, object newNode)
|
||||
{
|
||||
if(nil == lastNode)
|
||||
{ ^ newNode };
|
||||
|
||||
if (aNewNode level <= aLastNode level)
|
||||
[ aNewNode left := aLastNode. ^ aNewNode ].
|
||||
if (newNode.Level <= lastNode.Level)
|
||||
{ newNode.Left := lastNode; ^ newNode };
|
||||
|
||||
var aParent := aLastNode.
|
||||
var aCurrent := aLastNode right.
|
||||
while ((nil != aCurrent) && (aNewNode level > aCurrent level))
|
||||
[ aParent := aCurrent. aCurrent := aCurrent right. ].
|
||||
var parent := lastNode;
|
||||
var current := lastNode.Right;
|
||||
while (nil != current && newNode.Level > current.Level)
|
||||
{ parent := current; current := current.Right };
|
||||
|
||||
if (nil == aCurrent)
|
||||
[ aParent right := aNewNode. ];
|
||||
[ aNewNode left := aCurrent. aParent right := aNewNode ].
|
||||
if (nil == current)
|
||||
{
|
||||
parent.Right := newNode
|
||||
}
|
||||
else
|
||||
{
|
||||
newNode.Left := current; parent.Right := newNode
|
||||
};
|
||||
|
||||
^ aLastNode
|
||||
]
|
||||
^ lastNode
|
||||
}
|
||||
|
||||
run : aText
|
||||
[
|
||||
var aScope := Scope new(self).
|
||||
run(text)
|
||||
{
|
||||
var scope := Scope.new(self);
|
||||
|
||||
aText forEach(:ch)[ aScope eval:ch ].
|
||||
text.forEach:(ch){ scope.eval:ch };
|
||||
|
||||
^ aScope number
|
||||
]
|
||||
^ scope.Number
|
||||
}
|
||||
}
|
||||
|
||||
public program
|
||||
[
|
||||
var aText := StringWriter new.
|
||||
var aParser := Parser new.
|
||||
public program()
|
||||
{
|
||||
var text := new StringWriter();
|
||||
var parser := new Parser();
|
||||
|
||||
$(console readLine; saveTo:aText; length > 0) doWhile:
|
||||
[
|
||||
try(console printLine("=",aParser run:aText))
|
||||
while (console.readLine().saveTo(text).Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
on(Exception e)
|
||||
[
|
||||
console writeLine:"Invalid Expression"
|
||||
]
|
||||
}.
|
||||
console.printLine("=",parser.run:text)
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
console.writeLine(e.Printable)
|
||||
|
||||
aText clear
|
||||
]
|
||||
]
|
||||
//console.writeLine:"Invalid Expression"
|
||||
};
|
||||
|
||||
text.clear()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue