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
hash macro name => Macro
the program (used to create new label names)
# File metasm/parse.rb, line 173 def initialize(text='', program=nil) @program = program @may_apreprocess = false @macro = {} super(text) end
# File metasm/parse.rb, line 194 def feed!(*a) super(*a) if not @may_apreprocess and (@text =~ / (macro|equ) / or not @macro.empty?) @may_apreprocess = true end self end
# File metasm/parse.rb, line 188 def nexttok t = readtok unreadtok t t end
reads a token, handles macros/comments/etc
# File metasm/parse.rb, line 203 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
# File metasm/parse.rb, line 184 def skip_space readtok while t = nexttok and t.type == :space end
# File metasm/parse.rb, line 180 def skip_space_eol readtok while t = nexttok and (t.type == :space or t.type == :eol) end