Element MathParse GlobalConst MathParse.FuncList: dq 'PI' dq 'E' dq 'SIN' dq 'COS' dq 'TG' dq 'CTG' dq 'ARCSIN' dq 'ARCCOS' dq 'ARCTG' dq 'ARCCTG' dq 'LOG' dq 'LG' dq 'LN' dq 'EXP' dq 'SQR' dq 'SQRT' dq 'ABS' dq 'SIGN' dq 'ROUND' dq 'FRAC' dq 'TRUNC' dq 'MIN' dq 'MAX' dd 0 MathParse.FuncProc: irp proc,add,sub,mul,div,idiv,imod,power,pi,e,sin,cos,tg,ctg,arcsin,arccos,arctg,arcctg,\ log,lg,ln,exp,sqr,sqrt,abs,sign \{ dd math.\#proc \} MathParse.OptArg = 10h + ($-MathParse.FuncProc)/4 irp proc,round,frac,trunc \{ dd math.\#proc \} MathParse.AggFunc = 10h + ($-MathParse.FuncProc)/4 irp proc,min,max \{ dd math.\#proc \} MathParse.FuncCount = ($-MathParse.FuncProc)/4 GlobalVars MathParse.TokTp db ? MathParse.Token rb 31 GlobalProc proc MathParse.Parse ; esi - pchar, edi - pcode mov word [MathParse.TokTp],'(' shl 8 + 1 call MathParse.GetToken call MathParse.Level1 xor al,al stosb ret endp proc MathParse.Level1 call MathParse.Level2 .loop: mov ax,word [MathParse.TokTp] cmp ax,'+' shl 8 + 1 jne .op1 call MathParse.GetToken call MathParse.Level2 mov al,10h stosb jmp .loop .op1: cmp ax,'-' shl 8 + 1 jne .end call MathParse.GetToken call MathParse.Level2 mov al,11h stosb jmp .loop .end: ret endp proc MathParse.Level2 call MathParse.Level3 .loop: mov ax,word [MathParse.TokTp] cmp ax,'*' shl 8 + 1 jne .op1 call MathParse.GetToken call MathParse.Level3 mov al,12h stosb jmp .loop .op1: cmp ax,'/' shl 8 + 1 jne .op2 call MathParse.GetToken call MathParse.Level3 mov al,13h stosb jmp .loop .op2: cmp al,2 jne .end mov eax,dword [MathParse.Token] and eax,0DFDFDFDFh cmp eax,'DIV' jne .op3 call MathParse.GetToken call MathParse.Level3 mov al,14h stosb jmp .loop .op3: cmp eax,'MOD' jne .end call MathParse.GetToken call MathParse.Level3 mov al,15h stosb jmp .loop .end: ret endp proc MathParse.Level3 call MathParse.Level4 mov ax,word [MathParse.TokTp] cmp ax,'^' shl 8 + 1 jne .end call MathParse.GetToken call MathParse.Level3 mov al,16h stosb .end: ret endp proc MathParse.Level4 .loop: mov al,[MathParse.TokTp] dec al je .opcha dec al je .alpha dec al jne .error lea eax,[MathParse.Token] stdcall StrToReal,eax mov al,2 stosb fstp qword [edi] add edi,8 jmp MathParse.GetToken .opcha: mov al,[MathParse.Token] cmp al,'+' je .plus cmp al,'-' je .minus cmp al,'%' je .arg cmp al,'(' jne .error call MathParse.GetToken call MathParse.Level1 mov ax,word [MathParse.TokTp] cmp ax,')' shl 8 + 1 jne .error jmp MathParse.GetToken .plus: call MathParse.GetToken jmp .loop .minus: call MathParse.GetToken call MathParse.Level4 mov al,4 stosb jmp .loop .arg: call MathParse.GetToken cmp al,3 jne .error push ebx esi mov ebx,10 lea esi,[MathParse.Token] call __str2int pop esi ebx cmp eax,80h jae .error add al,7Fh stosb jmp MathParse.GetToken .alpha: push esi and dword [MathParse.Token],0DFDFDFDFh and dword [MathParse.Token+4],0DFDFDFDFh mov edx,16h lea esi,[MathParse.FuncList] .alloop: inc edx lodsd or eax,eax je .alerr cmp eax,dword [MathParse.Token] jne .alnx1 lodsd cmp eax,dword [MathParse.Token+4] je .alfound jmp .alloop .alnx1: add esi,4 jmp .alloop .alfound: pop esi push edx push 0 call MathParse.GetToken mov ax,word [MathParse.TokTp] cmp ax,'(' shl 8 + 1 jne .alnoarg .alloop2: inc dword [esp] call MathParse.GetToken call MathParse.Level1 mov ax,word [MathParse.TokTp] cmp ax,',' shl 8 + 1 je .alloop2 cmp ax,')' shl 8 + 1 je .alend pop eax pop eax jmp .error .alend: call MathParse.GetToken .alnoarg: pop ecx mov eax,[esp] sub eax,MathParse.OptArg cmp eax,MathParse.AggFunc-MathParse.OptArg jae .noargc mov al,3 stosb mov al,cl stosb .noargc: pop eax stosb ret .alerr: pop esi .error: ret endp proc MathParse.GetToken ; esi - pchar push edi mov ecx,3 mov ax,word [MathParse.TokTp] cmp ax,'(' shl 8 + 1 jne @f mov ecx,7 @@:lea edi,[MathParse.Token] .loop1: lodsb or al,al je .end cmp al,' ' jbe .loop1 mov ah,al and ah,0DFh sub ah,'A' cmp ah,26 jb .alpha test ecx,4 je @f cmp al,'-' je .num cmp al,'+' je .num @@:cmp al,'.' je .nump mov ah,al sub ah,'0' cmp ah,10 jb .nums stosb inc esi .opcha: mov al,1 jmp .end .alpha: stosb lodsb mov ah,al and ah,0DFh sub ah,'A' cmp ah,26 jb .alpha mov ah,al sub ah,'0' cmp ah,10 jb .alpha mov al,2 jmp .end .nump: and ecx,6 jmp .num1 .nume: mov ecx,4 jmp .num1 .nums: and ecx,3 jmp .num1 .num: stosb lodsb mov ah,al sub ah,'0' cmp ah,10 jb .nums cmp al,'.' jne .opcha and ecx,3 .num1: stosb lodsb mov ah,al sub ah,'0' cmp ah,10 jb .nums test ecx,1 je @f cmp al,'.' je .nump @@:test ecx,2 je @f cmp al,'E' je .nume cmp al,'e' je .nume @@:test ecx,4 je @f cmp al,'-' je .nums cmp al,'+' je .nums @@:mov al,3 .end: dec esi mov [MathParse.TokTp],al mov ecx,7 xor al,al rep stosb mov al,[MathParse.TokTp] pop edi ret endp proc MathParse.Calc ; esi - pcode, eax - AngleMode or eax,eax je .radian push 180 fldpi fild dword [esp] fdivp st1,st0 add esp,4 jmp .setamode .radian: fld1 .setamode: fstp [math.anglemode] fwait .loop: lodsb or al,al je .end cmp al,80h jb .noarg and eax,7Fh shl eax,3 add eax,4 add eax,esp fld qword [eax] jmp .loop .noarg: cmp al,2 jne .noreal fld qword [esi] add esi,8 jmp .loop .noreal: cmp al,3 jne .noargc lodsb mov cl,al jmp .loop .noargc: cmp al,4 jne .noneg fchs jmp .loop .noneg: sub al,10h cmp al,MathParse.FuncCount jae .end and eax,0FFh call dword [MathParse.FuncProc+eax*4] jmp .loop .end: ret endp Vars Self#.AngleMode dd ? Self#.Code dd ? Self#.Result dq ? Self#.tmp dd ? Create xor eax,eax mov [Self#.Code],eax mov [Self#.AngleMode],Self#.prop.AngleMode fmov_ex Self#.Result,Self#.prop.Default push esi edi mov eax,512 lea edx,[Self#.Code] call __strsetlength mov edi,[Self#.Code] mov esi,Self#.prop.MathStr call MathParse.Parse pop edi esi Destroy lea edx,[Self#.Code] call __strclear DPointData X \local res ReadReal res,[Self#.tmp],data.type,Self#.X#Index,0 if res eq 1 fstp qword [esp+(Index-1)*8] else fmov_ex esp+(Index-1)*8,res end if EndPoint PointWork doCalc \local sv.t DataSave data,data.type,[Self#.tmp],sv.t push esi sub esp,Self#.prop.DataCount*8 Self#.CallData ,,data,data.type mov eax,[Self#.AngleMode] mov esi,[Self#.Code] call MathParse.Calc add esp,Self#.prop.DataCount*8 pop esi Self#.onResult 1,data_real_st0 DataClear [Self#.tmp],sv.t EndPoint PointWork doClear fmov_ex Self#.Result,Self#.prop.Default EndPoint PointWork doMathStr \local res ToString res,data,data.type push esi edi mov esi,res mov edi,[Self#.Code] call MathParse.Parse pop edi esi EndPoint PointWork doAngleMode \local res ToInteger res,data,data.type if res eqtype 0 mov [Self#.AngleMode],res else mov_ex eax,res mov [Self#.AngleMode],eax end if EndPoint EndElement ; opcodes (hex) ; 00 - end ; 01 dd - fild int ; 02 dq - fld real ; 03 db - argc ; 04 - neg ; 10 - fadd ; 11 - fsub ; 12 - fmul ; 13 - fdiv ; 14 - div ; 15 - mod ; 16 - fpower ;>80 - fld arg (opcode-7F)