unit evalcomp;
interface
type
fun = function(x, y: real): real;
evalvec = ^evalobj;
evalobj = object
f1, f2: evalvec;
f1x, f2y: real;
f3: fun;
function eval: real;
function eval1d(x: real): real;
function eval2d(x, y: real): real;
function eval3d(x, y, z: real): real;
constructor init(st: string);
destructor done;
end;
var
evalx, evaly, evalz: real;
implementation
var
analysetmp: fun;
function search(text, code: string; var pos: integer): boolean;
var
i, count: integer;
flag: boolean;
newtext: string;
begin
if length(text) < l;
length(code) then
begin
search := false;
exit;
end;
flag := false;
pos := length(text) - length(code) + 1;
repeat
if code = copy(text, pos, length(code)) then
flag := true
else
dec(pos);
if flag then
begin
count := 0;
for i := pos + 1 to length(text) do
begin
if copy(text, i, 1) = '(' then
inc(count);
if copy(text, i, 1) = ')' then
dec(count);
end;
if count < l;
> 0 then
begin
dec(pos);
flag := false;
end;
end;
until (flag = true) or (pos = 0);
search := flag;
end;
function myid(x, y: real): real;
begin
myid := x;
end;
function myunequal(x, y: real): real;
begin
if x <> y then
myunequal := 1
else
myunequal := 0;
end;
function mylessequal(x, y: real): real;
begin
if x <= y then
mylessequal := 1
else
mylessequal := 0;
end;
function mygreaterequal(x, y: real): real;
begin
if x >= y then
mygreaterequal := 1
else
mygreaterequal := 0;
end;
function mygreater(x, y: real): real;
begin
if x > y then
mygreater := 1
else
mygreater := 0;
end;
function myless(x, y: real): real;
begin
if x < y then
myless := 1
else
myless := 0;
end;
function myequal(x, y: real): real;
begin
if x = y then
myequal := 1
else
myequal := 0;
end;
function myadd(x, y: real): real;
begin
myadd := x + y;
end;
function mysub(x, y: real): real;
begin
mysub := x - y;
end;
function myeor(x, y: real): real;
begin
myeor := trunc(x) xor trunc(y);
end;
function myor(x, y: real): real;
begin
myor := trunc(x) or trunc(y);
end;
function mymult(x, y: real): real;
begin
mymult := x * y;
end;
function mydivid(x, y: real): real;
begin
mydivid := x / y;
end;
function myand(x, y: real): real;
begin
myand := trunc(x) and trunc(y);
end;
function mymod(x, y: real): real;
begin
mymod := trunc(x) mod trunc(y);
end;
function mydiv(x, y: real): real;
begin
mydiv := trunc(x) div trunc(y);
end;
function mypower(x, y: real): real;
begin
if x = 0 then
mypower := 0
else if x > 0 then
mypower := exp(y * ln(x))
else if trunc(y) <> y then
begin
writeln(' Немогу вычислить x^y ');
halt;
end
else if odd(trunc(y)) = true then
mypower := -exp(y * ln(-x))
else
mypower := exp(y * ln(-x))
end;
function myshl(x, y: real): real;
begin
myshl := trunc(x) shl trunc(y);
end;
function myshr(x, y: real): real;
begin
myshr := trunc(x) shr trunc(y);
end;
function mynot(x, y: real): real;
begin
mynot := not trunc(x);
end;
function mysinc(x, y: real): real;
begin
if x = 0 then
mysinc := 1
else
mysinc := sin(x) / x
end;
function mysinh(x, y: real): real;
begin
mysinh := 0.5 * (exp(x) - exp(-x))
end;
function mycosh(x, y: real): real;
begin
mycosh := 0.5 * (exp(x) + exp(-x))
end;
function mytanh(x, y: real): real;
begin
mytanh := mysinh(x, 0) / mycosh(x, 0)
end;
function mycoth(x, y: real): real;
begin
mycoth := mycosh(x, 0) / mysinh(x, 0)
end;
function mysin(x, y: real): real;
begin
mysin := sin(x)
end;
function mycos(x, y: real): real;
begin
mycos := cos(x)
end;
function mytan(x, y: real): real;
begin
mytan := sin(x) / cos(x)
end;
function mycot(x, y: real): real;
begin
mycot := cos(x) / sin(x)
end;
function mysqrt(x, y: real): real;
begin
mysqrt := sqrt(x)
end;
function mysqr(x, y: real): real;
begin
mysqr := sqr(x)
end;
function myarcsinh(x, y: real): real;
begin
myarcsinh := ln(x + sqrt(sqr(x) + 1))
end;
function mysgn(x, y: real): real;
begin
if x = 0 then
mysgn := 0
else
mysgn := x / abs(x)
end;
function myarccosh(x, y: real): real;
begin
myarccosh := ln(x + mysgn(x, 0) * sqrt(sqr(x) - 1))
end;
function myarctanh(x, y: real): real;
begin
myarctanh := ln((1 + x) / (1 - x)) / 2
end;
function myarccoth(x, y: real): real;
begin
myarccoth := ln((1 - x) / (1 + x)) / 2
end;
function myarcsin(x, y: real): real;
begin
if x = 1 then
myarcsin := pi / 2
else
myarcsin := arctan(x / sqrt(1 - sqr(x)))
end;
function myarccos(x, y: real): real;
begin
myarccos := pi / 2 - myarcsin(x, 0)
end;
function myarctan(x, y: real): real;
begin
myarctan := arctan(x);
end;
function myarccot(x, y: real): real;
begin
myarccot := pi / 2 - arctan(x)
end;
function myheavy(x, y: real): real;
begin
myheavy := mygreater(x, 0)
end;
function myfrac(x, y: real): real;
begin
myfrac := frac(x)
end;
function myexp(x, y: real): real;
begin
myexp := exp(x)
end;
function myabs(x, y: real): real;
begin
myabs := abs(x)
end;
function mytrunc(x, y: real): real;
begin
mytrunc := trunc(x)
end;
function myln(x, y: real): real;
begin
myln := ln(x)
end;
function myodd(x, y: real): real;
begin
if odd(trunc(x)) then
myodd := 1
else
myodd := 0;
end;
function mypred(x, y: real): real;
begin
mypred := pred(trunc(x));
end;
function mysucc(x, y: real): real;
begin
mysucc := succ(trunc(x));
end;
function myround(x, y: real): real;
begin
myround := round(x);
end;
function myint(x, y: real): real;
begin
myint := int(x);
end;
function myfac(x, y: real): real;
var
n: integer;
r: real;
begin
if x < 0 then
begin
writeln(' Немогу вычислить факториал ');
halt;
end;
if x = 0 then
myfac := 1
else
begin
r := 1;
for n := 1 to trunc(x) do
r := r * n;
myfac := r;
end;
end;
function myrnd(x, y: real): real;
begin
myrnd := random;
end;
function myrandom(x, y: real): real;
begin
myrandom := random(trunc(x));
end;
function myevalx(x, y: real): real;
begin
myevalx := evalx;
end;
function myevaly(x, y: real): real;
begin
myevaly := evaly;
end;
function myevalz(x, y: real): real;
begin
myevalz := evalz;
end;
procedure analyse(st: string; var st2, st3: string);
label
start;
var
pos: integer;
value: real;
newterm, term: string;
begin
term := st;
start:
if term = '' then
begin
analysetmp := myid;
st2 := '0';
st3 := '';
exit;
end;
newterm := '';
for pos := 1 to length(term) do
if copy(term, pos, 1) <> ' ' then
newterm := newterm + copy(term, pos, 1);
term := newterm;
if term = '' then
begin
analysetmp := myid;
st2 := '0';
st3 := '';
exit;
end;
val(term, value, pos);
if pos = 0 then
begin
analysetmp := myid;
st2 := term;
st3 := '';
exit;
end;
if search(term, '<>', pos) then
begin
analysetmp := myunequal;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 2, length(term) - pos - 1);
exit;
end;
if search(term, '<=', pos) then
begin
analysetmp := mylessequal;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 2, length(term) - pos - 1);
exit;
end;
if search(term, '>=', pos) then
begin
analysetmp := mygreaterequal;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 2, length(term) - pos - 1);
exit;
end;
if search(term, '>', pos) then
begin
analysetmp := mygreater;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, '<', pos) then
begin
analysetmp := myless;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, '=', pos) then
begin
analysetmp := myequal;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, '+', pos) then
begin
analysetmp := myadd;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, '-', pos) then
begin
analysetmp := mysub;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, 'eor', pos) then
begin
analysetmp := myeor;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 3, length(term) - pos - 2);
exit;
end;
if search(term, 'or', pos) then
begin
analysetmp := myor;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 2, length(term) - pos - 1);
exit;
end;
if search(term, '*', pos) then
begin
analysetmp := mymult;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, '/', pos) then
begin
analysetmp := mydivid;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, 'and', pos) then
begin
analysetmp := myand;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 3, length(term) - pos - 2);
exit;
end;
if search(term, 'mod', pos) then
begin
analysetmp := mymod;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 3, length(term) - pos - 2);
exit;
end;
if search(term, 'div', pos) then
begin
analysetmp := mydiv;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 3, length(term) - pos - 2);
exit;
end;
if search(term, '^', pos) then
begin
analysetmp := mypower;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 1, length(term) - pos);
exit;
end;
if search(term, 'shl', pos) then
begin
analysetmp := myshl;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 3, length(term) - pos - 2);
exit;
end;
if search(term, 'shr', pos) then
begin
analysetmp := myshr;
st2 := copy(term, 1, pos - 1);
st3 := copy(term, pos + 3, length(term) - pos - 2);
exit;
end;
if copy(term, 1, 1) = '(' then
begin
term := copy(term, 2, length(term) - 2);
goto start;
end;
if copy(term, 1, 3) = 'not' then
begin
analysetmp := mynot;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'sinc' then
begin
analysetmp := mysinc;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'sinh' then
begin
analysetmp := mysinh;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'cosh' then
begin
analysetmp := mycosh;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'tanh' then
begin
analysetmp := mytanh;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'coth' then
begin
analysetmp := mycoth;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'sin' then
begin
analysetmp := mysin;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'cos' then
begin
analysetmp := mycos;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'tan' then
begin
analysetmp := mytan;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'cot' then
begin
analysetmp := mycot;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'sqrt' then
begin
analysetmp := mysqrt;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'sqr' then
begin
analysetmp := mysqr;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 7) = 'arcsinh' then
begin
analysetmp := myarcsinh;
st2 := copy(term, 8, length(term) - 7);
st3 := '';
exit;
end;
if copy(term, 1, 7) = 'arccosh' then
begin
analysetmp := myarccosh;
st2 := copy(term, 8, length(term) - 7);
st3 := '';
exit;
end;
if copy(term, 1, 7) = 'arctanh' then
begin
analysetmp := myarctanh;
st2 := copy(term, 8, length(term) - 7);
st3 := '';
exit;
end;
if copy(term, 1, 7) = 'arccoth' then
begin
analysetmp := myarccoth;
st2 := copy(term, 8, length(term) - 7);
st3 := '';
exit;
end;
if copy(term, 1, 6) = 'arcsin' then
begin
analysetmp := myarcsin;
st2 := copy(term, 7, length(term) - 6);
st3 := '';
exit;
end;
if copy(term, 1, 6) = 'arccos' then
begin
analysetmp := myarccos;
st2 := copy(term, 7, length(term) - 6);
st3 := '';
exit;
end;
if copy(term, 1, 6) = 'arctan' then
begin
analysetmp := myarctan;
st2 := copy(term, 7, length(term) - 6);
st3 := '';
exit;
end;
if copy(term, 1, 6) = 'arccot' then
begin
analysetmp := myarccot;
st2 := copy(term, 7, length(term) - 6);
st3 := '';
exit;
end;
if copy(term, 1, 5) = 'heavy' then
begin
analysetmp := myheavy;
st2 := copy(term, 6, length(term) - 5);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'sgn' then
begin
analysetmp := mysgn;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'frac' then
begin
analysetmp := myfrac;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'exp' then
begin
analysetmp := myexp;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'abs' then
begin
analysetmp := myabs;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 5) = 'trunc' then
begin
analysetmp := mytrunc;
st2 := copy(term, 6, length(term) - 5);
st3 := '';
exit;
end;
if copy(term, 1, 2) = 'ln' then
begin
analysetmp := myln;
st2 := copy(term, 3, length(term) - 2);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'odd' then
begin
analysetmp := myodd;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'pred' then
begin
analysetmp := mypred;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 4) = 'succ' then
begin
analysetmp := mysucc;
st2 := copy(term, 5, length(term) - 4);
st3 := '';
exit;
end;
if copy(term, 1, 5) = 'round' then
begin
analysetmp := myround;
st2 := copy(term, 6, length(term) - 5);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'int' then
begin
analysetmp := myint;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'fac' then
begin
analysetmp := myfac;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if term = 'rnd' then
begin
analysetmp := myrnd;
st2 := '';
st3 := '';
exit;
end;
if copy(term, 1, 3) = 'rnd' then
begin
analysetmp := myrandom;
st2 := copy(term, 4, length(term) - 3);
st3 := '';
exit;
end;
if term = 'x' then
begin
analysetmp := myevalx;
st2 := '';
st3 := '';
exit;
end;
if term = 'y' then
begin
analysetmp := myevaly;
st2 := '';
st3 := '';
exit;
end;
if term = 'z' then
begin
analysetmp := myevalz;
st2 := '';
st3 := '';
exit;
end;
if (term = 'pi') then
begin
analysetmp := myid;
str(pi, st2);
st3 := '';
exit;
end;
if term = 'e' then
begin
analysetmp := myid;
str(exp(1), st2);
sst3 := '';
exit;
end;
writeln(' ВНИМАНИЕ : НЕДЕКОДИРУЕМАЯ ФОРМУЛА ');
analysetmp := myid;
st2 := '';
st3 := '';
end;
function evalobj.eval: real;
var
tmpx, tmpy: real;
begin
if f1 = nil then
tmpx := f1x
else
tmpx := f1^.eval;
if f2 = nil then
tmpy := f2y
else
tmpy := f2^.eval;
eval := f3(tmpx, tmpy);
end;
function evalobj.eval1d(x: real): real;
begin
evalx := x;
evaly := 0;
evalz := 0;
eval1d := eval;
end;
function evalobj.eval2d(x, y: real): real;
begin
evalx := x;
evaly := y;
evalz := 0;
eval2d := eval;
end;
function evalobj.eval3d(x, y, z: real): real;
begin
evalx := x;
evaly := y;
evalz := z;
eval3d := eval;
end;
constructor evalobj.init(st: string);
var
st2, st3: string;
error: integer;
begin
f1 := nil;
f2 := nil;
analyse(st, st2, st3);
f3 := analysetmp;
val(st2, f1x, error);
if st2 = '' then
begin
f1x := 0;
error := 0;
end;
if error <> 0 then
new(f1, init(st2));
val(st3, f2y, error);
if st3 = '' then
begin
f2y := 0;
error := 0;
end;
if error <> 0 then
new(f2, init(st3));
end;
destructor evalobj.done;
begin
if f1 <> nil then
dispose(f1, done);
if f2 <> nil then
dispose(f2, done);
end;
end.
|