-
Notifications
You must be signed in to change notification settings - Fork 108
/
Copy pathpars_skl.py
155 lines (129 loc) · 4.56 KB
/
pars_skl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#
# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
#
# SPDX-License-Identifier: BSD-2-Clause
#
"""Parser for skeletons of theory files which are completed
by inserting parsed Haskell."""
from __future__ import print_function
from __future__ import absolute_import
import sys
import os
import os.path
import lhs_pars
from msgs import error, warning, status
def create_find_source():
dir = os.environ['L4CAP']
dir = os.path.join(dir, 'src')
return lambda x: os.path.join(dir, x)
def continued_lines(file):
'''Iterate over lines in file, using backslash at EOL as line continuation
character.'''
out = []
for line in file:
if line.endswith('\\\n'):
out.append(line[:-2])
else:
out.append(line)
yield ''.join(out)
out = []
if out:
raise IOError('No line after line continuation character')
find_source = create_find_source()
bad_type_assignment = False
if sys.argv[1] == '-q':
instructions = open(sys.argv[2])
quiet = True
else:
instructions = open(sys.argv[1])
quiet = False
for line in instructions:
instruct = line.strip()
if not instruct:
continue
[input, output] = [bit.strip() for bit in instruct.split('-->')]
output_tmp = os.path.join(os.path.dirname(output), 'pars_skel.tmp')
output_f = open(output_tmp, 'w')
output_f.write('(* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. *)\n')
output_f.write('(* instead, see the skeleton file %s *)\n' %
os.path.basename(input))
input_f = open(input)
for line in continued_lines(input_f):
if line.startswith('#INCLUDE_HASKELL'):
call = lhs_pars.Call()
bits = line.split()
call.filename = find_source(bits[1])
call.all_bits = 'all_bits' in bits
call.decls_only = 'decls_only' in bits
call.instanceproofs = 'instanceproofs' in bits
call.bodies_only = 'bodies_only' in bits
call.moduletranslations = dict([bit.split('=')
for bit in bits if '=' in bit])
if 'CONTEXT' in bits:
n = bits.index('CONTEXT')
call.current_context.append(bits[n + 1])
if 'ONLY' in bits:
n = bits.index('ONLY')
m = set(bits[n + 1:])
call.restr = lambda x: x.defined in m
elif 'NOT' in bits:
n = bits.index('NOT')
m = set(bits[n + 1:])
call.restr = lambda x: not x.defined in m
elif 'BODY' in bits:
call.body = True
assert bits[-2] == 'BODY'
fn = bits[-1]
call.restr = lambda x: x.defined == fn
try:
parsed = lhs_pars.parse(call)
except:
warning("%s -X-> %s" % (input, output), input)
raise
bad_type_assignment |= call.bad_type_assignment
if bits[0] == '#INCLUDE_HASKELL_PREPARSE':
pass
else:
output_f.writelines(parsed)
elif line.startswith("#INCLUDE_SETTINGS"):
(_, settings) = line.split(None, 1)
settings = settings.strip()
lhs_pars.settings_line(settings)
else:
output_f.write(line)
output_f.close()
# at this point, output_tmp should exist, but output might not exist
if not os.path.exists(output_tmp):
error('{} did not generate correctly'.format(output_tmp))
sys.exit(1)
if os.path.exists(output):
try:
lines1 = [line for line in open(output_tmp)]
lines2 = [line for line in open(output)]
changed = not (lines1 == lines2)
except IOError as e:
error("IOError comparing {} and {}:\n{}".format(output_tmp, output, e))
sys.exit(1)
else:
#warning('{} does not exist, assuming changed'.format(output))
changed = 1
if changed:
if not quiet:
status(instruct)
try:
os.unlink(output)
except:
pass
try:
os.rename(output_tmp, output)
except IOError as e:
error("IOError moving {} -> {}:\n{}".format(output_tmp, output, e))
sys.exit(1)
else:
os.unlink(output_tmp)
status("")
if bad_type_assignment and not quiet:
print("Note: for type assignments with parameters, define "
"the type explicitly in the theory skeleton",
file=sys.stderr)
lhs_pars.warn_supplied_usage()