# Vectors.
Type.new_leaf('vector', 'const struct vector *',
'vector', 'v', 'vector'),
+ Type.new_any('num_vec_elem', 'double', 'number', 'n',
+ 'number', 'ns', 'SYSMIS'),
# Types as leaves or auxiliary data.
Type.new_leaf('expr_node', 'const struct expr_node *',
for arg in self.args:
arg_name = 'arg_%s' % arg.name
if arg.idx is None:
- if arg.type_.name in ['number', 'boolean']:
+ if arg.type_.name in ['number', 'boolean', 'integer']:
sysmis_cond += ['!is_valid (%s)' % arg_name]
elif arg.type_.name == 'number':
a = arg_name
return_type = Type.parse()
if return_type is None:
return_type = types['number']
- if return_type.name not in ['number', 'string', 'boolean']:
+ if return_type.name not in ['number', 'string', 'boolean', 'num_vec_elem']:
die('%s is not a valid return type' % return_type.name)
if token == 'operator':
def print_header():
"""Prints the output file header."""
- out_file.write("""\
-/* %s
- Generated from %s by generate.py.
- Do not modify! */
-
-""" % (out_file_name, in_file_name))
+ sys.stdout.write("""\
+/* Generated by generate.py. Do not modify! */
+""")
def print_trailer():
"""Prints the output file trailer."""
- out_file.write("""\
+ sys.stdout.write("""\
/*
Local Variables:
def generate_evaluate_h():
- out_file.write('#include "helpers.h"\n\n')
+ sys.stdout.write('#include "helpers.h"\n\n')
for op in order:
if op.unimplemented:
else:
statements = ' return %s;\n' % op.expression
- out_file.write('static inline %s\n' % op.returns.c_type)
- out_file.write('eval_%s (%s)\n' % (op.opname, ', '.join(args)))
- out_file.write('{\n')
- out_file.write(statements)
- out_file.write('}\n\n')
+ sys.stdout.write('static inline %s\n' % op.returns.c_type)
+ sys.stdout.write('eval_%s (%s)\n' % (op.opname, ', '.join(args)))
+ sys.stdout.write('{\n')
+ sys.stdout.write(statements)
+ sys.stdout.write('}\n\n')
def generate_evaluate_inc():
for op in order:
if op.unimplemented:
- out_file.write('case %s:\n' % op.opname)
- out_file.write(' NOT_REACHED ();\n\n')
+ sys.stdout.write('case %s:\n' % op.opname)
+ sys.stdout.write(' NOT_REACHED ();\n\n')
continue
decls = []
args = []
for arg in op.args:
type_ = arg.type_
- c_type = type_.c_type
- args += ['arg_%s' % arg.name]
+ if type_.c_type == 'int ':
+ c_type = 'double '
+ if op.absorb_miss:
+ args += ['arg_%s == SYSMIS ? INT_MIN : arg_%s'
+ % (arg.name, arg.name)]
+ else:
+ args += ['arg_%s' % arg.name]
+ else:
+ c_type = type_.c_type
+ args += ['arg_%s' % arg.name]
if arg.idx is None:
decl = '%sarg_%s' % (c_type, arg.name)
if type_.role == 'any':
stack = op.returns.stack
- out_file.write('case %s:\n' % op.opname)
+ sys.stdout.write('case %s:\n' % op.opname)
if decls:
- out_file.write(' {\n')
+ sys.stdout.write(' {\n')
for decl in decls:
- out_file.write(' %s;\n' % decl)
+ sys.stdout.write(' %s;\n' % decl)
if sysmis_cond is not None:
miss_ret = op.returns.missing_value
- out_file.write(' *%s++ = force_sysmis ? %s : %s;\n'
+ sys.stdout.write(' *%s++ = force_sysmis ? %s : %s;\n'
% (stack, miss_ret, result))
else:
- out_file.write(' *%s++ = %s;\n' % (stack, result))
- out_file.write(' }\n')
+ sys.stdout.write(' *%s++ = %s;\n' % (stack, result))
+ sys.stdout.write(' }\n')
else:
- out_file.write(' *%s++ = %s;\n' % (stack, result))
- out_file.write(' break;\n\n')
+ sys.stdout.write(' *%s++ = %s;\n' % (stack, result))
+ sys.stdout.write(' break;\n\n')
def generate_operations_h():
- out_file.write('#include <stdlib.h>\n')
- out_file.write('#include <stdbool.h>\n\n')
+ sys.stdout.write('#include <stdlib.h>\n')
+ sys.stdout.write('#include <stdbool.h>\n\n')
- out_file.write('typedef enum')
- out_file.write(' {\n')
+ sys.stdout.write('typedef enum')
+ sys.stdout.write(' {\n')
atoms = []
for type_ in types.values():
if type_.role != 'auxonly':
print_operations('operator', 'OP_function_last + 1',
[o.opname for o in opers])
print_range('OP_composite', 'OP_function_first', 'OP_operator_last')
- out_file.write(',\n\n')
+ sys.stdout.write(',\n\n')
print_range('OP', 'OP_atom_first', 'OP_composite_last')
- out_file.write('\n }\n')
- out_file.write('operation_type, atom_type;\n')
+ sys.stdout.write('\n }\n')
+ sys.stdout.write('operation_type, atom_type;\n')
print_predicate('is_operation', 'OP')
for key in ('atom', 'composite', 'function', 'operator'):
def print_operations(type_, first, names):
- out_file.write(' /* %s types. */\n' % type_.title())
- out_file.write(' %s = %s,\n' % (names[0], first))
+ sys.stdout.write(' /* %s types. */\n' % type_.title())
+ sys.stdout.write(' %s = %s,\n' % (names[0], first))
for name in names[1:]:
- out_file.write(' %s,\n' % name)
+ sys.stdout.write(' %s,\n' % name)
print_range('OP_%s' % type_, names[0], names[-1])
- out_file.write(',\n\n')
+ sys.stdout.write(',\n\n')
def print_range(prefix, first, last):
- out_file.write(' %s_first = %s,\n' % (prefix, first))
- out_file.write(' %s_last = %s,\n' % (prefix, last))
- out_file.write(' n_%s = %s_last - %s_first + 1'
+ sys.stdout.write(' %s_first = %s,\n' % (prefix, first))
+ sys.stdout.write(' %s_last = %s,\n' % (prefix, last))
+ sys.stdout.write(' n_%s = %s_last - %s_first + 1'
% (prefix, prefix, prefix))
def print_predicate(function, category):
- out_file.write('\nstatic inline bool\n')
- out_file.write('%s (operation_type op)\n' % function)
- out_file.write('{\n')
+ sys.stdout.write('\nstatic inline bool\n')
+ sys.stdout.write('%s (operation_type op)\n' % function)
+ sys.stdout.write('{\n')
if function != 'is_operation':
- out_file.write(' assert (is_operation (op));\n')
- out_file.write(' return op >= %s_first && op <= %s_last;\n'
+ sys.stdout.write(' assert (is_operation (op));\n')
+ sys.stdout.write(' return op >= %s_first && op <= %s_last;\n'
% (category, category))
- out_file.write('}\n')
+ sys.stdout.write('}\n')
def generate_optimize_inc():
for op in order:
if not op.optimizable or op.unimplemented:
- out_file.write('case %s:\n' % op.opname)
- out_file.write(' NOT_REACHED ();\n\n')
+ sys.stdout.write('case %s:\n' % op.opname)
+ sys.stdout.write(' NOT_REACHED ();\n\n')
continue
decls = []
% (op.returns.c_type, miss_ret, result)]
result = 'result'
- out_file.write('case %s:\n' % op.opname)
+ sys.stdout.write('case %s:\n' % op.opname)
alloc_func = 'expr_allocate_%s' % op.returns.name
if decls:
- out_file.write(' {\n')
+ sys.stdout.write(' {\n')
for decl in decls:
- out_file.write(' %s;\n' % decl)
- out_file.write(' return %s (e, %s);\n' % (alloc_func, result))
- out_file.write(' }\n')
+ sys.stdout.write(' %s;\n' % decl)
+ sys.stdout.write(' return %s (e, %s);\n' % (alloc_func, result))
+ sys.stdout.write(' }\n')
else:
- out_file.write(' return %s (e, %s);\n' % (alloc_func, result))
- out_file.write('\n')
+ sys.stdout.write(' return %s (e, %s);\n' % (alloc_func, result))
+ sys.stdout.write('\n')
def generate_parse_inc():
members = ['""', '""', '0', '0', '0', '{}', '0', '0']
- out_file.write('{%s},\n' % ', '.join(members))
+ sys.stdout.write('{%s},\n' % ', '.join(members))
for type_ in types.values():
if type_.role != 'auxonly':
members = ('"%s"' % type_.name, '"%s"' % type_.human_name,
'0', 'OP_%s' % type_.name, '0', '{}', '0', '0')
- out_file.write('{%s},\n' % ', '.join(members))
+ sys.stdout.write('{%s},\n' % ', '.join(members))
for op in order:
members = []
members += ['%s' % (op.array_arg().times if op.array_arg() else 0)]
- out_file.write('{%s},\n' % ', '.join(members))
+ sys.stdout.write('{%s},\n' % ', '.join(members))
def usage():
print("""\
%s, for generating expression parsers and evaluators from definitions
-usage: generate.py -o OUTPUT [-i INPUT] [-h]
+usage: generate.py -o OUTPUT_TYPE [-i INPUT] [-h] > OUTPUT
-i INPUT input file containing definitions (default: operations.def)
- -o OUTPUT output file
+ -o OUTPUT output file type, one of: evaluate.h, evaluate.inc,
+ operations.h, optimize.inc, parse.inc
-h display this help message
""" % argv0)
sys.exit(0)
'(use --help for help)' % argv0)
in_file = open(in_file_name, 'r')
- out_file = open(out_file_name, 'w')
init_all_types()
parse_input()
print_header()
- if out_file_name.endswith('evaluate.h'):
+ if out_file_name == 'evaluate.h':
generate_evaluate_h()
- elif out_file_name.endswith('evaluate.inc'):
+ elif out_file_name == 'evaluate.inc':
generate_evaluate_inc()
- elif out_file_name.endswith('operations.h'):
+ elif out_file_name == 'operations.h':
generate_operations_h()
- elif out_file_name.endswith('optimize.inc'):
+ elif out_file_name == 'optimize.inc':
generate_optimize_inc()
- elif out_file_name.endswith('parse.inc'):
+ elif out_file_name == 'parse.inc':
generate_parse_inc()
else:
die('%s: unknown output type' % argv0)