def compile(self): """ Emit code for this parser as a function into the global context. """ t_env = TemplateEnvironment() t_env._self = self # Don't emit code twice for the same parser if self.gen_fn_name in get_context().fns: return get_context().fns.add(self.gen_fn_name) t_env.parser_context = ( self.generate_code() ) get_context().generated_parsers.append(GeneratedParser( self.gen_fn_name, render('parsers/fn_profile_ada', t_env), render('parsers/fn_code_ada', t_env)))
def generate_code(self, pos_name="pos"): t_env = TemplateEnvironment(pos_name=pos_name) t_env._self = self t_env.pos, t_env.res = gen_names("row_pos", "row_res") decls = [(t_env.pos, Token)] t_env.subresults = list(gen_names(*[ "row_subres_{0}".format(i) for i in range(len(self.parsers)) ])) t_env.exit_label = gen_name("row_exit_label") self.args = [r for r, m in zip(t_env.subresults, self.parsers) if not m.discard()] self.allargs = [r for r, m in zip(t_env.subresults, self.parsers)] bodies = [] for i, (parser, subresult) in enumerate(zip(self.parsers, t_env.subresults)): t_subenv = TemplateEnvironment( t_env, parser=parser, subresult=subresult, i=i, parser_context=parser.gen_code_or_fncall(t_env.pos) ) decls += t_subenv.parser_context.var_defs if not parser.discard(): decls.append((subresult, parser.get_type())) bodies.append(render('parsers/row_submatch_ada', t_subenv)) code = render('parsers/row_code_ada', t_env, body='\n'.join(bodies)) return ParserCodeContext( pos_var_name=t_env.pos, res_var_name=t_env.res, code=code, var_defs=decls )