From: Ben Pfaff Date: Tue, 14 Dec 2021 06:24:05 +0000 (-0800) Subject: sysmis_decl X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1353faaa410617a7896e85a942e9900e9b3442e8;p=pspp sysmis_decl --- diff --git a/src/language/expressions/generate.py b/src/language/expressions/generate.py index 9edcc3a4d3..4d42c112cf 100644 --- a/src/language/expressions/generate.py +++ b/src/language/expressions/generate.py @@ -200,6 +200,41 @@ class Op: else: return None + def sysmis_decl(self, min_valid_src): + """Returns a declaration for a boolean variable called `force_sysmis', + which will be true when this operation should be + system-missing. Returns None if there are no such + circumstances. + + If this operation has a minimum number of valid arguments, + 'min_valid_src' should be an an expression that evaluates to + the minimum number of valid arguments for this operation. + + """ + sysmis_cond = [] + if not self.absorb_miss: + for arg in self.args: + arg_name = 'arg_%s' % arg.name + if arg.idx is None: + if arg.type_.name in ['number', 'boolean']: + sysmis_cond += ["!is_valid (%s)" % arg_name] + elif arg.type_.name == 'number': + a = arg_name + n = 'arg_%s' % arg.idx + sysmis_cond += ['count_valid (%s, %s) < %s' % (a, n, n)] + elif self.min_valid > 0: + args = self.args + arg = args[-1] + a = 'arg_%s' % arg.name + n = 'arg_%s' % arg.idx + sysmis_cond += ["count_valid (%s, %s) < %s" % (a, n, min_valid_src)] + for arg in self.args: + if arg.condition is not None: + sysmis_cond += ['!(%s)' % arg.condition] + if sysmis_cond: + return 'bool force_sysmis = %s' % ' || '.join(sysmis_cond) + return None + def parse_input(): """Parses the entire input. @@ -660,7 +695,7 @@ def generate_evaluate_inc(): elif type_.role == 'fixed': args += [type_.fixed_value] - sysmis_cond = make_sysmis_decl(op, 'op++->integer') + sysmis_cond = op.sysmis_decl('op++->integer') if sysmis_cond is not None: decls += [sysmis_cond] @@ -758,7 +793,7 @@ def generate_optimize_inc(): decls += ["%s*arg_%s = get_%s_args (node, %s, arg_%s, e)" % (c_type, name, type_.atom, arg_idx, arg.idx)] arg_idx += 1 - sysmis_cond = make_sysmis_decl (op, "node->min_valid") + sysmis_cond = op.sysmis_decl("node->min_valid") if sysmis_cond is not None: decls += [sysmis_cond] @@ -876,40 +911,6 @@ def generate_parse_inc(): # Utilities. -def make_sysmis_decl(op, min_valid_src): - """Returns a declaration for a boolean variable called `force_sysmis', - which will be true when operation 'op' should be system-missing. - Returns None if there are no such circumstances. - - If 'op' has a minimum number of valid arguments, 'min_valid_src' - should be an an expression that evaluates to the minimum number of - valid arguments for 'op'. - - """ - sysmis_cond = [] - if not op.absorb_miss: - for arg in op.args: - arg_name = 'arg_%s' % arg.name - if arg.idx is None: - if arg.type_.name in ['number', 'boolean']: - sysmis_cond += ["!is_valid (%s)" % arg_name] - elif arg.type_.name == 'number': - a = arg_name - n = 'arg_%s' % arg.idx - sysmis_cond += ['count_valid (%s, %s) < %s' % (a, n, n)] - elif op.min_valid > 0: - args = op.args - arg = args[-1] - a = 'arg_%s' % arg.name - n = 'arg_%s' % arg.idx - sysmis_cond += ["count_valid (%s, %s) < %s" % (a, n, min_valid_src)] - for arg in op.args: - if arg.condition is not None: - sysmis_cond += ['!(%s)' % arg.condition] - if sysmis_cond: - return 'bool force_sysmis = %s' % ' || '.join(sysmis_cond) - return None - def usage(): print("""\ %(argv0)s, for generating expression parsers and evaluators from definitions