Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow files to be loaded from the REPL #17

Open
brendanzab opened this issue Mar 29, 2018 · 3 comments
Open

Allow files to be loaded from the REPL #17

brendanzab opened this issue Mar 29, 2018 · 3 comments
Projects
Milestone

Comments

@brendanzab
Copy link
Member

brendanzab commented Mar 29, 2018

We should be able to load files in the REPL, either when passing a list of filenames on startup, or by a :load/:l command while the REPL is running:

cargo run repl ./src/library/prelude.pi
Pikelet> :load ./src/library/prelude.pi
Pikelet> id String "hi"
"hi" : #String

We should also be able to reload files using :reload/:r:

Pikelet> :load ./src/library/prelude.pi
Pikelet> :reload
@brendanzab brendanzab added this to the v0.1.0 milestone Apr 3, 2018
@brendanzab
Copy link
Member Author

brendanzab commented Jun 13, 2018

One thing that might complicate this is that we currently parse REPL commands as part of the main grammar:

pub ReplCommand: ReplCommand = {
=> ReplCommand::NoOp,
<term: Term> => ReplCommand::Eval(Box::new(term)),
<start: @L> <command: "REPL command"> <end: @R> =>? match command {
"?" | "h" | "help" => Ok(ReplCommand::Help),
"q" | "quit" => Ok(ReplCommand::Quit),
command => {
let span = ByteSpan::new(start, end);
let command = String::from(command);
Err(LalrpopError::User { error: ParseError::UnknownReplCommand { span, command} })
},
},
<start: @L> <command: "REPL command"> <end: @R> <term: Term> =>? match command {
"core" => Ok(ReplCommand::Core(Box::new(term))),
"t" | "type" => Ok(ReplCommand::TypeOf(Box::new(term))),
command => {
let span = ByteSpan::new(start, end);
let command = String::from(command);
Err(LalrpopError::User { error: ParseError::UnknownReplCommand { span, command} })
},
},
<start: @L> <command: "REPL command"> <end: @R> <ident: Ident> "=" <term: Term> =>? match command {
"let" => Ok(ReplCommand::Let(ident, Box::new(term))),
command => {
let span = ByteSpan::new(start, end);
let command = String::from(command);
Err(LalrpopError::User { error: ParseError::UnknownReplCommand { span, command} })
},
},
};

It will complicate things because we'll also need to include a 'file path' token in the lexer, which feels a little excessive. One way to hack around this until we find a better solution would be to use Token::String as the argument to :load.

Including the repl stuff in the main parser has always felt a tad unpleasant though, especially the way we match on the command names. Not sure of a better solution though...

@boomshroom
Copy link
Contributor

Currently, load_file generates its own TcEnv and DesugarEnv. While TcEnv can be added to after the fact, DesugarEnv can only be expanded by generating new identifiers. In order for this to work, we'd need to be able to add any exports from the module to both the TcEnv and the DesugarEnv of the repl, but without including the repl's environment with it (though the prelude and any future imports should be included).

@brendanzab
Copy link
Member Author

I'm wondering if load_file could take a TcEnv instead? 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development
  
In progress
Development

No branches or pull requests

2 participants