News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Using Macros To Overlay A Grammar

Started by cman, October 08, 2009, 05:33:12 PM

Previous topic - Next topic

cman

Can Macros be used to "overlay A grammar" onto masm's input. Say I wanted to make a macro to allow high level expressions in Masm:



eax = eax + ebx;


could this be done with a macro? I've been trying to figure out how to do this. Thanks for any information!

jj2007

I have pushed this a bit to the limits in MasmBasic - download and check masm32\MasmBasic\MbGuide.rtf to see what is feasible. Let My$(3)="Hello"+CrLf+Str$(123) works, but eax = edx+2 is, ehm, difficult. If you find a solution to that one, let me know...

fearless

A pre-processor might be an option, but it would have to 'know' somehow which lines to look at to parse and evaluate.

Another option is to create some sort of runtime parser that evaluates expressions, like Shunting-yard algorithm to convert to Reverse Polish Notation.

Looks like it would be difficult to implement. At a lower level, an assembler or compiler could be made to understand expressions in that format, but you would need to either modify an open source one, or bug an author of an assembler to mod it for that purpose. No mean feat methinks ;-)
ƒearless

qWord

it is possible, but there are limits. You need to write a parser, for such task - and that is not simple. For your example it wouldn't get so hard, as long as you limit the syntax to something like 'a = b [+-*/] c'.

EDIT: here an very simple and incomplete macro for showing how it could done:
SmplMathTokenize macro txt:=<>

    spt_cntr    = 0
    spt_nchar   = 0
    spt_list    TEXTEQU <>
    spt_record  TEXTEQU <>
   
    FORC char,<&txt>
        spt_pos INSTR 1,<=+-*/>,<&char>
        IF spt_pos NE 0
            IF spt_nchar NE 0
                spt_list    CATSTR spt_list,<,>,spt_record,<,>,<&char>
                spt_record  TEXTEQU <>             
                spt_cntr    = spt_cntr + 1
                spt_nchar   = 0
            ELSE
                spt_list    CATSTR spt_list,<,>,<&char>
                spt_cntr    = spt_cntr + 1
            ENDIF
        ELSE
            spt_record CATSTR spt_record,<&char>           
            spt_nchar = spt_nchar + 1
        ENDIF
    ENDM

    IF spt_nchar NE 0
        spt_list    CATSTR spt_list,<,>,spt_record
        spt_cntr    = spt_cntr + 1
    ENDIF

    IF spt_cntr NE 0
        spt_list SUBSTR spt_list,2
    ENDIF
   
    EXITM spt_list
endm

math macro txt:=<>
    m_cntr = 0
    m_error = 0
%   FOR  arg,<SmplMathTokenize(<&txt>)>
        IF m_cntr EQ 0
            m_dest TEXTEQU <&arg>
        ELSEIF m_cntr EQ 1
            IFDIF <&arg>,<=>
                echo syntax error
                m_error = 1
                EXITM
            ENDIF
        ELSEIF m_cntr EQ 2
            m_src1 TEXTEQU <&arg>
        ELSEIF m_cntr EQ 3
            IF @InStr(1,<+-*/>,<&arg>) EQ 0
                echo syntax error
                m_error = 1
                EXITM
            ENDIF
            m_operator = @InStr(1,<+-*/>,<&arg>)
        ELSEIF m_cntr EQ 4
            m_src2 TEXTEQU <&arg>
        ELSE
            echo unexpected char.
            m_error = 1
            EXITM
        ENDIF           
        m_cntr = m_cntr + 1
    ENDM
   
    IF m_error EQ 1
        EXITM
    ENDIF
   
    ; this is a very simple solution - it should be extend ;)
    IF (m_operator EQ 1) OR (m_operator EQ 2)
        IF ((OPATTR m_dest) EQ 48) AND ((OPATTR m_src1) EQ 48) AND ((OPATTR m_src2) EQ 48)
            IF m_operator EQ 2
                neg m_src2
            ENDIF
            lea m_dest,[m_src1+m_src2]
            IF m_operator EQ 2
                neg m_src2
            ENDIF
        ELSE
            IFDIFI m_dest,<eax>
                push eax
                mov eax,m_src1
                IF m_operator EQ 1
                    add eax,m_src2
                ELSE
                    sub eax,m_src2
                ENDIF
                mov m_dest,eax
                pop eax
            ELSE
                push edx
                mov edx,m_src1
                IF m_operator EQ 1
                    add edx,m_src2
                ELSE
                    sub edx,m_src2
                ENDIF
                mov m_dest,edx
                pop edx
            ENDIF
        ENDIF
    ELSEIF (m_operator EQ 3)
        echo not implemented ;)
    ELSE
        echo not implemented ;)
    ENDIF
