class Metasm::AsmPreprocessor

asm-specific preprocessor handles asm arguments (; … eol) asm macros (name macro argsnbody endm, name equ val) initializes token.value (reads integers in hex etc) merges consecutive space/eol

Attributes

macro[RW]

hash macro name => Macro

may_apreprocess[RW]
program[RW]

the program (used to create new label names)

Public Class Methods

new(text='', program=nil) click to toggle source
Calls superclass method
# File metasm/parse.rb, line 182
def initialize(text='', program=nil)
        @program = program
        @may_apreprocess = false
        @macro = {}
        super(text)
end

Public Instance Methods

feed!(*a) click to toggle source
Calls superclass method
# File metasm/parse.rb, line 203
def feed!(*a)
        super(*a)
        if not @may_apreprocess and (@text =~ / (macro|equ) / or not @macro.empty?)
                @may_apreprocess = true
        end
        self
end
nexttok() click to toggle source
# File metasm/parse.rb, line 197
def nexttok
        t = readtok
        unreadtok t
        t
end
readtok() click to toggle source

reads a token, handles macros/comments/etc

Calls superclass method
# File metasm/parse.rb, line 212
def readtok
        tok = super()
        return tok if not tok or tok.alreadyapp

        # handle ; comments
        if tok.type == :punct and tok.raw[0] == ?;
                tok.type = :eol
                begin
                        tok = tok.dup
                        while ntok = super() and ntok.type != :eol
                                tok.raw << ntok.raw
                        end
                        tok.raw << ntok.raw if ntok
                rescue ParseError
                        # unterminated string
                end
        end

        # handle macros
        if @may_apreprocess and tok.type == :string
                if @macro[tok.raw]
                        @macro[tok.raw].apply(tok, self, @program).reverse_each { |t| unreadtok t }
                        tok = readtok
                else
                        if ntok = super() and ntok.type == :space and nntok = super() and nntok.type == :string and (nntok.raw == 'macro' or nntok.raw == 'equ')
                                puts "W: asm: redefinition of macro #{tok.raw} at #{tok.backtrace_str}, previous definition at #{@macro[tok.raw].name.backtrace_str}" if @macro[tok.raw]
                                m = Macro.new tok
                                # XXX this allows nested macro definition..
                                if nntok.raw == 'macro'
                                        m.parse_definition self
                                else
                                        # equ
                                        raise nntok if not etok = readtok
                                        unreadtok etok
                                        raise nntok if not v = Expression.parse(self)
                                        etok = etok.dup
                                        etok.type = :string
                                        etok.value = v
                                        etok.raw = v.to_s
                                        m.body << etok
                                end
                                @macro[tok.raw] = m
                                tok = readtok
                        else
                                unreadtok nntok
                                unreadtok ntok
                        end
                end
        end

        tok.alreadyapp = true if tok
        tok
end
skip_space() click to toggle source
# File metasm/parse.rb, line 193
def skip_space
        readtok while t = nexttok and t.type == :space
end
skip_space_eol() click to toggle source
# File metasm/parse.rb, line 189
def skip_space_eol
        readtok while t = nexttok and (t.type == :space or t.type == :eol)
end