1.1 --- a/micropython/ast.py Mon Mar 24 23:53:18 2008 +0100
1.2 +++ b/micropython/ast.py Mon Mar 31 00:54:03 2008 +0200
1.3 @@ -48,7 +48,9 @@
1.4
1.5 "A translated module."
1.6
1.7 - def __init__(self, module, objtable, paramtable, builtins=None):
1.8 + supported_optimisations = ["constant_storage", "known_target"]
1.9 +
1.10 + def __init__(self, module, objtable, paramtable, builtins=None, optimisations=None):
1.11
1.12 """
1.13 Initialise the translation with an inspected 'module' and an attribute
1.14 @@ -62,6 +64,10 @@
1.15 self.paramtable = paramtable
1.16 self.builtins = builtins
1.17
1.18 + # Desired optimisations.
1.19 +
1.20 + self.optimisations = set(optimisations or [])
1.21 +
1.22 # The current unit being translated.
1.23
1.24 self.unit = None
1.25 @@ -205,7 +211,9 @@
1.26 # Where the last operation (defining the attribute owner) yields a
1.27 # constant...
1.28
1.29 - if isinstance(last, (LoadName, LoadAttr)) and last.attr.assignments == 1:
1.30 + if self._have_constant_input(0):
1.31 +
1.32 + # Optimise away the constant storage if appropriate.
1.33
1.34 if self._optimise_constant_storage(AttrInstruction, 1):
1.35 return
1.36 @@ -357,13 +365,14 @@
1.37 # Either test for a complete set of arguments.
1.38
1.39 if target is not None:
1.40 - nargs = len(target.positional_names)
1.41 - if len(args) < nargs:
1.42 + nargs_max = len(target.positional_names)
1.43 + nargs_min = nargs_max - len(target.defaults)
1.44 + if len(args) < nargs_min:
1.45 raise TranslateError(self.module.full_name(), node,
1.46 - "Insufficient arguments for %r: need %d arguments." % (target.name, nargs))
1.47 - elif len(args) > nargs and not target.has_star and not target.has_dstar:
1.48 + "Insufficient arguments for %r: need at least %d arguments." % (target.name, nargs_min))
1.49 + elif len(args) > nargs_max and not target.has_star and not target.has_dstar:
1.50 raise TranslateError(self.module.full_name(), node,
1.51 - "Too many arguments for %r: need %d arguments." % (target.name, nargs))
1.52 + "Too many arguments for %r: need at most %d arguments." % (target.name, nargs))
1.53
1.54 # Or generate instructions to do this at run-time.
1.55
1.56 @@ -432,7 +441,23 @@
1.57 else:
1.58 raise TranslateError(self.module.full_name(), node, "No __builtins__ module is available for name %r." % name)
1.59
1.60 - # Optimisation methods.
1.61 + # Optimisation tests.
1.62 +
1.63 + def _should_optimise_constant_storage(self):
1.64 + return "constant_storage" in self.optimisations
1.65 +
1.66 + def _should_optimise_known_target(self):
1.67 + return "known_target" in self.optimisations
1.68 +
1.69 + def _have_constant_input(self, n):
1.70 + last = self.last_ops(n+1)
1.71 + return len(last) > n and (isinstance(last[n], LoadAttr) and last[n].attr.assignments == 1 or
1.72 + isinstance(last[n], LoadConst))
1.73 +
1.74 + def _have_known_target(self):
1.75 + return self._have_constant_input(0)
1.76 +
1.77 + # Optimisation methods. See the supported_optimisations class attribute.
1.78
1.79 def _optimise_constant_storage(self, cls, n):
1.80
1.81 @@ -441,12 +466,8 @@
1.82 also constant, optimise away both operations.
1.83 """
1.84
1.85 - last = self.last_ops(n+1)
1.86 -
1.87 - if cls in (StoreAttr, StoreName) and len(last) > n and \
1.88 - (isinstance(last[n], LoadAttr) and last[n].attr.assignments == 1 or
1.89 - isinstance(last[n], LoadConst)):
1.90 -
1.91 + if self._should_optimise_constant_storage() and cls in (StoreAttr, StoreName) and \
1.92 + self._have_constant_input(n) and self._have_constant_input(n-1):
1.93 self.remove_ops(n+1)
1.94 return 1
1.95 else:
1.96 @@ -460,8 +481,8 @@
1.97 appropriate, get information about the specific initialiser.
1.98 """
1.99
1.100 - last = self.last_op()
1.101 - if isinstance(last, (LoadName, LoadAttr)) and last.attr.assignments == 1:
1.102 + if self._should_optimise_known_target() and self._have_known_target():
1.103 + last = self.last_op()
1.104 target = last.attr.value
1.105 context = last.attr.parent
1.106