Commit 76750ffb authored by Robert Bradshaw's avatar Robert Bradshaw

Added pre-import option, which assumes all undeclared names come from the given module.

Emulates behavior of

from <module> import *
parent 4bce9494
......@@ -18,6 +18,9 @@ Options:
-o, --output-file <filename> Specify name of generated C file
-p, --embed-positions If specified, the positions in Pyrex files of each
function definition is embedded in its docstring.
-z, --pre-import <module> If specified, assume undeclared names in this
module. Emulates the behavior of putting
"from <module> import *" at the top of the file.
"""
#The following experimental options are supported only on MacOSX:
# -C, --compile Compile generated .c file to .o file
......@@ -70,6 +73,8 @@ def parse_command_line(args):
options.output_file = pop_arg()
elif option in ("-p", "--embed-positions"):
Options.embed_pos_in_docstring = 1
elif option in ("-z", "--pre-import"):
Options.pre_import = pop_arg()
else:
bad_usage()
else:
......
......@@ -311,7 +311,7 @@ class CCodeWriter:
lbl)
def error_goto_if(self, cond, pos):
if Options.gcc_branch_hints or 0: # TODO this path is almost _never_ taken, yet this macro makes is slower!
if Options.gcc_branch_hints:
return "if (unlikely(%s)) %s" % (cond, self.error_goto(pos))
else:
return "if (%s) %s" % (cond, self.error_goto(pos))
......
......@@ -163,6 +163,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln('')
code.putln('static PyObject *%s;' % env.module_cname)
code.putln('static PyObject *%s;' % Naming.builtins_cname)
if Options.pre_import is not None:
code.putln('static PyObject *%s;' % Naming.preimport_cname)
code.putln('static int %s;' % Naming.lineno_cname)
code.putln('static char *%s;' % Naming.filename_cname)
code.putln('static char **%s;' % Naming.filetable_cname)
......@@ -1122,6 +1124,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.module_cname,
Naming.builtins_cname,
code.error_goto(self.pos)))
if Options.pre_import is not None:
code.putln(
'%s = PyImport_AddModule("%s");' % (
Naming.preimport_cname,
Options.pre_import))
code.putln(
"if (!%s) %s;" % (
Naming.preimport_cname,
code.error_goto(self.pos)));
def generate_intern_code(self, env, code):
if env.intern_map:
......
......@@ -35,6 +35,7 @@ args_cname = pyrex_prefix + "args"
kwdlist_cname = pyrex_prefix + "argnames"
obj_base_cname = pyrex_prefix + "base"
builtins_cname = pyrex_prefix + "b"
preimport_cname = pyrex_prefix + "i"
moddict_cname = pyrex_prefix + "d"
dummy_cname = pyrex_prefix + "dummy"
filename_cname = pyrex_prefix + "filename"
......
......@@ -7,3 +7,5 @@ cache_builtins = 1 # Perform lookups on builtin names only once
embed_pos_in_docstring = 0
gcc_branch_hints = 1
pre_import = None
......@@ -448,12 +448,27 @@ class Scope:
return 1
return 0
class PreImportScope(Scope):
def __init__(self):
Scope.__init__(self, Options.pre_import, None, None)
def declare_builtin(self, name, pos):
entry = self.declare(name, name, py_object_type, pos)
entry.is_variable = True
entry.is_pyglobal = True
entry.namespace_cname = Naming.preimport_cname
return entry
class BuiltinScope(Scope):
# The builtin namespace.
def __init__(self):
if Options.pre_import is None:
Scope.__init__(self, "__builtin__", None, None)
else:
Scope.__init__(self, "__builtin__", PreImportScope(), None)
for name, definition in self.builtin_functions.iteritems():
if len(definition) < 4: definition.append(None) # exception_value
if len(definition) < 5: definition.append(False) # exception_check
......@@ -468,6 +483,9 @@ class BuiltinScope(Scope):
def declare_builtin(self, name, pos):
if not hasattr(__builtin__, name):
if self.outer_scope is not None:
return self.outer_scope.declare_builtin(name, pos)
else:
error(pos, "undeclared name not builtin: %s"%name)
entry = self.declare(name, name, py_object_type, pos)
if Options.cache_builtins:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment