Index: sasmodels/autoc.py
===================================================================
--- sasmodels/autoc.py	(revision db0340684d33368d63f9c39a84e1c2398bf1e953)
+++ sasmodels/autoc.py	(revision ef6a512bdc10b7b1960f0ffcc00f147b98c0003a)
@@ -6,4 +6,5 @@
 import ast
 import inspect
+from functools import reduce
 
 import numpy as np
@@ -37,4 +38,6 @@
 }
 
+DEFINES = frozenset("M_PI M_PI_2 M_PI_4 M_SQRT1_2 M_E NAN INFINITY M_PI_180 M_4PI_3".split())
+
 def convert(info, module):
     # type: ("ModelInfo", ModuleType) -> bool
@@ -44,24 +47,24 @@
     # Check if there is already C code
     if info.source or info.c_code is not None:
-        print("a", info.source, info.c_code)
         return
 
     public_methods = "Iq", "Iqxy", "form_volume"
 
-    tagged = []
-    translate = []
+    tagged = [] # type: List[str]
+    translate = [] # type: List[Callable]
     for function_name in public_methods:
         function = getattr(info, function_name)
         if callable(function):
-            translate.append(function)
             tagged.append(function_name)
+            translate.append((function_name, function))
     if not translate:
-        print("b")
-        return  # nothing to translate---maybe Iq, etc. are already C snippets?
+        # nothing to translate---maybe Iq, etc. are already C snippets?
+        return
 
-    deps = []
-    code = []
+    libs = []  # type: List[str]
+    code = {}  # type: Dict[str, str]
+    depends = {}  # type: Dict[str, List[str]]
     while translate:
-        function = translate.pop(0)
+        function_name, function = translate.pop(0)
         source = inspect.getsource(function)
         tree = ast.parse(source)
@@ -70,26 +73,30 @@
         refs = function.__code__.co_names
         snippet = codegen.to_source(tree) #, filename, offset)
-        code.insert(0, snippet)
+        code[function_name] = snippet
+        depends[function_name] = set(refs)
         for name in refs:
+            if name in tagged or name in DEFINES:
+                continue
+            tagged.append(name)
             obj = getattr(module, name, None)
             if obj is None:
                 pass # ignore unbound variables for now
                 #raise ValueError("global %s is not defined" % name)
-            elif getattr(special, name, None):
-                # special symbol: look up depenencies
-                deps.extend(DEPENDENCY.get(name, []))
             elif callable(obj):
-                if name not in tagged:
-                    translate.append(obj)
-                    tagged.append(name)
+                if getattr(special, name, None):
+                    # special symbol: look up depenencies
+                    libs.extend(DEPENDENCY.get(name, []))
+                else:
+                    # not special: add function to translate stack
+                    translate.append((name, obj))
             elif isinstance(obj, float):
-                code.insert(0, "const double %s = %.15g\n"%(name, obj))
+                code[name] = "const double %s = %.15g\n"%(name, obj)
             elif isinstance(obj, int):
-                code.insert(0, "const int %s = %d\n"%(name, obj))
+                code[name] = "const int %s = %d\n"%(name, obj)
             elif isinstance(obj, (list, tuple, np.ndarray)):
                 vals = ", ".join("%.15g"%v for v in obj)
-                code.insert(0, "const double %s[] = {%s};\n" %(name, vals))
+                code[name] = "const double %s[] = {%s};\n" %(name, vals)
             elif isinstance(obj, special.Gauss):
-                deps.append('lib/gauss%d.c'%obj.n)
+                libs.append('lib/gauss%d.c'%obj.n)
             else:
                 raise TypeError("Could not convert global %s of type %s"
@@ -97,11 +104,11 @@
 
     # remove duplicates from the dependecy list
-    unique_deps = []
-    for dep in deps:
-        if dep not in unique_deps:
-            unique_deps.append(dep)
+    unique_libs= []
+    for filename in libs:
+        if filename not in unique_libs:
+            unique_libs.append(filename)
 
-    info.source = unique_deps
-    info.c_code = "\n".join(code)
+    info.source = unique_libs
+    info.c_code = "\n".join(code[k] for k in ordered_dag(depends) if k in code)
 
     info.Iq = info.Iqxy = info.form_volume = None
@@ -111,2 +118,27 @@
 
     raise RuntimeError("not yet converted...")
+
+
+# Modified from the following:
+#
+#    http://code.activestate.com/recipes/578272-topological-sort/
+#    Copyright (C) 2012 Sam Denton
+#    License: MIT
+def ordered_dag(dag):
+    # type: (Dict[T, Set[T]]) -> Iterator[T]
+    dag = dag.copy()
+
+    # make leaves depend on the empty set
+    leaves = reduce(set.union, dag.values()) - set(dag.keys())
+    dag.update({node: set() for node in leaves})
+    while True:
+        leaves = set(node for node, links in dag.items() if not links)
+        if not leaves:
+            break
+        for node in leaves:
+            yield node
+        dag = {node: (links-leaves)
+               for node, links in dag.items() if node not in leaves}
+    if dag:
+        raise ValueError("Cyclic dependes exists amongst these items:\n%s"
+                            % ", ".join(str(node) for node in dag.keys()))
Index: sasmodels/special.py
===================================================================
--- sasmodels/special.py	(revision db0340684d33368d63f9c39a84e1c2398bf1e953)
+++ sasmodels/special.py	(revision ef6a512bdc10b7b1960f0ffcc00f147b98c0003a)
@@ -206,7 +206,4 @@
 from numpy import fmin, fmax, trunc, rint
 from numpy import pi, nan, inf
-NAN = nan
-INFINITY = inf
-
 from scipy.special import gamma as sas_gamma
 from scipy.special import erf as sas_erf
@@ -220,4 +217,6 @@
 # C99 standard math constants
 M_PI, M_PI_2, M_PI_4, M_SQRT1_2, M_E = np.pi, np.pi/2, np.pi/4, np.sqrt(0.5), np.e
+NAN = nan
+INFINITY = inf
 
 # non-standard constants
