def __init__(self, macro_defn, line_num=0, filename='unspecified'): ''' macro_defn = full text of macro such as 'my_macro(x,y) (x + y )' Note: `define has already been stripped. ''' self.name = '' self.argList = [] self.text = '' # body of the macro self.line_num = line_num self.filename = filename # blank macro; `define fred match = VMacro.pat_macro_blank.match(macro_defn) if match: self.name = match.group(1) return #macro with args: `define my_macro(x,y) (x + y ) match = VMacro.pat_macro_with_params.match(macro_defn) if match: self.name = match.group(1) args = match.group(2) self.text = match.group(3) args = args.strip() self.argList = map ( lambda x: x.strip(), args.split(',') ) return # macro without args: `define my_simple_macro vector[10:0] match = VMacro.pat_macro_without_params.match(macro_defn) if match: self.name = match.group(1) self.text = match.group(2) return ParserError.report_syntax_err( ParserError.SE_BAD_MACRO_DEFN, line_num, filename)
def do_macro_substitution(self, line, line_num, filename): ''' Do a single macro substitution (if any). Note: assumes that first backtick is a macro subst - i.e. if it was a `include or something else then you better have dealt with it already. Returns modified line. ''' tick_pos = line.find('`') if tick_pos == -1: return line # get macro name (after the tick) (err, macro_name) = get_simple_identifier_at_offset(line, tick_pos+1) if err: ParserError.report_syntax_err(ParserError.SE_ID_EXPECTED_AFTER_TICK, line_num, filename) if macro_name not in self.macros: ParserError.report_syntax_err(ParserError.SE_MACRO_NOT_DEFINED, line_num, filename) # Must differentiate between macro with args and without. # A macro with args must be followed by '(' immediately after name. nxt_pos = tick_pos + len(macro_name) + 1 if nxt_pos >= len(line) or line[nxt_pos] != '(': # simple macro (no args) line = line[0:tick_pos] + self.macros[macro_name].text + line[nxt_pos:] else: # macro with args (err, arg_end_pos, argL) = get_comma_sep_exprs_from_balanced_string(line, nxt_pos) if err: ParserError.report_syntax_err(err, line_num, filename) macro = self.macros[macro_name] # get the original macro body, replacing formal params with actual args. (err,new_body) = macro.subst_args_in_body(argL) if err: ParserError.report_syntax_err(err, line_num, filename) line = line[0:tick_pos] + new_body + line[arg_end_pos+1:] return line