1
1
from __future__ import annotations
2
2
3
- import json
4
3
import logging
5
4
from enum import Enum
6
5
from pathlib import Path
7
6
from subprocess import CalledProcessError
8
7
from typing import TYPE_CHECKING
9
8
10
9
from ..cli .utils import check_dir_path , check_file_path
11
- from ..cterm import CTerm
12
- from ..kast import kast_term
13
- from ..kast .inner import KInner , KLabel , KSort
14
- from ..konvert import unmunge
15
10
from ..kore .parser import KoreParser
16
- from ..kore .syntax import DV , App , SortApp , String
11
+ from ..kore .tools import PrintOutput , kore_print
17
12
from ..utils import run_process
18
13
from .kprint import KPrint
19
14
31
26
_LOGGER : Final = logging .getLogger (__name__ )
32
27
33
28
29
+ class KRunOutput (Enum ):
30
+ PRETTY = 'pretty'
31
+ PROGRAM = 'program'
32
+ KAST = 'kast'
33
+ BINARY = 'binary'
34
+ JSON = 'json'
35
+ LATEX = 'latex'
36
+ KORE = 'kore'
37
+ NONE = 'none'
38
+
39
+
34
40
class KRun (KPrint ):
35
41
command : str
36
42
@@ -52,181 +58,120 @@ def __init__(
52
58
)
53
59
self .command = command
54
60
55
- def run (
61
+ def run_kore_process (
56
62
self ,
57
- pgm : KInner ,
63
+ pgm : Pattern ,
58
64
* ,
59
- config : Mapping [str , KInner ] | None = None ,
65
+ cmap : Mapping [str , str ] | None = None ,
66
+ pmap : Mapping [str , str ] | None = None ,
67
+ term : bool = False ,
60
68
depth : int | None = None ,
61
- expand_macros : bool = False ,
62
- expect_rc : int | Iterable [ int ] = 0 ,
63
- ) -> CTerm :
64
- if config is not None and 'PGM' in config :
65
- raise ValueError ( 'Cannot supply both pgm and config with PGM variable.' )
66
- pmap = { k : 'cat' for k in config } if config is not None else None
67
- cmap = { k : self . kast_to_kore ( v ). text for k , v in config . items ()} if config is not None else None
69
+ expand_macros : bool = True ,
70
+ search_final : bool = False ,
71
+ no_pattern : bool = False ,
72
+ output : KRunOutput | None = KRunOutput . PRETTY ,
73
+ pipe_stderr : bool = True ,
74
+ bug_report : BugReport | None = None ,
75
+ ) -> CompletedProcess :
68
76
with self ._temp_file () as ntf :
69
- ntf .write (self . pretty_print ( pgm ) )
77
+ pgm .write (ntf )
70
78
ntf .flush ()
71
79
72
- result = _krun (
80
+ return _krun (
73
81
command = self .command ,
74
82
input_file = Path (ntf .name ),
75
83
definition_dir = self .definition_dir ,
76
- output = KRunOutput .JSON ,
84
+ output = KRunOutput .KORE ,
77
85
depth = depth ,
86
+ parser = 'cat' ,
78
87
cmap = cmap ,
79
88
pmap = pmap ,
89
+ term = term ,
80
90
temp_dir = self .use_directory ,
81
91
no_expand_macros = not expand_macros ,
92
+ search_final = search_final ,
93
+ no_pattern = no_pattern ,
82
94
bug_report = self ._bug_report ,
83
- check = (expect_rc == 0 ),
95
+ check = False ,
96
+ pipe_stderr = pipe_stderr ,
84
97
)
85
98
86
- self ._check_return_code (result .returncode , expect_rc )
87
-
88
- result_kast = kast_term (json .loads (result .stdout ), KInner ) # type: ignore # https://github.com/python/mypy/issues/4717
89
- return CTerm .from_kast (result_kast )
90
-
91
99
def run_kore (
92
100
self ,
93
- pgm : KInner ,
101
+ pgm : Pattern ,
94
102
* ,
95
- sort : KSort | None = None ,
103
+ cmap : Mapping [str , str ] | None = None ,
104
+ pmap : Mapping [str , str ] | None = None ,
105
+ term : bool = False ,
96
106
depth : int | None = None ,
97
- expand_macros : bool = False ,
98
- expect_rc : int | Iterable [int ] = 0 ,
99
- ) -> CTerm :
100
- kore_pgm = self .kast_to_kore (pgm , sort = sort )
101
- with self ._temp_file () as ntf :
102
- kore_pgm .write (ntf )
103
- ntf .write ('\n ' )
104
- ntf .flush ()
105
-
106
- result = _krun (
107
- command = self .command ,
108
- input_file = Path (ntf .name ),
109
- definition_dir = self .definition_dir ,
110
- output = KRunOutput .KORE ,
111
- parser = 'cat' ,
112
- depth = depth ,
113
- temp_dir = self .use_directory ,
114
- no_expand_macros = not expand_macros ,
115
- bug_report = self ._bug_report ,
116
- check = (expect_rc == 0 ),
117
- )
118
-
119
- self ._check_return_code (result .returncode , expect_rc )
120
-
121
- result_kore = KoreParser (result .stdout ).pattern ()
122
- result_kast = self .kore_to_kast (result_kore )
123
- return CTerm .from_kast (result_kast )
124
-
125
- def run_kore_term (
126
- self ,
127
- pattern : Pattern ,
128
- * ,
129
- depth : int | None = None ,
130
- expand_macros : bool = False ,
107
+ expand_macros : bool = True ,
131
108
search_final : bool = False ,
132
109
no_pattern : bool = False ,
110
+ output : KRunOutput | None = KRunOutput .PRETTY ,
111
+ check : bool = False ,
112
+ pipe_stderr : bool = True ,
133
113
bug_report : BugReport | None = None ,
134
- expect_rc : int | Iterable [int ] = 0 ,
135
- ) -> Pattern :
136
- with self ._temp_file () as ntf :
137
- pattern .write (ntf )
138
- ntf .write ('\n ' )
139
- ntf .flush ()
140
-
141
- proc_res = _krun (
142
- command = self .command ,
143
- input_file = Path (ntf .name ),
144
- definition_dir = self .definition_dir ,
145
- output = KRunOutput .KORE ,
146
- parser = 'cat' ,
147
- term = True ,
148
- depth = depth ,
149
- temp_dir = self .use_directory ,
150
- no_expand_macros = not expand_macros ,
151
- search_final = search_final ,
152
- no_pattern = no_pattern ,
153
- bug_report = self ._bug_report ,
154
- check = (expect_rc == 0 ),
155
- )
156
-
157
- self ._check_return_code (proc_res .returncode , expect_rc )
114
+ ) -> None :
115
+ result = self .run_kore_process (
116
+ pgm ,
117
+ cmap = cmap ,
118
+ pmap = pmap ,
119
+ term = term ,
120
+ depth = depth ,
121
+ expand_macros = expand_macros ,
122
+ search_final = search_final ,
123
+ no_pattern = no_pattern ,
124
+ output = output ,
125
+ pipe_stderr = pipe_stderr ,
126
+ bug_report = bug_report ,
127
+ )
158
128
159
- parser = KoreParser (proc_res .stdout )
160
- res = parser .pattern ()
161
- assert parser .eof
162
- return res
129
+ if output != KRunOutput .NONE :
130
+ output_kore = KoreParser (result .stdout ).pattern ()
131
+ match output :
132
+ case KRunOutput .JSON :
133
+ print (self .kore_to_kast (output_kore ).to_json ())
134
+ case KRunOutput .KORE :
135
+ print (output_kore .text )
136
+ case KRunOutput .PRETTY | KRunOutput .PROGRAM | KRunOutput .KAST | KRunOutput .BINARY | KRunOutput .LATEX :
137
+ print (kore_print (output_kore , self .definition_dir , PrintOutput (output .value )))
138
+ case KRunOutput .NONE :
139
+ raise AssertionError ()
140
+
141
+ if check :
142
+ result .check_returncode ()
163
143
164
- def run_kore_config (
144
+ def run_kore_term (
165
145
self ,
166
- config : Mapping [ str , Pattern ] ,
146
+ pattern : Pattern ,
167
147
* ,
168
148
depth : int | None = None ,
169
149
expand_macros : bool = False ,
170
150
search_final : bool = False ,
171
151
no_pattern : bool = False ,
172
- # ---
152
+ pipe_stderr : bool = True ,
153
+ check : bool = False ,
173
154
bug_report : BugReport | None = None ,
174
- expect_rc : int = 0 ,
175
155
) -> Pattern :
176
- def _config_var_token (s : str ) -> DV :
177
- return DV (SortApp ('SortKConfigVar' ), String (f'${ s } ' ))
178
-
179
- def _map_item (s : str , p : Pattern , sort : KSort ) -> Pattern :
180
- _map_key = self ._add_sort_injection (_config_var_token (s ), KSort ('KConfigVar' ), KSort ('KItem' ))
181
- _map_value = self ._add_sort_injection (p , sort , KSort ('KItem' ))
182
- return App ("Lbl'UndsPipe'-'-GT-Unds'" , [], [_map_key , _map_value ])
183
-
184
- def _map (ps : list [Pattern ]) -> Pattern :
185
- if len (ps ) == 0 :
186
- return App ("Lbl'Stop'Map{}()" , [], [])
187
- if len (ps ) == 1 :
188
- return ps [0 ]
189
- return App ("Lbl'Unds'Map'Unds'" , [], [ps [0 ], _map (ps [1 :])])
190
-
191
- def _sort (p : Pattern ) -> KSort :
192
- if type (p ) is DV :
193
- return KSort (p .sort .name [4 :])
194
- if type (p ) is App :
195
- label = KLabel (unmunge (p .symbol [3 :]))
196
- return self .definition .return_sort (label )
197
- raise ValueError (f'Cannot fast-compute sort for pattern: { p } ' )
198
-
199
- config_var_map = _map ([_map_item (k , v , _sort (v )) for k , v in config .items ()])
200
- term = App ('LblinitGeneratedTopCell' , [], [config_var_map ])
201
-
202
- return self .run_kore_term (
203
- term ,
156
+ proc_res = self .run_kore_process (
157
+ pattern ,
204
158
depth = depth ,
159
+ term = True ,
205
160
expand_macros = expand_macros ,
206
161
search_final = search_final ,
207
162
no_pattern = no_pattern ,
163
+ output = KRunOutput .NONE ,
164
+ pipe_stderr = pipe_stderr ,
208
165
bug_report = bug_report ,
209
- expect_rc = expect_rc ,
210
166
)
211
167
212
- @staticmethod
213
- def _check_return_code (actual : int , expected : int | Iterable [int ]) -> None :
214
- if isinstance (expected , int ):
215
- expected = [expected ]
168
+ if check :
169
+ proc_res .check_returncode ()
216
170
217
- if actual not in expected :
218
- raise RuntimeError (f'Expected { expected } as exit code from krun, but got { actual } ' )
219
-
220
-
221
- class KRunOutput (Enum ):
222
- PRETTY = 'pretty'
223
- PROGRAM = 'program'
224
- KAST = 'kast'
225
- BINARY = 'binary'
226
- JSON = 'json'
227
- LATEX = 'latex'
228
- KORE = 'kore'
229
- NONE = 'none'
171
+ parser = KoreParser (proc_res .stdout )
172
+ res = parser .pattern ()
173
+ assert parser .eof
174
+ return res
230
175
231
176
232
177
def _krun (
@@ -237,16 +182,16 @@ def _krun(
237
182
output : KRunOutput | None = None ,
238
183
parser : str | None = None ,
239
184
depth : int | None = None ,
240
- pmap : Mapping [str , str ] | None = None ,
241
185
cmap : Mapping [str , str ] | None = None ,
186
+ pmap : Mapping [str , str ] | None = None ,
242
187
term : bool = False ,
243
188
temp_dir : Path | None = None ,
244
189
no_expand_macros : bool = False ,
245
190
search_final : bool = False ,
246
191
no_pattern : bool = False ,
247
192
# ---
248
193
check : bool = True ,
249
- pipe_stderr : bool = False ,
194
+ pipe_stderr : bool = True ,
250
195
logger : Logger | None = None ,
251
196
bug_report : BugReport | None = None ,
252
197
) -> CompletedProcess :
@@ -259,6 +204,9 @@ def _krun(
259
204
if depth and depth < 0 :
260
205
raise ValueError (f'Expected non-negative depth, got: { depth } ' )
261
206
207
+ if term and (cmap is not None or pmap is not None ):
208
+ raise ValueError ('Cannot supply both term and cmap/pmap' )
209
+
262
210
args = _build_arg_list (
263
211
command = command ,
264
212
input_file = input_file ,
0 commit comments