X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fexpressions%2Fgenerate.py;fp=src%2Flanguage%2Fexpressions%2Fgenerate.py;h=ffe780a3c35ab9cbfdd07f016dcc857890605a06;hb=9333137c2283f783d1ea493c41797e7a0a8b0d14;hp=d989a14e390f001f882acadeacddcd76b6a09169;hpb=8b37609fc39ebaed47d9d07520d2e2e04f99f734;p=pspp diff --git a/src/language/expressions/generate.py b/src/language/expressions/generate.py index d989a14e39..ffe780a3c3 100644 --- a/src/language/expressions/generate.py +++ b/src/language/expressions/generate.py @@ -72,6 +72,8 @@ def init_all_types(): # 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 *', @@ -240,7 +242,7 @@ class Op: 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 @@ -369,7 +371,7 @@ def parse_input(): 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': @@ -673,17 +675,14 @@ class Arg: 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: @@ -695,7 +694,7 @@ def print_trailer(): 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: @@ -718,26 +717,34 @@ def generate_evaluate_h(): 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': @@ -778,29 +785,29 @@ def generate_evaluate_inc(): 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 \n') - out_file.write('#include \n\n') + sys.stdout.write('#include \n') + sys.stdout.write('#include \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': @@ -812,10 +819,10 @@ def generate_operations_h(): 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'): @@ -823,37 +830,37 @@ def generate_operations_h(): 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 = [] @@ -907,28 +914,28 @@ def generate_optimize_inc(): % (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 = [] @@ -950,15 +957,16 @@ def generate_parse_inc(): 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) @@ -990,21 +998,20 @@ if __name__ == '__main__': '(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)