Some improvements to the thing

This commit is contained in:
greg 2018-06-04 18:17:03 -07:00
parent df76e7c120
commit 27729cefdf
2 changed files with 33 additions and 22 deletions

View File

@ -51,7 +51,7 @@ pub enum Lit {
Float(f64), Float(f64),
Bool(bool), Bool(bool),
StringLit(Rc<String>), StringLit(Rc<String>),
Custom(Rc<String>), Custom(Rc<String>, Vec<Expr>),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -44,25 +44,12 @@ enum ValueEntry {
type EvalResult<T> = Result<T, String>; type EvalResult<T> = Result<T, String>;
impl Expr { impl Expr {
fn to_repl(&self) -> String { fn to_repl(&self) -> String {
use self::Lit::*; use self::Lit::*;
use self::Func::*; use self::Func::*;
match self { fn paren_wrapped_vec(exprs: &Vec<Expr>) -> String {
Expr::Lit(ref l) => match l {
Nat(n) => format!("{}", n),
Int(i) => format!("{}", i),
Float(f) => format!("{}", f),
Bool(b) => format!("{}", b),
StringLit(s) => format!("\"{}\"", s),
Custom(s) => format!("{}", s),
},
Expr::Func(f) => match f {
BuiltIn(name) => format!("<built-in function {}>", name),
UserDefined { name: None, .. } => format!("<function>"),
UserDefined { name: Some(name), .. } => format!("<function {}>", name),
},
Expr::Tuple(exprs) => {
let mut buf = String::new(); let mut buf = String::new();
write!(buf, "(").unwrap(); write!(buf, "(").unwrap();
for term in exprs.iter().map(|e| Some(e)).intersperse(None) { for term in exprs.iter().map(|e| Some(e)).intersperse(None) {
@ -73,7 +60,24 @@ impl Expr {
} }
write!(buf, ")").unwrap(); write!(buf, ")").unwrap();
buf buf
}
match self {
Expr::Lit(ref l) => match l {
Nat(n) => format!("{}", n),
Int(i) => format!("{}", i),
Float(f) => format!("{}", f),
Bool(b) => format!("{}", b),
StringLit(s) => format!("\"{}\"", s),
Custom(name, args) if args.len() == 0 => format!("{}", name),
Custom(name, args) => format!("{}{}", name, paren_wrapped_vec(args)),
}, },
Expr::Func(f) => match f {
BuiltIn(name) => format!("<built-in function {}>", name),
UserDefined { name: None, .. } => format!("<function>"),
UserDefined { name: Some(name), .. } => format!("<function {}>", name),
},
Expr::Tuple(exprs) => paren_wrapped_vec(exprs),
_ => format!("{:?}", self), _ => format!("{:?}", self),
} }
} }
@ -141,13 +145,7 @@ impl<'a> State<'a> {
literal @ Lit(_) => Ok(literal), literal @ Lit(_) => Ok(literal),
Call { box f, args } => { Call { box f, args } => {
if let Val(name) = f { if let Val(name) = f {
let symbol_table = self.symbol_table_handle.borrow(); self.apply_data_constructor(name, args)
match symbol_table.values.get(&name) {
Some(Symbol { spec: SymbolSpec::DataConstructor { type_name, type_args }, .. }) => {
Ok(Expr::Lit(self::Lit::Nat(99)))
},
_ => return Err(format!("Bad symbol {}", name))
}
} else { } else {
match self.expression(f)? { match self.expression(f)? {
Func(f) => self.apply_function(f, args), Func(f) => self.apply_function(f, args),
@ -180,6 +178,19 @@ impl<'a> State<'a> {
} }
} }
fn apply_data_constructor(&mut self, name: Rc<String>, args: Vec<Expr>) -> EvalResult<Expr> {
let symbol_table = self.symbol_table_handle.borrow();
match symbol_table.values.get(&name) {
Some(Symbol { spec: SymbolSpec::DataConstructor { type_name, type_args }, name }) => {
if args.len() != type_args.len() {
return Err(format!("Data constructor {} requires {} args", name, type_args.len()));
}
Ok(Expr::Lit(self::Lit::Custom(name.clone(), vec![])))
},
_ => return Err(format!("Bad symbol {}", name))
}
}
fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Expr> { fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Expr> {
match f { match f {
Func::BuiltIn(sigil) => self.apply_builtin(sigil, args), Func::BuiltIn(sigil) => self.apply_builtin(sigil, args),
@ -278,7 +289,7 @@ impl<'a> State<'a> {
Some(Symbol { name, spec }) => match spec { Some(Symbol { name, spec }) => match spec {
SymbolSpec::DataConstructor { type_name, type_args } => { SymbolSpec::DataConstructor { type_name, type_args } => {
if type_args.len() == 0 { if type_args.len() == 0 {
Expr::Lit(Lit::Custom(name.clone())) Expr::Lit(Lit::Custom(name.clone(), vec![]))
} else { } else {
return Err(format!("This data constructor thing not done")) return Err(format!("This data constructor thing not done"))
} }