sysmis_decl
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 14 Dec 2021 06:24:05 +0000 (22:24 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 14 Dec 2021 06:24:05 +0000 (22:24 -0800)
src/language/expressions/generate.py

index 9edcc3a4d3b3ec95ee65772ff3e1967e1c10730f..4d42c112cff78fd5b6228912a3b97555efa1903c 100644 (file)
@@ -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():
 \f
 # 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