while not match(')'):
arg = parse_arg()
op['ARGS'] += [arg]
- if 'IDX' in arg:
+ if arg.idx is not None:
if match(')'):
break
sys.stderr.write('array must be last argument\n')
break
for arg in op['ARGS']:
- if 'CONDITION' in arg:
- any_arg = '|'.join([a['NAME'] for a in op['ARGS']])
- arg['CONDITION'] = re.sub(r'\b(%s)\b' % any_arg, r'arg_\1',
- arg['CONDITION'])
+ if arg.condition is not None:
+ any_arg = '|'.join([a.name for a in op['ARGS']])
+ arg.condition = re.sub(r'\b(%s)\b' % any_arg, r'arg_\1', arg.condition)
opname = 'OP_' + op['NAME']
opname = opname.replace('.', '_')
if op['CATEGORY'] == 'function':
- print(op)
- mangle = ''.join([a['TYPE']['MANGLE'] for a in op['ARGS']])
+ mangle = ''.join([a.type_['MANGLE'] for a in op['ARGS']])
op['MANGLE'] = mangle
opname += '_' + mangle
op['OPNAME'] = opname
if aa is None:
sys.stderr.write("can't have minimum valid count without array arg\n")
sys.exit(1)
- if aa['TYPE']['NAME'] != 'number':
+ if aa.type_['NAME'] != 'number':
sys.stderr.write('minimum valid count allowed only with double array\n')
sys.exit(1)
- if aa['TIMES'] != 1:
+ if aa.times != 1:
sys.stderr.write("can't have minimu valid count if array has multiplication factor\n")
sys.exit(1)
if op['RETURNS']['NAME'] == 'string' and not op['ABSORB_MISS']:
for arg in op['ARGS']:
- if arg['TYPE']['NAME'] in ['number', 'boolean']:
+ if arg.type_['NAME'] in ['number', 'boolean']:
sys.stderr.write("'%s' returns string and has double or bool "
"argument, but is not marked ABSORB_MISS\n"
% op['NAME'])
sys.exit(1)
- if 'CONDITION' in arg:
+ if arg.condition is not None:
sys.stderr.write("'%s' returns string but has argument with condition\n")
sys.exit(1)
if toktype == 'eof':
return
- print('%s %s' % (line, toktype))
m = re.match(r'([a-zA-Z_][a-zA-Z_.0-9]*)(.*)$', line)
if m:
token, line = m.groups()
s = ""
nest = 0
global line
- print("line='%s'" % line)
while True:
- print(type(line))
for idx, c in enumerate(line):
- print('nest=%s %s end=%s' % (nest, c, end))
if c in end and nest == 0:
line = line[idx:]
if swallow_end:
global line_number
line = in_file.readline()
line_number += 1
- print("%s\n" % line_number)
if line == '':
line = None
else:
sys.stderr.write("parse error at `%s' expecting `%s'\n" % (token, tok))
sys.exit(1)
+class Arg:
+ def __init__(self, name, type_, idx, times, condition):
+ self.name = name
+ self.type_ = type_
+ self.idx = idx
+ self.times = times
+ self.condition = condition
+
def parse_arg():
"""Parses and returns a function argument."""
- arg = {}
- arg['TYPE'] = parse_type()
- if arg['TYPE'] is None:
- arg['TYPE'] = types['number']
+ type_ = parse_type()
+ if type_ is None:
+ type_ = types['number']
if toktype != 'id':
sys.stderr.write("argument name expected at `%s'\n" % token)
sys.exit(1)
- arg['NAME'] = token
+ name = token
lookahead()
global line
- print("line[0]=%s" % line[0])
+
+ idx = None
+ times = 1
+
if line[0] in "[,)":
get_token()
- print('token=%s toktype=%s' % (token, toktype))
if match('['):
- if arg['TYPE']['NAME'] not in ('number', 'string'):
+ if type_['NAME'] not in ('number', 'string'):
sys.stderr.write('only double and string arrays supported\n')
sys.exit(1)
- arg['IDX'] = force('id')
+ idx = force('id')
if match('*'):
- arg['TIMES'] = force('int')
- if arg['TIMES'] != 2:
+ times = force('int')
+ if times != 2:
sys.stderr.write('multiplication factor must be two\n')
sys.exit(1)
- else:
- arg['TIMES'] = 1
force_match(']')
+ condition = None
else:
- arg['CONDITION'] = arg['NAME'] + ' ' + accumulate_balanced(',)', swallow_end=False)
+ condition = name + ' ' + accumulate_balanced(',)', swallow_end=False)
get_token()
- return arg
+
+ return Arg(name, type_, idx, times, condition)
def print_header():
"""Prints the output file header."""
args = []
for arg in op['ARGS']:
- if 'IDX' not in arg:
- args += [c_type(arg['TYPE']) + arg['NAME']]
+ if arg.idx is None:
+ args += [c_type(arg.type_) + arg.name]
else:
- args += [c_type(arg['TYPE']) + arg['NAME'] + '[]']
- args += ['size_t %s' % arg['IDX']]
+ args += [c_type(arg.type_) + arg.name + '[]']
+ args += ['size_t %s' % arg.idx]
for aux in op['AUX']:
args += [c_type(aux['TYPE']) + aux['NAME']]
if not args:
decls = []
args = []
for arg in op['ARGS']:
- name = arg['NAME']
- type_ = arg['TYPE']
+ type_ = arg.type_
ctype = c_type(type_)
- args += ['arg_%s' % name]
- if 'IDX' not in arg:
- decl = '%sarg_%s' % (ctype, name)
+ args += ['arg_%s' % arg.name]
+ if arg.idx is None:
+ decl = '%sarg_%s' % (ctype, arg.name)
if type_['ROLE'] == 'any':
decls = ['%s = *--%s' % (decl, type_['STACK'])] + decls
elif type_['ROLE'] == 'leaf':
else:
assert False
else:
- idx = arg['IDX']
+ idx = arg.idx
stack = type_['STACK']
- decls = ['%s*arg_%s = %s -= arg_%s' % (ctype, name, stack, idx)] + decls
+ decls = ['%s*arg_%s = %s -= arg_%s' % (ctype, arg.name, stack, idx)] + decls
decls = ['size_t arg_%s = op++->integer' % idx] + decls
idx = 'arg_%s' % idx
- if arg['TIMES'] != 1:
- idx += ' / %s' % arg['TIMES']
+ if arg.times != 1:
+ idx += ' / %s' % arg.times
args += [idx]
for aux in op['AUX']:
type_ = aux['TYPE']
if sysmis_cond is not None:
decls += [sysmis_cond]
- print(args)
result = 'eval_%s (%s)' % (op['OPNAME'], ', '.join(args))
stack = op['RETURNS']['STACK']
decls = []
arg_idx = 0
for arg in op['ARGS']:
- name = arg['NAME']
- type_ = arg['TYPE']
+ name = arg.name
+ type_ = arg.type_
ctype = c_type(type_)
- if not 'IDX' in arg:
+ if arg.idx is None:
func = "get_%s_arg" % type_['ATOM']
decls += ["%sarg_%s = %s (node, %s)" % (ctype, name, func, arg_idx)]
else:
- idx = arg['IDX']
- decl = "size_t arg_%s = node->n_args" % idx
+ decl = "size_t arg_%s = node->n_args" % arg.idx
if arg_idx > 0:
decl += " - %s" % arg_idx
decls += [decl]
- decls += ["%s*arg_%s = get_%s_args (node, %s, arg_%s, e)" % (ctype, name, type_['ATOM'], arg_idx, idx)]
+ decls += ["%s*arg_%s = get_%s_args (node, %s, arg_%s, e)" % (ctype, name, type_['ATOM'], arg_idx, arg.idx)]
arg_idx += 1
sysmis_cond = make_sysmis_decl (op, "node->min_valid")
args = []
for arg in op['ARGS']:
- args += ["arg_%s" % arg['NAME']]
- if 'IDX' in arg:
- idx = 'arg_%s' % arg['IDX']
- if arg['TIMES'] != 1:
- idx += " / %s" % arg['TIMES']
+ args += ["arg_%s" % arg.name]
+ if arg.idx is not None:
+ idx = 'arg_%s' % arg.idx
+ if arg.times != 1:
+ idx += " / %s" % arg.times
args += [idx]
for aux in op['AUX']:
args = []
opt_args = []
for arg in op['ARGS']:
- if 'IDX' not in arg:
- args += [arg['TYPE']['HUMAN_NAME']]
+ if arg.idx is None:
+ args += [arg.type_['HUMAN_NAME']]
array = array_arg(op)
if array is not None:
if op['MIN_VALID'] == 0:
array_args = []
- for i in range(array['TIMES']):
- array_args += [array['TYPE']['HUMAN_NAME']]
+ for i in range(array.times):
+ array_args += [array.type_['HUMAN_NAME']]
args += array_args
opt_args = array_args
else:
for i in range(op['MIN_VALID']):
- args += [array['TYPE']['HUMAN_NAME']]
- opt_args += [array['TYPE']['HUMAN_NAME']]
+ args += [array.type_['HUMAN_NAME']]
+ opt_args += [array.type_['HUMAN_NAME']]
human = "%s(%s" % (op['NAME'], ', '.join(args))
if opt_args:
human += '[, %s]...' % ', '.join(opt_args)
members += ['%s' % len(op['ARGS'])]
- arg_types = ["OP_%s" % arg['TYPE']['NAME'] for arg in op['ARGS']]
+ arg_types = ["OP_%s" % arg.type_['NAME'] for arg in op['ARGS']]
members += ['{%s}' % ', '.join(arg_types)]
members += ['%s' % op['MIN_VALID']]
- members += ['%s' % (array_arg(op)['TIMES'] if array_arg(op) else 0)]
+ members += ['%s' % (array_arg(op).times if array_arg(op) else 0)]
out_file.write('{%s},\n' % ', '.join(members))
\f
sysmis_cond = []
if not op['ABSORB_MISS']:
for arg in op['ARGS']:
- arg_name = 'arg_%s' % arg['NAME']
- if 'IDX' not in arg:
- if arg['TYPE']['NAME'] in ['number', 'boolean']:
+ 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':
+ elif arg.type_['NAME'] == 'number':
a = arg_name
- n = 'arg_%s' % arg['IDX']
+ 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']
+ 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 'CONDITION' in arg:
- sysmis_cond += ['!(%s)' % arg['CONDITION']]
+ if arg.condition is not None:
+ sysmis_cond += ['!(%s)' % arg.condition]
if sysmis_cond:
return 'bool force_sysmis = %s' % ' || '.join(sysmis_cond)
return None
if not args:
return None
last_arg = args[-1]
- if 'IDX' in last_arg:
+ if last_arg.idx is not None:
return last_arg
return None