1.1 --- a/translator.py Mon Feb 06 22:29:25 2017 +0100
1.2 +++ b/translator.py Mon Feb 06 22:30:47 2017 +0100
1.3 @@ -194,6 +194,9 @@
1.4 self.refs = refs
1.5 self.accessor_kinds = accessor_kinds
1.6
1.7 + def references(self):
1.8 + return self.refs
1.9 +
1.10 def get_origin(self):
1.11 return self.refs and len(self.refs) == 1 and first(self.refs).get_origin()
1.12
1.13 @@ -286,6 +289,8 @@
1.14 else:
1.15 return Expression(str(expr))
1.16
1.17 +
1.18 +
1.19 # The actual translation process itself.
1.20
1.21 class TranslatedModule(CommonModule):
1.22 @@ -1129,20 +1134,32 @@
1.23
1.24 expr = self.process_structure_node(n.node)
1.25 objpath = expr.get_origin()
1.26 +
1.27 + # Identified target details.
1.28 +
1.29 target = None
1.30 target_structure = None
1.31 +
1.32 + # Specific function target information.
1.33 +
1.34 function = None
1.35 +
1.36 + # Instantiation involvement.
1.37 +
1.38 instantiation = False
1.39 literal_instantiation = False
1.40 +
1.41 + # Invocation requirements.
1.42 +
1.43 context_required = True
1.44 -
1.45 - # Obtain details of the callable.
1.46 + parameters = None
1.47 +
1.48 + # Obtain details of the callable and of its parameters.
1.49
1.50 # Literals may be instantiated specially.
1.51
1.52 if expr.is_name() and expr.name.startswith("$L") and objpath:
1.53 instantiation = literal_instantiation = objpath
1.54 - parameters = None
1.55 target = encode_literal_instantiator(objpath)
1.56 context_required = False
1.57
1.58 @@ -1186,7 +1203,30 @@
1.59 # Other targets are retrieved at run-time.
1.60
1.61 else:
1.62 - parameters = None
1.63 + refs = expr.references()
1.64 +
1.65 + # Attempt to test the number of arguments and warn about possible
1.66 + # invocation problems.
1.67 +
1.68 + if refs:
1.69 + for ref in refs:
1.70 + _objpath = ref.get_origin()
1.71 + _parameters = self.importer.function_parameters.get(_objpath)
1.72 +
1.73 + if _parameters is None:
1.74 + continue
1.75 +
1.76 + # Determine whether the possible target has a different
1.77 + # number of parameters to the number of arguments given.
1.78 +
1.79 + num_parameters = len(_parameters)
1.80 + _defaults = len(self.importer.function_defaults.get(_objpath, []))
1.81 +
1.82 + if len(n.args) < num_parameters - _defaults or len(n.args) > num_parameters:
1.83 + print "In %s, at line %d, inappropriate number of " \
1.84 + "arguments given. Need %d arguments to call %s." % (
1.85 + self.get_namespace_path(), n.lineno, num_parameters,
1.86 + _objpath)
1.87
1.88 # Arguments are presented in a temporary frame array with any context
1.89 # always being the first argument. Where it would be unused, it may be
1.90 @@ -1198,6 +1238,9 @@
1.91 else:
1.92 args = ["__NULL"]
1.93
1.94 + # Complete the array with null values, permitting tests for a complete
1.95 + # set of arguments.
1.96 +
1.97 args += [None] * (not parameters and len(n.args) or parameters and len(parameters) or 0)
1.98 kwcodes = []
1.99 kwargs = []
1.100 @@ -1888,9 +1931,6 @@
1.101 self.writeline("}")
1.102
1.103 def statement(self, expr):
1.104 - # NOTE: Should never be None.
1.105 - if not expr:
1.106 - self.writestmt("...;")
1.107 s = str(expr)
1.108 if s:
1.109 self.writestmt("%s;" % s)