parent
36aeb10da9
commit
c8062f7843
@ -1 +1,80 @@
|
|||||||
fn main() {}
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
io::{Write, stdin, stdout},
|
||||||
|
rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use stlc_type_inference::{infer_type, is_ident, parse, parse_string, parse_type};
|
||||||
|
|
||||||
|
macro_rules! repl_err {
|
||||||
|
($err:expr) => {{
|
||||||
|
println!($err);
|
||||||
|
print!("> ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
|
continue;
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut gamma = Rc::new(HashMap::new());
|
||||||
|
print!("> ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
|
for line in stdin().lines() {
|
||||||
|
let line = line.unwrap();
|
||||||
|
if let Some(tl) = line.strip_prefix(':') {
|
||||||
|
if let Some((cmd, expr)) = tl.split_once(' ') {
|
||||||
|
match cmd {
|
||||||
|
"t" => match parse(expr) {
|
||||||
|
Ok(a) => match infer_type(gamma.clone(), a) {
|
||||||
|
Ok(t) => println!("{t}"),
|
||||||
|
Err(e) => repl_err!("Could not infer type {e:?}"),
|
||||||
|
},
|
||||||
|
Err(e) => repl_err!("Parse error {e:?}"),
|
||||||
|
},
|
||||||
|
"ctx" => {
|
||||||
|
if let Some((ident, typ)) = expr.split_once(':') {
|
||||||
|
let ident: String =
|
||||||
|
ident.chars().filter(|c| !c.is_whitespace()).collect();
|
||||||
|
if !is_ident(&ident) {
|
||||||
|
repl_err!("{ident} is not a valid identifer");
|
||||||
|
}
|
||||||
|
let typ_ast = match parse_string(typ) {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => repl_err!("Could not parse the type: {e:?}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let typ = match parse_type(&typ_ast) {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => repl_err!("type could not be parsed {e:?}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Added {ident} with type {typ} to the context");
|
||||||
|
Rc::make_mut(&mut gamma).insert(ident, typ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c => println!("Unknown command {c}"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match tl {
|
||||||
|
"t" => println!(":t need an expr as an argument"),
|
||||||
|
"ctx" => println!(":ctx needs an ident and a type as argument"),
|
||||||
|
c => println!("Unknown command {c}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let ast = match parse(&line) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(e) => repl_err!("Parse error {e:?}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let typ = match infer_type(gamma.clone(), ast.clone()) {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => repl_err!("Could not infer type {e:?}"),
|
||||||
|
};
|
||||||
|
let ast = ast.beta_reduce();
|
||||||
|
println!("{ast} : {typ}")
|
||||||
|
}
|
||||||
|
print!("> ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in new issue