-
Notifications
You must be signed in to change notification settings - Fork 0
/
process.py
102 lines (71 loc) · 2.57 KB
/
process.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
"""
Inspired by
https://github.com/idris-hackers/idris-bot/
Info about IDE mode and what commands can be sent to it is available at:
https://github.com/idris-lang/Idris-dev/blob/master/src/Idris/IdeMode.hs
"""
import subprocess
import time
import idr_parse as parse
import idr_parse.interpret as interpret
class IdrisProcess(subprocess.Popen):
"""Start & communicate with Idris process"""
template_interpret = '((:interpret "{cmd}") 0)\n'
template_loadfile = '((:load-file "{file}") 0)\n'
def __init__(self):
super(IdrisProcess, self).__init__(
[
"idris",
"--ide-mode",
"--nocolor"
],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT
)
def load_file(self, file):
return self.send_cmd(IdrisProcess.template_loadfile.format(file = file))
def interpret(self, cmd):
return self.send_cmd(IdrisProcess.template_interpret.format(cmd = cmd))
def load_file_(self, file):
return self.send_cmd_(IdrisProcess.template_loadfile.format(file = file))
def interpret_(self, cmd):
return self.send_cmd_(IdrisProcess.template_interpret.format(cmd = cmd))
def send_cmd_(self, cmd):
length_request = len(cmd)
to_send = bytes("{:06x}".format(length_request) + cmd, "utf-8")
self.stdout.flush()
self.stdin.write(to_send)
self.stdin.flush()
def send_cmd(self, cmd):
self.send_cmd_(cmd)
self.first_interpretable_cmd()
def receive_cmd(self, timeout = 10):
length = int(self.stdout.read(6).decode("utf8"), base = 16)
result = self.stdout.read(length)
result, couldnt_parse = parse.parse_expr(result.decode("utf8").strip())
if couldnt_parse:
print("Couldn't parse", couldnt_parse)
return result
def first_interpretable_cmd(self, output = print):
while True:
unparsed_result = self.receive_cmd()
interpreted_result = interpret.interpret(unparsed_result)
if interpreted_result is not None:
output(interpreted_result)
if isinstance(interpreted_result, interpret.Return):
break
if __name__ == "__main__":
process = IdrisProcess()
code1 = """Int'' : Type
Int'' = (a : Type) -> (a -> a) -> a -> a
successor : Int'' -> Int''
"""
code2 = """recursion_over_int : Int'' -> (a : Type) -> ((a, Int'') -> a) -> a -> a
recursion_over_int n a inheritance initial = fst $ n (a, Int'') inheritance2 (initial, zero)
where
inheritance2 : (a, Int'') -> (a, Int'')
inheritance2 (x, m) = (inheritance (x, m), succ m)
"""
print(code1)
print(code2)