On 2007-05-06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > Hey, > > I'm writing a script to generate code. I'm a bit tired of typing > outfile.write(....). Does python have a way to c-like macros? Every > instance of o(...) in the code will be replaced by outfile.write(...)?
Just in case you don't know, you can write an arbitrary number of lines in one write. Below is how I format a usage() message of a program in one write call: def usage(fp): fp.write("Usage: convert options [infile] [outfile]\n" "with\n" " options\n" "\t--prefix=<name-prefix>\t(obligatory)\n" "\t--write-size\t\tWrite a line containing the size\n" "\t--append-zero\t\tAppend a terminating 0 byte\n") ie one multi-line write call. Pyhon concatenates two consequtive string literals for us. Unfortunately, this gets less pretty when inserting variable values. In other code generation code, I normally use a list of lines. Rather than writing everything directly to file, I make a list data structure containing lines, then dump the list to file, as in: lines = [] gencode_first(lines) gencode_second(lines) lines.append("the end") write_lines(lines) where write_lines() is def write_lines(lines): for line in lines: outfile.write(line) outfile.write('\n') (i left out the opening and closing of outfile). I normally do not include the \n in the list but instead add it while writing it to file. This makes life much easier since there are no special last-value problems in the code generator itself. The nice thing here is that 'lines' is a normal data structure which you can manipulate if you like. For more demanding code generators (ie C or C++ code) I use the concept 'sections'. At a global level, the generated code has an 'include', 'declarations', 'definitions', and 'main' section, each section is a list of lines. I use a dictionary for this, like output = { 'incl': [], 'decl': [], 'def': [], 'main': [] } then pass around this in the code generator. Each part of the generator can write in each section, for example when defining a C function, you can write the declaration in the decl section and the definition in the def section at the same time. For example def write_c_function(output): output['decl'].append('int mycfunc(void);') output['def'].extend(['int myfunc(void)', '{' 'return 131;', }' ]) Reducing such a dictionary to a list is then something like def make_lines(sec_list, output): lines = [] for sec in sec_list: lines.extend(output[sec]) return lines And outputting the code is then something like write_lines(make_lines(['incl', 'decl', 'def', 'main'], output)) In this way you can abstract away from the order of code as required by the target language and instead generate code in a nicer order. Note that this section trick can be done recursively. for example, a function can be thought of as a number of sections like funcoutput = { 'header': [], 'opening-bracket' : [], 'localvars':[], 'closing-bracket': [] } so you can generate a function using sections as well, then at the end reduce funcoutput to a list of lines, and insert that in a section of the global 'output'. Last but not least, if you replace the lists by an object, you can do much smarter things. For example, in general you don't want to have double #include lines in the 'incl' section. Instead of worrying about generation of doubles, just make an object that behaves like a list but silently drops doubles. In the same way, you can create a list-like object that handles indenting for you. The possibilities here are endless!! Good luck with your code generation problem, I hope I gave you some ideas of alternative solutions that are available. Albert -- http://mail.python.org/mailman/listinfo/python-list