'=========================================================================== ' Subject: FORMULA PARSER AND EXECUTOR Date: 06-09-98 (23:43) ' Author: Bert van Dam Code: QB, QBasic, PDS ' Origin: bd1rsd@usa.net Packet: ALGOR.ABC '=========================================================================== 'Simple formula parser and executor june 9, 1998 ' Bert van Dam 'This program takes a simple formula as a string (for example as entered 'by a user), converts it into an asm subroutine and executes it. This is 'not meant a a complete application. It was merely meant to show that the 'question "can you have basic calculate a formula entered by a user" has 'the answer "yes!" Since it is a demo it has some limitations: it can handle 'numbers smaller than FF (254) including the answer!, it handles simple 'operands only (+-x/) and it parses 'left-to-right' ignoring all math 'rules. So this example 2x3+6-1 is seen as ((2x3)+6)-1 which only happens 'to be correct by accident. Divisions need to result in integers since 'remainders are ignored. So if you actually want to use this technique 'you'll need to do some work yourself! CLS PRINT "---===[ Simple Formula Parser and Executor Using Inline Assembler ]===---" 'This program is donated to the public domain by Bert van Dam. I can be 'reached in the QUIK_BAS fidonet area (2:285/750.16) or the internet at 'bd1rsd@usa.net PRINT 'Parse formula, this could be entered by a user TestFormula$ = "2x3+6-1=" PRINT "Parsing formula "; TestFormula$ PRINT FOR t = 1 TO LEN(TestFormula$) 'Chop into parts containing the operator and the following number Token$ = MID$(TestFormula$, t, 1) IF INSTR("+-x/=", Token$) <> 0 THEN 'Process current part based on the leading operator SELECT CASE LEFT$(Part$, 1) CASE "+" 'Remove the operator NewPart$ = RIGHT$(Part$, LEN(Part$) - 1) 'Print the required assembler code PRINT "add ax,"; NewPart$ 'Add the code in hex to the formula string Formula$ = Formula$ + CHR$(&H5) + CHR$(VAL(NewPart$)) + CHR$(&H0) 'Clear the current part Part$ = "" CASE "-" NewPart$ = RIGHT$(Part$, LEN(Part$) - 1) PRINT "sub ax,"; NewPart$ Formula$ = Formula$ + CHR$(&H2D) + CHR$(VAL(NewPart$)) + CHR$(&H0) Part$ = "" CASE "x" NewPart$ = RIGHT$(Part$, LEN(Part$) - 1) PRINT "mov bx,"; NewPart$ Formula$ = Formula$ + CHR$(&HBB) + CHR$(VAL(NewPart$)) + CHR$(&H0) PRINT "mul bx" Formula$ = Formula$ + CHR$(&HF7) + CHR$(&HE3) Part$ = "" CASE "/" NewPart$ = RIGHT$(Part$, LEN(Part$) - 1) PRINT "mov bx,"; NewPart$ Formula$ = Formula$ + CHR$(&HBB) + CHR$(VAL(NewPart$)) + CHR$(&H0) PRINT "div bx" Formula$ = Formula$ + CHR$(&HF7) + CHR$(&HF3) Part$ = "" CASE ELSE 'No leading operator so this must be the first part PRINT "mov ax,"; Part$ 'Start a formu;a string and add the code in hex Formula$ = CHR$(&HB8) + CHR$(VAL(Part$)) + CHR$(&H0) Part$ = "" END SELECT END IF 'Keep building this part intul the next operator ss found Part$ = Part$ + Token$ NEXT t PRINT 'This is the asm header needed to transform the formula into an 'assembler subroutine. it contains the following code ' push bp save the stack position ' mov bp,sp ' push ax registers needed in the calculations ' push bx ' push dx needed by div and add Header$ = CHR$(&H55) + CHR$(&H8B) + CHR$(&HEC) Header$ = Header$ + CHR$(&H50) + CHR$(&H53) + CHR$(&H52) 'This is the asm trailer needed to transform the formula into an 'assembler subroutine. it contains the following code ' mov bx,[bp+6] determine propper position on the stack ' mov [bx],ax place ax on the stack ' pop dx retore used registers ' pop bx ' pop ax ' mov sp, bp restore the stack position ' pop bp ' retf 2 do a far return to basic Trailer$ = CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6) Trailer$ = Trailer$ + CHR$(&H89) + CHR$(&H7) + CHR$(&H5A) + CHR$(&H5B) + CHR$(&H58) Trailer$ = Trailer$ + CHR$(&H8B) + CHR$(&HE5) + CHR$(&H5D) + CHR$(&HCA) + CHR$(&H2) + CHR$(&H0) 'Make the complete asm subroutine by adding the parts together Program$ = Header$ + Formula$ + Trailer$ DEF SEG = VARSEG(Program$) LetSee% = SADD(Program$) 'And call the routine to see the answer Test% = 0 CALL ABSOLUTE(Test%, LetSee%) PRINT "The result of "; TestFormula$; Test%