metasm/parse.rb in metasm-1.0.3 vs metasm/parse.rb in metasm-1.0.4

- old
+ new

@@ -24,23 +24,15 @@ # find prefixes, break on opcode name while tok = lexer.readtok and parse_prefix(i, tok.raw) lexer.skip_space_eol end + + lexer.unreadtok(tok) + tok = parse_instruction_mnemonic(lexer) return if not tok - # allow '.' in opcode name - tok = tok.dup - while ntok = lexer.nexttok and ntok.type == :punct and ntok.raw == '.' - tok.raw << lexer.readtok.raw - ntok = lexer.readtok - raise tok, 'invalid opcode name' if not ntok or ntok.type != :string - tok.raw << ntok.raw - end - - raise tok, 'invalid opcode' if not opcode_list_byname[tok.raw] - i.opname = tok.raw i.backtrace = tok.backtrace lexer.skip_space # find arguments list @@ -61,10 +53,27 @@ parse_instruction_fixup(i) i end + # return a lexer token with an instruction mnemonic in #raw + # allows '.' in opcode name + # return nil at eof + def parse_instruction_mnemonic(lexer) + return if not tok = lexer.readtok + tok = tok.dup + while ntok = lexer.nexttok and ntok.type == :punct and ntok.raw == '.' + tok.raw << lexer.readtok.raw + ntok = lexer.readtok + raise tok, 'invalid opcode name' if not ntok or ntok.type != :string + tok.raw << ntok.raw + end + + raise tok, 'invalid opcode' if not opcode_list_byname[tok.raw] + tok + end + def parse_instruction_checkproto(i) opcode_list_byname[i.opname].to_a.find { |o| o.args.length == i.args.length and o.args.zip(i.args).all? { |f, a| parse_arg_valid?(o, f, a) } } end @@ -419,11 +428,11 @@ end raise tok, 'syntax error' if ntok = @lexer.nexttok and ntok.type != :eol @cursource << Padding.new(fillwith, tok.backtrace) << Offset.new(e, tok.backtrace) else - @cpu.parse_parser_instruction(self, tok) + @cpu.parse_parser_instruction(@lexer, tok) end end def parse_data raise ParseError, 'internal error' if not tok = @lexer.readtok @@ -744,9 +753,11 @@ val end # for boolean operators, true is 1 (or anything != 0), false is 0 def parse(lexer) + lexer = Preprocessor.new(lexer) if lexer.kind_of?(::String) + opstack = [] stack = [] return if not e = parse_value(lexer)