1
1
use clap:: { Parser , Subcommand } ;
2
2
use directories:: UserDirs ;
3
- use glyph:: { Input , Options } ;
3
+ use glyph:: { FileBackedInputs , Input , Options , PromptOptions } ;
4
4
use pyro_core:: annotate:: { annotate_decl, annotate_val} ;
5
5
use pyro_core:: ast:: Tag ;
6
6
use pyro_core:: parser:: ParserState ;
7
7
use pyro_core:: sym:: Sym ;
8
8
use pyro_core:: tokenizer:: Tokenizer ;
9
9
use pyro_core:: { infer_decl, infer_val, Machine } ;
10
10
use pyro_runtime:: { Engine , Env } ;
11
+ use std:: io;
11
12
use std:: path:: PathBuf ;
12
13
13
14
#[ derive( Parser , Debug ) ]
14
- #[ command( name = ":" ) ]
15
15
struct Shell {
16
16
#[ command( subcommand) ]
17
17
cmd : Cmd ,
@@ -29,19 +29,38 @@ enum Cmd {
29
29
Exit ,
30
30
}
31
31
32
+ #[ derive( Default ) ]
33
+ struct State {
34
+ modules : Vec < String > ,
35
+ }
36
+
37
+ impl State {
38
+ fn next_input ( & self , inputs : & mut FileBackedInputs ) -> io:: Result < Option < Input < Shell > > > {
39
+ let prompt = self . modules . join ( " " ) ;
40
+ let options = if prompt. is_empty ( ) {
41
+ PromptOptions :: default ( )
42
+ } else {
43
+ PromptOptions :: default ( ) . prompt ( prompt)
44
+ } ;
45
+
46
+ inputs. next_input_with_parser_and_options :: < Shell > ( & options)
47
+ }
48
+ }
49
+
32
50
#[ tokio:: main]
33
51
async fn main ( ) -> eyre:: Result < ( ) > {
34
52
let user_dirs = UserDirs :: new ( ) ;
35
53
let options = Options :: default ( )
36
- . prompt ( "π" )
54
+ . prompt ( "π> " )
37
55
. header ( include_str ! ( "header.txt" ) )
38
56
. author ( "Yo Eight" )
39
57
. version ( "master" ) ;
40
58
41
59
let mut inputs = glyph:: file_backed_inputs ( options, ".pyro-repl" ) ?;
42
60
let mut engine = Engine :: with_nominal_typing ( ) . stdlib ( Env :: stdio ( ) ) . build ( ) ?;
61
+ let mut state = State :: default ( ) ;
43
62
44
- while let Some ( input) = inputs . next_input_with_parser :: < Shell > ( ) ? {
63
+ while let Some ( input) = state . next_input ( & mut inputs ) ? {
45
64
match input {
46
65
Input :: Exit => {
47
66
break ;
@@ -55,14 +74,14 @@ async fn main() -> eyre::Result<()> {
55
74
PathBuf :: from ( file)
56
75
} ;
57
76
58
- if let Err ( e) = add_module ( & mut engine, path) {
77
+ if let Err ( e) = add_module ( & mut state , & mut engine, path) {
59
78
println ! ( "ERR: {}" , e) ;
60
79
}
61
80
}
62
81
63
82
Cmd :: Type { expr } => {
64
83
if let Err ( e) = type_expr ( & mut engine, expr) {
65
- println ! ( "Err : {}" , e) ;
84
+ println ! ( "ERR : {}" , e) ;
66
85
}
67
86
}
68
87
@@ -104,8 +123,12 @@ fn extrapolate_path(dirs: &UserDirs, path: PathBuf) -> PathBuf {
104
123
buf
105
124
}
106
125
107
- fn add_module < M : Machine > ( engine : & mut Engine < M > , path : PathBuf ) -> eyre:: Result < ( ) > {
108
- let source_code = std:: fs:: read_to_string ( path) ?;
126
+ fn add_module < M : Machine > (
127
+ state : & mut State ,
128
+ engine : & mut Engine < M > ,
129
+ path : PathBuf ,
130
+ ) -> eyre:: Result < ( ) > {
131
+ let source_code = std:: fs:: read_to_string ( path. as_path ( ) ) ?;
109
132
let tokens = Tokenizer :: new ( source_code. as_str ( ) ) . tokenize ( ) ?;
110
133
let mut parser = ParserState :: new ( tokens. as_slice ( ) ) ;
111
134
@@ -129,6 +152,8 @@ fn add_module<M: Machine>(engine: &mut Engine<M>, path: PathBuf) -> eyre::Result
129
152
}
130
153
}
131
154
155
+ state. modules . push ( format ! ( "{}" , path. to_string_lossy( ) ) ) ;
156
+
132
157
Ok ( ( ) )
133
158
}
134
159
0 commit comments