1 # This file is part of libFirm.
2 # Copyright (C) 2012 Karlsruhe Institute of Technology.
10 def isAbstract(nodetype):
11 return nodetype in abstracts
14 cls.__is_firm_op = True
17 return hasattr(nodetype, "__is_firm_op")
19 def is_dynamic_pinned(node):
20 return node.pinned in ["memory", "exception"]
23 return hasattr(node, "flags") and "fragile" in node.flags
25 def inout_contains(l, name):
31 def verify_node(node):
32 if not hasattr(node, "pinned"):
33 print "%s: NO PINNED SET" % node.name
34 elif node.pinned not in ["yes", "no", "memory", "exception"]:
35 print "%s: UNKNOWN PINNED MODE: %s" % (node.name, node.pinned)
37 if not hasattr(node, "flags"):
38 if not isAbstract(node):
39 print "WARNING: no flags specified for %s\n" % node.name
40 elif type(node.flags) != list:
41 print "ERROR: flags of %s not a list" % node.name
43 if hasattr(node, "pinned_init") and not is_dynamic_pinned(node):
44 print "ERROR: node %s has pinned_init attribute but is not marked as dynamically pinned" % node.name
45 if hasattr(node, "flags") and "uses_memory" in node.flags:
46 if not inout_contains(node.ins, "mem"):
47 print "ERROR: memory op %s needs an input named 'mem'" % node.name
49 if not is_dynamic_pinned(node):
50 print "ERROR: fragile node %s must be dynamically pinned" % node.name
51 if not hasattr(node, "throws_init"):
52 print "ERROR: fragile node %s needs a throws_init attribute" % node.name
53 if not inout_contains(node.outs, "X_regular"):
54 print "ERROR: fragile node %s needs an output named 'X_regular'" % node.name
55 if not inout_contains(node.outs, "X_except"):
56 print "ERROR: fragile node %s needs an output named 'X_except'" % node.name
58 if hasattr(node, "throws_init"):
59 print "ERROR: throws_init only makes sense for fragile nodes"
62 def setldefault(node, attr, val):
63 # Don't use hasattr, as these things should not be inherited
64 if attr not in node.__dict__:
65 setattr(node, attr, val)
67 def setdefault(node, attr, val):
68 # Don't use hasattr, as these things should not be inherited
69 if not hasattr(node, attr):
70 setattr(node, attr, val)
72 def setnodedefaults(node):
73 setldefault(node, "name", node.__name__)
77 setdefault(node, "ins", [])
78 setdefault(node, "arity", len(node.ins))
79 setdefault(node, "attrs", [])
80 setdefault(node, "constructor_args", [])
81 setdefault(node, "customSerializer", False)
82 if hasattr(node, "__doc__"):
83 node.doc = trim_docstring(node.__doc__)
86 if hasattr(node, "outs"):
89 def load_spec(filename):
90 module = imp.load_source('spec', filename)
92 for x in module.__dict__.values():
98 nodes.sort(key=lambda x: x.name)
101 print "Warning: No nodes found in spec file '%s'" % filename
102 if not hasattr(module, "name"):
103 print "Warning: No name specified in file '%s'" % filename
106 def trim_docstring(docstring):
109 # Convert tabs to spaces (following the normal Python rules)
110 # and split into a list of lines:
111 lines = docstring.expandtabs().splitlines()
112 # Determine minimum indentation (first line doesn't count):
114 for line in lines[1:]:
115 stripped = line.lstrip()
117 indent = min(indent, len(line) - len(stripped))
118 # Remove indentation (first line is special):
119 trimmed = [lines[0].strip()]
120 if indent < sys.maxint:
121 for line in lines[1:]:
122 trimmed.append(line[indent:].rstrip())
123 # Strip off trailing and leading blank lines:
124 while trimmed and not trimmed[-1]:
126 while trimmed and not trimmed[0]:
128 # Return a single string:
129 return '\n'.join(trimmed)