-
Notifications
You must be signed in to change notification settings - Fork 4
/
ghcihalp.py
executable file
·95 lines (84 loc) · 2.66 KB
/
ghcihalp.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
#!/usr/bin/env python
"""
Run a Halp-extended .lhs sourcefile from stdin; write to stdout the
same sourcefile with evaluation results placed inline.
"""
import os
import re
import subprocess
import sys
import tempfile
dbg = False
ext = sys.argv[1]
input = [line for line in sys.stdin if not line.startswith('-- | ')]
if input and not input[-1].endswith('\n'):
input[-1] += '\n'
input.append('\n')
if ext == '.hs':
input.append('aouhtnuoeahn = 0 -- Make sure the file has *some* code.\n')
else:
input.append('> aouhtnuoeahn = 0 -- Make sure the file has *some* code.\n')
module_name = 'Main'
defn_lines = []
eval_line_numbers = []
eval_lines = []
for i, line in enumerate(input):
if line.startswith('--- '):
eval_line_numbers.append(i+1)
eval_lines.append(line[len('--- '):])
else:
m = re.search(r'module (.*) where', line) # TODO: more specific
if m:
module_name = m.group(1)
defn_lines.append(line)
if dbg:
print eval_line_numbers
print ''.join(eval_lines)
fd, main_lhs = tempfile.mkstemp(ext)
try:
os.write(fd, ''.join(defn_lines))
os.close(fd)
ghci = subprocess.Popen(['ghci', main_lhs],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT) # for now
ghci.stdin.write(''.join(eval_lines))
results, foo = ghci.communicate()
finally:
os.unlink(main_lhs)
if dbg:
print results, foo
print ''
def count(it):
n = 0
for flag in it:
if flag:
n += 1
return n
prompt = '*%s> ' % module_name
result_lines = results.split('\n')
output = input[:-2]
for j, r in enumerate(result_lines):
m = re.search(r'[.]lhs:(\d+):(\d+):', r)
if m:
error_line_num = int(m.group(1))
output_line_num = (error_line_num
+ count(lnum < error_line_num
for lnum in eval_line_numbers))
output.insert(output_line_num, '-- | At column %s:\n' % m.group(2))
output_line_num += 1
for plaint_line in result_lines[j+1:]:
if plaint_line.startswith('Failed, modules loaded:'): break
output.insert(output_line_num, '-- | %s\n' % plaint_line)
output_line_num += 1
break
if r.startswith(prompt):
i = 0
for r in result_lines[j:]:
if r.startswith(prompt):
result = r[len(prompt):]
if result.startswith('Leaving GHCi.'): break
output.insert(eval_line_numbers[i] + i, '-- | %s\n' % result)
i += 1
break
sys.stdout.write(''.join(output).replace('\r\n', '\n'))