endm


usage:
;addition:
math eax = ebx + DWORD ptr [esp]

; subtraction:
math eax = ebx - edx
FPU in a trice: SmplMath
It's that simple!

jj2007

Looks good, qWord :U
Some time ago I had arrived at Let MyRes=4+5-G2*(f1+34*3)-G2*f1+2000, but I eventually gave up - too complex.

qWord

Quote from: jj2007 on October 08, 2009, 07:02:00 PM
Some time ago I had arrived at Let MyRes=4+5-G2*(f1+34*3)-G2*f1+2000, but I eventually gave up - too complex.
I'm a bit onwards: (fpu)

fSolveRegConst e,2.718281828
fSolve [eax],<(e^(-0.9*abs([edx])))*sin([edx]*(4^(0.5*abs([edx]))))>


however, the generated code is so bad that I've gave it up  :( - now I'm working on an new Version without recursion...
FPU in a trice: SmplMath
It's that simple!

jj2007

Quote from: qWord on October 08, 2009, 07:11:01 PM
Quote from: jj2007 on October 08, 2009, 07:02:00 PM
Some time ago I had arrived at Let MyRes=4+5-G2*(f1+34*3)-G2*f1+2000, but I eventually gave up - too complex.
I'm a bit onwards: (fpu)

fSolveRegConst e,2.718281828
fSolve [eax],<(e^(-0.9*abs([edx])))*sin([edx]*(4^(0.5*abs([edx]))))>


however, the generated code is so bad that I've gave it up  :( - now I'm working on an new Version without recursion...
Impressing, really. The Masm macro system is damn powerful. My version was without recursion from the very beginning, and the code seemed pretty effective, but keeping track of the FPU "levels" turned out to be very tricky. I even simulated the whole system in a Basic program...

qWord

Quote from: jj2007 on October 08, 2009, 07:19:23 PM
... but keeping track of the FPU "levels" turned out to be very tricky.
that's it - Currently I'm parsing the expression into a 'table' to get a overview about it. My consideration with this is, that it might be possible to make a 'all over' optimization of used registers.
FPU in a trice: SmplMath
It's that simple!

jj2007

Quote from: qWord on October 08, 2009, 07:29:47 PM
Quote from: jj2007 on October 08, 2009, 07:19:23 PM
... but keeping track of the FPU "levels" turned out to be very tricky.
that's it - Currently I'm parsing the expression into a 'table' to get a overview about it. My consideration with this is, that it might be possible to make a 'all over' optimization of used registers.

I currently don't have the time and energy to dive into that, but I hope you are in a better mood. Keep us posted.
You could have my source code, almost 1,000 lines of macros, but it's very confused. If I ever go back to that, I'll start from scratch, and apply what I learned in the last months. Masm is so complex that one keeps learning all the time...

qWord

Quote from: jj2007 on October 08, 2009, 07:45:32 PM
You could have my source code, almost 1,000 lines of macros, but it's very confused.
no, thanks - my own code confuse me enough  :bg
regards, qWord
FPU in a trice: SmplMath
It's that simple!

jj2007

Quote from: qWord on October 08, 2009, 07:53:54 PM
Quote from: jj2007 on October 08, 2009, 07:45:32 PM
You could have my source code, almost 1,000 lines of macros, but it's very confused.
no, thanks - my own code confuse me enough  :bg
regards, qWord

I know, I know - looking at other people's code is a waste of time, unless they are named Iczelion, of cource :wink
Regards
Jochen