if statement[1] not in format:
nonfatal("uninitialized format string" +`statement[1]`)
else:
- (fmt, types) = fmt_convert(format[statement[1]])
+ types = deduce_types(fmt_convert(format[statement[1]]))
for (vtype, var) in zip(types, statement[2:]):
if type(var) == type(()) and var[0] == 'range':
typedict[var[1]] = vtype
#print "->fmt_convert(%s)" % str
fmt = str
res = ''
- types = []
while True:
if str[0] == '*':
break
# Now process the actual format item
if str[0] == '(':
i = str.find(')')
- (innerfmt, innertypes) = fmt_convert(str[1:i]+"*")
- res += innerfmt * count
+ res += fmt_convert(str[1:i]+"*") * count
str = str[i+1:]
- for i in range(count):
- types += innertypes * count
elif str[0] == 'C':
i = 1
while str[i] in '0123456789':
i += 1
res += "%" + `count * int(str[1:i])` + "s"
str = str[i:]
- types += ['char']
elif str[0] == 'F':
i = 1
while str[i] in '0123456789.':
i += 1
res += ('%' + str[1:i] + 'g') * count
str = str[i:]
- types += ['double'] * count
elif str[0] == 'H':
res += str[1:count+1]
str = str[count+1:]
- types += ['char']
elif str[0] == 'I':
i = 1
while str[i] in '0123456789':
lenprefix = ''
res += ('%' + lenprefix + 'd') * count
str = str[i:]
- types += ['int'] * count
else:
nonfatal('invalid field code %s at %d in format string %s!\n' % (`str[0]`, len(fmt)-len(str), `fmt`))
#print "<-fmt_convert() = %s" % res
- return (res, types)
+ return res
+
+def deduce_types(str):
+ "Deduce types from C format string converted from MAD format."
+ types = []
+ state = 0
+ # Simplified by the fact that MAD strings can't contain %.
+ for i in range(len(str)):
+ if str[i] == "%":
+ state = 1
+ elif state == 1:
+ if str[i].isdigit() or str[i] in ('.', '-', '+'):
+ continue
+ if str[i] == 's':
+ types.append("char")
+ elif str[i] == 'g':
+ types.append("double")
+ elif str[i] == 'd':
+ types.append("int")
+ else:
+ state = 0
+ return types
def lptcodes(res):
- "Interpret format character"
+ "Interpret line-printer control character at start of format string."
if res[0] == ' ': # Single space
res = res[1:]
elif res[0] == '0': # Double space
elif statement[0] == 'pause':
return('printf("%o", ' + print_C_expr(statement[1]) + '); getchar();')
elif statement[0] == 'print':
- (fmt, types) = fmt_convert(format[statement[1]])
- fmt = lptcodes(fmt)
+ fmt = lptcodes(fmt_convert(format[statement[1]]))
if len(statement) < 3:
return 'printf("' + fmt + '");'
else:
return 'printf("' + fmt + '", ' + ', '.join(map(print_C_expr, statement[2:])) + ');'
elif statement[0] == 'read':
- (fmt, types) = fmt_convert(format[statement[1]])
+ fmt = fmt_convert(format[statement[1]])
+ types = deduce_types(fmt)
inlist = []
for (ispec, itype) in zip(statement[2:], types):
if type(ispec) == type(""):