o_0 ... to moj projekt na zaliczenie pierwszej czesci programowania ... :/ wszystko jak na razie dziala poza procedura interpret, pisze tego posta dlatego ze utknalem ... ;( nie wiem jak to dalej ugryzc ;(
moze ktos podrzuci jakis fajny pomysl ?
o programie:
1 kompiluje sie na gpc 20040516 based on gcc-3.3.3 (cygwin) ale powinno tez smigac bez problemu na kazdym gpc, nie wiem czy turbo to skompiluje bo nie probowalem ... ale free pascal raczej powienin.
2 jak to dziala? hehe ;D no to jest dosyc skomplikowane ... otóż, mamy stringa 255 elementow jako wejscie, funkcja transform zamiania cyfry ze stringa na liczby i zapisuje na liscie dynamicznej vbox (vbox^.value) kazda taka liczba ma swoj numer 'block' ktoremu odpowiadaja szeregi operacji, przechowywane na liscie opebox, ... no tak to mniej wiecej wyglada ...
3 co program ma robic ? liczyc ;D tylko teraz nie wiem jak sie zabrac za procedure interpret zeby wkoncu zaczal liczyc ... tak sie zastanawiam czy dobrze by bylo ustawic dzialanie domysle jako + i uzywajac funkcji sine, wszystko sobie pododawac, jesli w bloku opebox nie ma dzialania o wyzszym priorytecie ... tylko holera nie wiem jak sie za to zabrac ... czy lepiej najpierw przegladac opebox'a czy vbox'a, czy tworzyc nowa liste dla wynikow dzialan pomiedzy blokami...
wyjsciowa program ma obslugiwac -,+,*,/,^,sqr,sin,cos,(,)
cos dziwnego dzieje sie rowniez ... jesli miedzy dzialaniami jest spacja ... nie wiem dlaczego jej nie ignoruje ... wg tych warunkow powinien reagowac jedynie na zdefinowane znaczniki tzn liczby 0..9 i dzialania o_0
oto kod:
program calc;
//uses crt;
type pointB = ^box;
pointO = ^ope;
st = string[255];
tnum = set of '0'..'9' ;
tope = set of 42..94;
ope = record
c:char;
block,count:integer;
prev,next:pointO;
end;
box = record
value:real;
block:integer;
prev,next:pointB;
end;
var formula:st;
vbox:pointB;
opebox:pointO;
val:double;
block:integer;
result:real;
procedure transform(formula:st;var vbox :pointB; var opebox:pointO; var block : integer );
var i,j,opecount : integer;
val : real;
num : tnum;
ope : tope;
newvbox : pointB;
newopebox : pointO;
bdec : boolean;
begin
new(vbox);
new(opebox);
vbox^.next := nil;
vbox^.prev := nil;
opebox^.next := nil;
opebox^.prev := nil;
vbox^.value := 0;
vbox^.block := 0;
opecount := 1;
j := 0;
val := 0;
ope:=[42,43,45,47,94];
num:=['0'..'9'];
bdec:=FALSE;
for i:=1 to length(formula) do
begin
if (formula[i] = '.') or (formula[i] = ',') then bdec := true;
if bdec = true then j:=j+1;
if formula[i] in num then begin
val:= 10 * val + ord(formula[i]) - ord('0');
if (ord(formula[i+1]) in ope) or (i = length(formula)) then begin
if j <> 0 then begin
for j:=j downto 2 do
val := val/10;
vbox^.value := val;
end
else begin
vbox^.value := val;
end;
val := 0;
j := 0;
end;
end;
if (formula[i] in num) and (ord(formula[i+1]) in ope) then begin
bdec:=false;
block:=block+1;
vbox^.block := block;
//creating new nod
new(newvbox);
newvbox^.next := vbox;
vbox^.prev := newvbox;
vbox := newvbox;
opecount := 1;
//nod created
end;
if ord(formula[i]) in ope then begin
opebox^.block := block;
opebox^.count := opecount;
opecount := opecount +1;
opebox^.c := formula[i];
new(newopebox);
newopebox^.next := opebox;
opebox^.prev := newopebox;
opebox := newopebox;
end;
end;
opebox^.block := block;
block := block +1;
vbox^.block := block;
end; // end of transform
function sign(opebox:pointO;block:integer):integer;
var tmp,i:integer;
opeboxScope:pointO;
begin
tmp:=1;
opeboxScope:=opebox;
while (opeboxScope^.next <> nil) do begin
if (opeboxScope^.block <> block) then begin
opeboxScope:=opeboxScope^.next;
end;
if (opeboxScope^.block = block) then begin
if (opeboxScope^.c = '-') then tmp:=tmp*(-1);
if (opeboxScope^.next <> nil) then opeboxScope:=opeboxScope^.next;
end;
end;
sign:=tmp;
end;
function add(a,b:real):real;
begin
add:=a+b;
end;
function multip(a,b:real):real;
begin
multip:=a*b;
end;
function divid(a,b:real):real;
begin
if b<>0 then divid:=a/b
else begin
writeln('Division by 0 detected, exiting with 0');
divid:=0;
end;
end;
procedure interpret( var vbox : pointB; var opebox : pointO; block:integer; var result:real);
var i:integer;
sum,partsum:real;
vboxTmp:pointB;
opeboxScope:pointO;
begin
sum:=0;
partsum:=0;
for block:=block downto 1 do begin
if opeboxScope^.block <> (block-1) then opeboxScope:=opeboxScope^.next
else begin
end;
if vbox^.block <> block then vbox:=vbox^.next
else begin
end;
//writeln(block);
//writeln((vbox^.value)*sign(opebox,(block-1)));
//writeln((vbox^.next^.value)*sign(opebox,block-2));
end; // end of for block:=block
end;
procedure showall(vbox:pointB; opebox:pointO; block:integer);
var vboxScope:pointB;
opeboxScope:pointO;
begin
vboxScope := vbox;
opeboxScope := opebox;
writeln;
writeln('############# showing whole vbox list content ###############');
writeln('# #');
writeln('# vbox content: #');
while (vboxScope^.block >= 1) do
begin
writeln('# vbox^.value for block ',vboxScope^.block,' is ',vboxScope^.value);
if vboxScope^.block = 1 then break
else
vboxScope := vboxScope^.next;
end;
writeln('# #');
writeln('############ showing whole opebox list content ##############');
writeln('# #');
writeln('# opebox content: #');
while (opeboxScope^.next <> nil) do
begin
writeln('# opebox^.c for block ',opeboxScope^.next^.block,' is ',opeboxScope^.next^.c);
writeln('# opebox^.count is ',opeboxScope^.next^.count);
opeboxScope := opeboxScope^.next;
end;
writeln('# #');
writeln('#############################################################');
writeln;
//dispose(vboxScope);
//dispose(opeboxScope);
end;
procedure disp(var vbox:pointB;var opebox:pointO);
begin
dispose(vbox);
dispose(opebox);
end;
begin
//clrscr;
block:=0;
result:=0;
writeln('calc input formula max string 255 char');
readln(formula);
transform(formula,vbox,opebox,block);
showall(vbox,opebox,block);
writeln(sign(opebox,0));
//interpret(vbox,opebox,block,result);
//writeln(result);
//readln;
end.