Use setdefault in several cases to simplify code
[libfirm] / scripts / gen_ir_io.py
index b25ed23..d9a77ef 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 import sys
 from jinja2 import Environment, Template
 import ir_spec
@@ -46,12 +46,12 @@ def get_io_type(type, attrname, nodename):
        elif type == "pn_Cmp" or type == "ir_where_alloc":
                importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
                exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);"""
-       elif type == "cons_flags" and nodename == "Store":
+       elif type == "ir_cons_flags" and nodename == "Store":
                importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
                exportcmd = """write_pin_state(env, irn);
                        write_volatility(env, irn);
                        write_align(env, irn);"""
-       elif type == "cons_flags" and nodename == "Load":
+       elif type == "ir_cons_flags" and nodename == "Load":
                importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
                exportcmd = """write_pin_state(env, irn);
                        write_volatility(env, irn);
@@ -62,9 +62,18 @@ def get_io_type(type, attrname, nodename):
        elif type == "ir_builtin_kind":
                importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname
                exportcmd = "write_builtin_kind(env, irn);"
+       elif type == "cond_kind":
+               importcmd = "cond_kind %s = read_cond_kind(env);" % attrname
+               exportcmd = "write_cond_kind(env, irn);"
+       elif type == "cond_jmp_predicate":
+               importcmd = "cond_jmp_predicate %s = read_cond_jmp_predicate(env);" % attrname
+               exportcmd = "write_cond_jmp_predicate(env, irn);"
        elif type == "int":
                importcmd = "int %s = (int) read_long(env);" % attrname
                exportcmd = """fprintf(env->file, "%%d ", %(val)s);"""
+       elif type == "long":
+               importcmd = "long %s = read_long(env);" % attrname
+               exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
        else:
                print "UNKNOWN TYPE: %s" % type
                importcmd = """// BAD: %s %s
@@ -144,6 +153,8 @@ def preprocess_node(nodename, node):
 
        # construct node arguments
        arguments = [ ]
+       initargs = [ ]
+       specialconstrs = [ ]
        i = 0
        for input in node["ins"]:
                arguments.append("prednodes[%i]" % i)
@@ -163,17 +174,49 @@ def preprocess_node(nodename, node):
        if "mode" not in node:
                arguments.append("mode")
 
+       attrs_with_special = 0
        for attr in node["attrs"]:
                if nodename == "Builtin" and attr["name"] == "kind":
                        continue
                prepare_attr(nodename, attr)
-               arguments.append(attr["name"])
+               if "special" in attr:
+                       if not "init" in attr:
+                               print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % nodename
+                               sys.exit(1)
+
+                       if attrs_with_special != 0:
+                               print "Node type %s has more than one attribute with a \"special\" entry" % nodename
+                               sys.exit(1)
+
+                       attrs_with_special += 1
+
+                       if "prefix" in attr["special"]:
+                               specialname = attr["special"]["prefix"] + nodename
+                       elif "suffix" in attr["special"]:
+                               specialname = nodename + attr["special"]["suffix"]
+                       else:
+                               print "Unknown special constructor type for node type %s" %nodename
+                               sys.exit(1)
+
+                       specialconstrs.append(
+                               dict(
+                                       constrname = specialname,
+                                       attrname = attr["name"],
+                                       value = attr["special"]["init"]
+                               )
+                       )
+               elif "init" in attr:
+                       initargs.append(attr["name"])
+               else:
+                       arguments.append(attr["name"])
 
        for arg in node["constructor_args"]:
                prepare_attr(nodename, arg)
                arguments.append(arg["name"])
 
        node["arguments"] = arguments
+       node["initargs"] = initargs
+       node["special_constructors"] = specialconstrs
 
 export_attrs_template = env.from_string('''
        case iro_{{nodename}}:
@@ -190,7 +233,13 @@ import_attrs_template = env.from_string('''
                {% for attr in node.attrs %}{{attr.importcmd}}
                {% endfor %}
                {% for attr in node.constructor_args %}{{attr.importcmd}}
-               {% endfor %}newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
+               {% endfor %}
+               {% for special in node.special_constructors %}if({{special.attrname}} == {{special.value}})
+                       newnode = new_r_{{special.constrname}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
+               else{% endfor %}
+               newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
+               {% for initarg in node.initargs %}set_{{nodename}}_{{initarg}}(newnode, {{initarg}});
+               {% endfor %}
                break;
        }
 ''')