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.