home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
cpm
/
calculat
/
calc224.lbr
/
CALC_P.IZC
/
CALC_P.INC
Wrap
Text File
|
1987-07-19
|
4KB
|
162 lines
function conv_post(expr : str; var post_expr : str) : boolean;
type
op_ptr = ^op_rec;
op_rec = record
op : str;
next : op_ptr;
end;
var
i : integer;
valid : boolean;
token : str;
last_tok : str;
top_tok : str;
op_stack : op_ptr;
is_prec : boolean;
function empty(op_stack : op_ptr) : boolean;
begin { function empty }
empty := op_stack = nil;
end; { function empty }
function pop(var op_stack : op_ptr) : str;
var
prev : op_ptr;
begin { function pop }
if empty(op_stack) then
begin
pop := '';
writeln('Stack empty.');
end
else
begin
pop := op_stack^.op;
prev := op_stack;
op_stack := op_stack^.next;
dispose(prev);
end;
end; { function pop }
procedure push(var op_stack : op_ptr; op : str);
var
new_op : op_ptr;
begin { procedure push }
new(new_op);
new_op^.op := op;
new_op^.next := op_stack;
op_stack := new_op;
end; { procdure push }
function top(op_stack : op_ptr) : str;
begin { function top }
if empty(op_stack) then
begin
top := '';
writeln('Stack empty.');
end
else
top := op_stack^.op;
end; { function top }
function op_prec(op1, op2 : str) : boolean;
var
val_op1, val_op2 : number;
function op_val(op : str) : integer;
begin { function op_val }
if (op = '|') or (op = '^') then
op_val := 1
else if (op = '&') then
op_val := 2
else if (op = '+') or (op = '-') then
op_val := 3
else if (op = '*') or (op = '/') or (op = '%') then
op_val := 5
else if (op = '**') then
op_val := 7
else if (op = '~') then
op_val := 8
else if (op = '!') then
op_val := 9
else
op_val := 0;
end; { function op_val }
begin { function op_prec }
if (op1 = '(') and (op2 = ')') then
op_prec := false
else if op2 = ')' then
op_prec := true
else if op2 = '(' then
op_prec := false
else if (op1 = '~') and (op2 = '~') then
op_prec := false
else
op_prec := op_val(op1) >= op_val(op2);
end; { function op_prec }
procedure put_stack(stack : op_ptr);
begin { procedure put_stack }
writeln('stack:');
while stack <> nil do
begin
writeln(' ', stack^.op);
stack := stack^.next;
end;
writeln;
end;{ procedure put_stack }
begin { functioon conv_post }
valid := true;
op_stack := nil;
post_expr := '';
top_tok := '';
last_tok := '(';
while get_token(expr, token) and valid do
begin
if is_num(token) then
post_expr := post_expr + token + ' '
else if is_op(token) then
begin
if (token = '-') and (is_op(last_tok)
and not (last_tok[1] in [')', '!'])) then
token := '~';
is_prec := true;
while not empty(op_stack) and is_prec do
begin
top_tok := top(op_stack);
is_prec := op_prec(top_tok, token);
if is_prec and (top_tok <> '(') then
post_expr := post_expr + pop(op_stack) + ' '
else if (top_tok = '(') and (token = ')')then
voids := pop(op_stack)
end;
if token <> ')' then
push(op_stack, token)
else if top_tok <> '(' then
begin
writeln('Missing open parenthesis.');
valid := false;
end;
end
else
begin
writeln('Invalid token ''', token, '''.');
valid := false;
end;
last_tok := token;
end;
while valid and not empty(op_stack) do
if (top(op_stack) <> '(') then
post_expr := post_expr + pop(op_stack) + ' '
else
begin
writeln('Missing close parenthesis.');
valid := false;
end;
conv_post := valid;
end; { procedure conv_post }
= true
else i