// built by Liu Yang 2002.1.8
library Expression;
uses Dialogs, Math, SysUtils;
Const Symbol_Mod='M'; Symbol_Div='D'; Symbol_Shl='L'; Symbol_Shr='R'; Symbol_Or='O'; Symbol_Xor='X'; Symbol_And='A';
function ConvertExpression(ExpressionString:PChar):PChar; stdcall; var inputexp:string; begin inputexp:=ExpressionString; //convert input expression to recognize expression if pos('=',inputexp)=0 then inputexp:=inputexp+'=' else inputexp:=Copy(inputexp,1,Pos('=',inputexp)); inputexp:=UpperCase(inputexp); inputexp:=StringReplace(inputexp,' ','',[rfReplaceAll]); inputexp:=StringReplace(inputexp,'MOD',Symbol_Mod,[rfReplaceAll]); inputexp:=StringReplace(inputexp,'DIV',Symbol_Div,[rfReplaceAll]); inputexp:=StringReplace(inputexp,'AND',Symbol_And,[rfReplaceAll]); inputexp:=StringReplace(inputexp,'XOR',Symbol_Xor,[rfReplaceAll]); inputexp:=StringReplace(inputexp,'OR',Symbol_Or,[rfReplaceAll]); inputexp:=StringReplace(inputexp,'SHL',Symbol_Shl,[rfReplaceAll]); inputexp:=StringReplace(inputexp,'SHR',Symbol_Shr,[rfReplaceAll]); inputexp:=StringReplace(inputexp,'(-','(0-',[rfReplaceAll]); if pos('-',inputexp)=1 then inputexp:='0'+inputexp; Result:=PChar(inputexp); end;
function ParseExpression(ExpressionString:PChar): extended; stdcall; var nextch:char; nextchpos,position:word; inputexp:string; procedure expression(var ev:extended);forward; procedure readnextch; begin repeat if inputexp[position]='=' then nextch:='=' else begin inc(nextchpos); inc(position); nextch:=inputexp[position]; end; until (nextch<>' ') or eoln; end; procedure error(ErrorString:string); begin MessageDlg('Unknown expression : '+ErrorString,mterror,[mbok],0); exit; end; procedure number(var nv:extended); var radix:longint; snv:string; function BinToInt(value: string): integer; var i,size:integer; begin // convert binary number to integer result:=0; size:=length(value); for i:=size downto 1 do if copy(value,i,1)='1' then result:=result+(1 shl (size-i)); end; begin nv:=0; snv:=''; while nextch in ['0'..'9','A'..'F'] do begin // nv:=10*nv+ord(nextch)-ord('0'); snv:=snv+nextch; readnextch; end; // parse Hex, Bin if snv<>'' then if snv[Length(snv)]='B' then nv:=BinToInt(Copy(snv,1,Length(snv)-1)) else if nextch='H' then begin nv:=StrToInt('$'+snv); readnextch; end else nv:=StrToInt(snv); if nextch='.' then begin radix:=10; readnextch; while nextch in ['0'..'9'] do begin nv:=nv+(ord(nextch)-ord('0'))/radix; radix:=radix*10; readnextch; end; end; end; procedure factor(var fv:extended); Var Symbol:string; function CalcN(Value:integer):extended; var i:integer; begin Result:=1; if Value=0 then Exit else for i:=1 to Value do Result:=Result*i; end; function ParseFunction(var FunctionSymbol:string):boolean; begin FunctionSymbol:=''; while not (nextch in ['0'..'9','.','(',')','+','-','*','/','=']) do begin FunctionSymbol:=FunctionSymbol+nextch; readnextch; end; if FunctionSymbol='ABS' then Result:=true else if FunctionSymbol='SIN' then Result:=true else if FunctionSymbol='COS' then Result:=true else if FunctionSymbol='TG' then Result:=true else if FunctionSymbol='TAN' then Result:=true else if FunctionSymbol='ARCSIN' then Result:=true else if FunctionSymbol='ARCCOS' then Result:=true else if FunctionSymbol='ARCTG' then Result:=true else if FunctionSymbol='ARCTAN' then Result:=true else if FunctionSymbol='LN' then Result:=true else if FunctionSymbol='LG' then Result:=true else if FunctionSymbol='EXP' then Result:=true else if FunctionSymbol='SQR' then Result:=true else if FunctionSymbol='SQRT' then Result:=true else if FunctionSymbol='PI' then Result:=true else if FunctionSymbol='NOT' then Result:=true else if FunctionSymbol='N!' then Result:=true else if FunctionSymbol='E' then Result:=true else Result:=false; end; begin Case nextch of '0'..'9' : number(fv); '(' : begin readnextch; expression(fv); if nextch=')' then readnextch else error(nextch); end else if ParseFunction(Symbol) then if nextch='(' then begin readnextch; expression(fv); if Symbol='ABS' then fv:=abs(fv) else if Symbol='SIN' then fv:=sin(fv) else if Symbol='COS' then fv:=cos(fv) else if Symbol='TG' then fv:=tan(fv) else if Symbol='TAN' then fv:=tan(fv) else if Symbol='ARCSIN' then fv:=arcsin(fv) else if Symbol='ARCCOS' then fv:=arccos(fv) else if Symbol='ARCTG' then fv:=arctan(fv) else if Symbol='ARCTAN' then fv:=arctan(fv) else if Symbol='LN' then fv:=ln(fv) else if Symbol='LG' then fv:=ln(fv)/ln(10) else if Symbol='EXP' then fv:=exp(fv) else if Symbol='SQR' then fv:=sqr(fv) else if Symbol='SQRT' then fv:=sqrt(fv) else if Symbol='NOT' then fv:=not(Round(fv)) else if Symbol='N!' then fv:=CalcN(Round(fv)) else error(symbol); if nextch=')' then readnextch else error(nextch); end else begin // parse constant if Symbol='PI' then fv:=3.14159265358979324 else if Symbol='E' then fv:=2.71828182845904523 else error(symbol); end else begin error(Symbol); fv:=1; end; end; end; procedure Power_(var pv:extended); var multiop:char; fs:extended; begin factor(pv); while nextch in ['^'] do begin multiop:=nextch; readnextch; factor(fs); case multiop of '^':if pv<>0.0 then pv:=exp(ln(pv)*fs) else error(multiop); end; end; end; procedure term_(var tv:extended); var multiop:char; fs:extended; begin Power_(tv); while nextch in ['*','/',Symbol_Mod,Symbol_Div,Symbol_And,Symbol_Shl,Symbol_Shr] do begin multiop:=nextch; readnextch; Power_(fs); case multiop of '*':tv:=tv*fs; '/':if fs<>0.0 then tv:=tv/fs else error(multiop); Symbol_Mod:tv:=round(tv) mod round(fs); // prase mod Symbol_Div:tv:=round(tv) div round(fs); // parse div Symbol_And:tv:=round(tv) and round(fs); // parse and Symbol_Shl:tv:=round(tv) shl round(fs); // parse shl Symbol_Shr:tv:=round(tv) shr round(fs); // parse shr end; end; end; procedure expression(var ev:extended); var addop:char; fs:extended; begin term_(ev); while nextch in ['+','-',Symbol_Or,Symbol_Xor] do begin addop:=nextch; readnextch; term_(fs); case addop of '+':ev:=ev+fs; '-':ev:=ev-fs; Symbol_Or:ev:=round(ev) or round(fs); // parse or Symbol_Xor:ev:=round(ev) xor round(fs); // parse xor end; end; end; BEGIN inputexp:=ConvertExpression(ExpressionString); if pos('=',inputexp)=0 then inputexp:=ConvertExpression(ExpressionString); position:=0; while inputexp[position]<>'=' do begin nextchpos:=0; readnextch; expression(result); end; END;
function ParseExpressionToStr(ExpressionString:PChar):PChar; stdcall; var ES:string; begin ES:=ExpressionString; if pos('=',ES)=0 then ES:=ES+'=' else ES:=Copy(ES,1,Pos('=',ES)); ES:=ES+FormatFloat('0.000000000000',ParseExpression(ExpressionString)); Result:=PChar(ES); end;
function Version:PChar; stdcall; begin Result:='Calculator Dll Build 2001.10.25 Made By Liu Yang All Rights Reserved'; end;
Exports ConvertExpression, ParseExpression, ParseExpressionToStr, Version; end. 
|