Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -9,15 +9,15 @@
collect (read-char stream) into digits
finally (return (parse-integer (coerce digits 'string))))))
(consume-whitespace)
(let ((c (peek-char nil stream nil nil)))
(let ((token (case c
((nil) nil)
((#\() :lparen)
((#\)) :rparen)
((#\*) '*)
((#\/) '/)
((#\+) '+)
((#\-) '-)
(let* ((c (peek-char nil stream nil nil)))
(token (case c
(nil nil)
(#\( :lparen)
(#\) :rparen)
(#\* '*)
(#\/ '/)
(#\+ '+)
(#\- '-)
(otherwise
(unless (digit-char-p c)
(cerror "Skip it." "Unexpected character ~w." c)
@ -27,7 +27,7 @@
(read-integer)))))
(unless (or (null token) (integerp token))
(read-char stream))
token))))
token)))
(defun group-parentheses (tokens &optional (delimited nil))
(do ((new-tokens '()))
@ -37,12 +37,12 @@
(values (nreverse new-tokens) '()))
(let ((token (pop tokens)))
(case token
((:lparen)
(:lparen
(multiple-value-bind (group remaining-tokens)
(group-parentheses tokens t)
(setf new-tokens (cons group new-tokens)
tokens remaining-tokens)))
((:rparen)
(:rparen
(if (not delimited)
(cerror "Ignore it." "Unexpected right parenthesis.")
(return (values (nreverse new-tokens) tokens))))

View file

@ -4,12 +4,13 @@ import std.stdio, std.string, std.ascii, std.conv, std.array,
struct Stack(T) {
T[] data;
alias data this;
void push(T top) pure nothrow { data ~= top; }
void push(T top) pure nothrow @safe { data ~= top; }
T pop(bool discard = true)() pure {
T pop(bool discard = true)() pure @nogc @safe {
immutable static exc = new immutable(Exception)("Stack Empty");
if (data.empty)
throw new Exception("Stack Empty");
auto top = data.back;
throw exc;
auto top = data[$ - 1];
static if (discard)
data.popBack;
return top;
@ -20,7 +21,7 @@ enum Type { Num, OBkt, CBkt, Add, Sub, Mul, Div }
immutable opChar = ["#", "(", ")", "+", "-", "*", "/"];
immutable opPrec = [ 0, -9, -9, 1, 1, 2, 2];
abstract class Visitor { void visit(XP e); }
abstract class Visitor { void visit(XP e) pure @safe; }
final class XP {
immutable Type type;
@ -28,7 +29,7 @@ final class XP {
immutable int pos; // Optional, to dispaly AST struct.
XP LHS, RHS;
this(string s=")", int p = -1) nothrow {
this(string s=")", int p = -1) pure nothrow @safe {
str = s;
pos = p;
auto localType = Type.Num;
@ -38,13 +39,13 @@ final class XP {
this.type = localType;
}
override int opCmp(Object other) pure {
override int opCmp(Object other) pure @safe {
auto rhs = cast(XP)other;
enforce(rhs !is null);
return opPrec[type] - opPrec[rhs.type];
}
void accept(Visitor v) { v.visit(this); }
void accept(Visitor v) pure @safe { v.visit(this); }
}
final class AST {
@ -53,13 +54,13 @@ final class AST {
string xpr, token;
int xpHead, xpTail;
void joinXP(XP x) pure {
void joinXP(XP x) pure @safe {
x.RHS = num.pop;
x.LHS = num.pop;
num.push(x);
}
string nextToken() pure {
string nextToken() pure @safe {
while (xpHead < xpr.length && xpr[xpHead] == ' ')
xpHead++; // Skip spc.
xpTail = xpHead;
@ -82,7 +83,7 @@ final class AST {
return null;
} // End nextToken.
AST parse(in string s) {
AST parse(in string s) /*@safe*/ {
bool expectingOP;
xpr = s;
try {
@ -147,7 +148,7 @@ final class AST {
// To display AST fancy struct.
void ins(ref char[][] s, in string v, in int p, in int l)
pure nothrow {
pure nothrow @safe {
if (l + 1 > s.length)
s.length++;
while (s[l].length < p + v.length + 1)
@ -160,7 +161,7 @@ final class CalcVis : Visitor {
string resultStr;
char[][] Tree;
static void opCall(AST a) {
static void opCall(AST a) @safe {
if (a && a.root) {
auto c = new CalcVis;
a.root.accept(c);
@ -187,7 +188,7 @@ final class CalcVis : Visitor {
}
// Calc. the value, display AST struct and eval order.
override void visit(XP xp) {
override void visit(XP xp) @safe {
ins(Tree, xp.str, xp.pos, level);
level++;
if (xp.type == Type.Num) {
@ -212,9 +213,9 @@ final class CalcVis : Visitor {
}
}
void main(string[] args) {
void main(string[] args) /*@safe*/ {
immutable exp0 = "1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5" ~
" - 22/(7 + 2*(3 - 1)) - 1)) + 1";
immutable exp = (args.length > 1) ? args[1 .. $].join(" ") : exp0;
immutable exp = (args.length > 1) ? args[1 .. $].join(' ') : exp0;
new AST().parse(exp).CalcVis; // Should be 60.
}

View file

@ -29,7 +29,7 @@
^ aNode += self.
]
#method Number = convertor toReal:theValue.
#method Number = convertor toReal:(theValue value).
}
// --- Node ---
@ -294,7 +294,7 @@
#var aParser := Parser new.
consoleEx writeLine:"=" :(aParser foreach:aText Number)
| ifFailed:
| if &e:
[
consoleEx writeLine:"Invalid Expression".
].

View file

@ -20,4 +20,4 @@
((num? X) X)
((= "+" X) (term))
((= "-" X) (list '- (term)))
((= "(" X) (prog1 (aggregate) (pop '*L)))) ) ) )
((= "(" X) (prog1 (aggregate) (pop '*L)))) ) )

View file

@ -14,8 +14,8 @@ j=0; do forever; j=j+1; if j>L then leave; _=substr(x,j,1); _2=getX()
end /* 2nd symbol.*/
z=z _ $; iterate
end
if _=='+' | _=="-" then do; p_=word(z,words(z)) /*last Z token*/
if p_=='(' then z=z 0 /*handle unary±*/
if _=='+' | _=="-" then do; p_=word(z,words(z)) /*last Z token*/
if p_=='(' then z=z 0 /*handle unary ±*/
z=z _ $; iterate
end
lets=0; sigs=0; #=_
@ -24,17 +24,17 @@ j=0; do forever; j=j+1; if j>L then leave; _=substr(x,j,1); _2=getX()
if lets==1 & sigs==0 then if _=='+' | _=='-' then do; sigs=1
#=# || _
iterate
end /*exp*/
end
if pos(_,nchars)==0 then leave
lets=lets+datatype(_,'M') /*keep track of # of exponents. */
#=# || translate(_,'EEEEE','eDdQq') /*keep building the num*/
#=# || translate(_,'EEEEE','eDdQq') /*keep buildingthe num.*/
end /*j*/
j=j-1
if \datatype(#,'N') then call serr 'invalid number: ' #
if \datatype(#,'N') then call serr 'invalid number: ' #
z=z # $
end /*forever*/
_=word(z,1); if _=='+' | _=='-' then z=0 z /*handle unary cases.*/
_=word(z,1); if _=='+' | _=='-' then z=0 z /*handle unary cases.*/
x='(' space(z) ') '; tokens=words(x) /*force stacking for expression. */
do i=1 for tokens; @.i=word(x,i); end /*i*/ /*assign input tokens*/
L=max(20,length(x)) /*use 20 for the min show width. */
@ -104,7 +104,7 @@ z=space(z stack) /*append any residual entries. */
say 'answer' z /*display the answer (result). */
parse source upper . how . /*invoked via C.L. or REXX pgm?*/
if how=='COMMAND' | ,
\datatype(z,'W') then exit /*stick a fork in it, we're done.*/
\datatype(z,'W') then exit /*stick a fork in it, we're done.*/
return z /*return Z ──► invoker (RESULT).*/
/*──────────────────────────────────subroutines─────────────────────────*/
isBit: return arg(1)==0 | arg(1)==1 /*returns 1 if arg1 is bin bit.*/
@ -112,6 +112,6 @@ isOp: return pos(arg(1),rOp)\==0 /*is argument1 a "real" operator?*/
serr: say; say e arg(1); say; exit 13 /*issue an error message with txt*/
/*──────────────────────────────────GETX subroutine─────────────────────*/
getX: do Nj=j+1 to length(x); _n=substr(x,Nj,1); if _n==$ then iterate
if _n==$ then iterate; return substr(x,Nj,1) /*ignore blanks*/
return substr(x,Nj,1) /* [↑] ignore any blanks in exp.*/
end /*Nj*/
return $ /*reached end-of-tokens, return $*/

View file

@ -1,11 +1,11 @@
$op_priority = {"+" => 0, "-" => 0, "*" => 1, "/" => 1}
$op_function = {
"+" => lambda {|x, y| x + y},
"-" => lambda {|x, y| x - y},
"*" => lambda {|x, y| x * y},
"/" => lambda {|x, y| x / y}}
class TreeNode
OP_FUNCTION = {
"+" => lambda {|x, y| x + y},
"-" => lambda {|x, y| x - y},
"*" => lambda {|x, y| x * y},
"/" => lambda {|x, y| x / y}}
attr_accessor :info, :left, :right
def initialize(info)
@ -23,10 +23,10 @@ class TreeNode
left_s, right_s = @left.to_s(order), @right.to_s(order)
strs = case order
when :prefix then [@info, left_s, right_s]
when :infix then [left_s, @info, right_s]
when :prefix then [@info, left_s, right_s]
when :infix then [left_s, @info, right_s]
when :postfix then [left_s, right_s, @info]
else []
else []
end
"(" + strs.join(" ") + ")"
@ -35,7 +35,7 @@ class TreeNode
def eval
if !leaf? and operator?(@info)
$op_function[@info].call(@left.eval, @right.eval)
OP_FUNCTION[@info].call(@left.eval, @right.eval)
else
@info.to_f
end
@ -46,6 +46,10 @@ def tokenize(exp)
exp
.gsub('(', ' ( ')
.gsub(')', ' ) ')
.gsub('+', ' + ')
.gsub('-', ' - ')
.gsub('*', ' * ')
.gsub('/', ' / ')
.split(' ')
end