1.1 --- a/micropython/ast.py Mon Apr 07 02:20:21 2008 +0200
1.2 +++ b/micropython/ast.py Thu Apr 17 23:04:50 2008 +0200
1.3 @@ -296,9 +296,7 @@
1.4
1.5 # Evaluate the arguments.
1.6
1.7 - positional = 1
1.8 - start_keywords = None
1.9 - employed_keywords = set()
1.10 + employed_positions = set()
1.11 extra_keywords = []
1.12
1.13 for frame_pos, arg in enumerate(args):
1.14 @@ -307,13 +305,6 @@
1.15
1.16 if isinstance(arg, compiler.ast.Keyword):
1.17
1.18 - # Note the start of keyword arguments.
1.19 -
1.20 - if positional:
1.21 - #self.new_op(ReserveFrame(len(args) - frame_pos))
1.22 - start_keywords = frame_pos
1.23 - positional = 0
1.24 -
1.25 # Optimise where the target is known now.
1.26
1.27 if target is not None:
1.28 @@ -340,14 +331,16 @@
1.29
1.30 # Test for illegal conditions.
1.31
1.32 - if pos < start_keywords:
1.33 + if pos in employed_positions:
1.34 raise TranslateError(self.module.full_name(), node,
1.35 "Keyword argument %r overwrites parameter %r." % (arg.name, pos))
1.36 - elif pos in employed_keywords:
1.37 - raise TranslateError(self.module.full_name(), node,
1.38 - "Keyword argument %r is repeated, overwriting parameter %r." % (arg.name, pos))
1.39 +
1.40 + employed_positions.add(pos)
1.41
1.42 - employed_keywords.add(pos)
1.43 + # Add space for arguments appearing before this one.
1.44 +
1.45 + if frame_pos < pos:
1.46 + self.new_op(ReserveFrame(pos - frame_pos)
1.47
1.48 # Generate code for the keyword and the positioning
1.49 # operation.
1.50 @@ -355,9 +348,9 @@
1.51 self.dispatch(arg.expr)
1.52
1.53 # If the position corresponds to the current frame element,
1.54 - # skip generating the instruction.
1.55 + # skip generating the store instruction.
1.56
1.57 - if frame_pos != pos:
1.58 + if frame_pos > pos:
1.59 self.new_op(StoreFrame(pos))
1.60
1.61 # Otherwise, generate the code needed to obtain the details of
1.62 @@ -390,16 +383,18 @@
1.63
1.64 else:
1.65 self.dispatch(arg)
1.66 + employed_positions.add(frame_pos)
1.67
1.68 frame_pos = len(args)
1.69
1.70 - # If any extra keywords were identified, generate them now.
1.71 -
1.72 - for arg in extra_keywords:
1.73 - const = self.module.constant_values[arg.name]
1.74 - self.new_op(LoadConst(const))
1.75 - self.dispatch(arg.expr)
1.76 - frame_pos += 1
1.77 + # NOTE: If any extra keywords were identified, generate them now.
1.78 + # NOTE: This needs to populate a ** argument dictionary.
1.79 + #
1.80 + # for arg in extra_keywords:
1.81 + # const = self.module.constant_values[arg.name]
1.82 + # self.new_op(LoadConst(const))
1.83 + # self.dispatch(arg.expr)
1.84 + # frame_pos += 1
1.85
1.86 # NOTE: Somehow, the above needs to be combined with * and ** arguments.
1.87
1.88 @@ -409,15 +404,18 @@
1.89
1.90 # Make sure that enough arguments have been given.
1.91
1.92 + nargs_max = len(target.positional_names)
1.93 ndefaults = len(target.defaults)
1.94 - nargs_max = len(target.positional_names)
1.95 nargs_min = nargs_max - ndefaults
1.96 +
1.97 + for i in range(0, nargs_min):
1.98 + if i not in employed_positions:
1.99 + raise TranslateError(self.module.full_name(), node,
1.100 + "Argument %r not supplied for %r: need at least %d arguments." % (i+1, target.name, nargs_min))
1.101 +
1.102 nargs = len(args)
1.103
1.104 - if nargs < nargs_min:
1.105 - raise TranslateError(self.module.full_name(), node,
1.106 - "Insufficient arguments for %r: need at least %d arguments." % (target.name, nargs_min))
1.107 - elif nargs > nargs_max and not target.has_star and not target.has_dstar:
1.108 + if nargs > nargs_max and not target.has_star and not target.has_dstar:
1.109 raise TranslateError(self.module.full_name(), node,
1.110 "Too many arguments for %r: need at most %d arguments." % (target.name, nargs_max))
1.111
1.112 @@ -425,15 +423,14 @@
1.113 # Here, we use negative index values to visit the right hand end of
1.114 # the defaults list.
1.115
1.116 - for i in range(nargs - nargs_max, 0):
1.117 - self.new_op(LoadConst(target))
1.118 - self.new_op(LoadAttr(target.default_attrs[ndefaults + i]))
1.119 + for pos in range(nargs_min, nargs_max):
1.120 + if pos not in employed_positions:
1.121 + self.new_op(LoadConst(target))
1.122 + self.new_op(LoadAttr(target.default_attrs[pos - nargs_min]))
1.123
1.124 # If the position corresponds to the current frame element,
1.125 # skip generating the instruction.
1.126
1.127 - pos = nargs_max + i
1.128 -
1.129 if frame_pos != pos:
1.130 self.new_op(StoreFrame(pos))
1.131