actually remove catchall pattern in eval

This commit is contained in:
Scott Richmond 2024-11-07 20:41:38 -05:00
parent fd55604608
commit 32ab5f7944
4 changed files with 51 additions and 10 deletions

View File

@ -43,7 +43,7 @@ mod vm;
use crate::vm::*;
pub fn main() {
let src = "let (x, 2) = (1, 2); x";
let src = "when { false -> :false, true -> :true}";
let (tokens, lex_errs) = lexer().parse(src).into_output_errors();
if lex_errs.len() > 0 {
println!("{:?}", lex_errs);

View File

@ -3,6 +3,12 @@ use crate::spans::*;
use chumsky::{input::ValueInput, prelude::*, recursive::Recursive};
use std::fmt;
#[derive(Clone, Debug, PartialEq)]
pub struct WhenClause<'src> {
pub cond: Spanned<Ast<'src>>,
pub body: Spanned<Ast<'src>>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum Ast<'src> {
Error,
@ -23,8 +29,7 @@ pub enum Ast<'src> {
Let(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
Box(&'src str, Box<Spanned<Self>>),
Synthetic(Box<Spanned<Self>>, Box<Spanned<Self>>, Vec<Spanned<Self>>),
WhenClause(Box<Spanned<Self>>, Box<Spanned<Self>>),
When(Vec<Spanned<Self>>),
When(Vec<Spanned<WhenClause<'src>>>),
MatchClause(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
Match(Box<Spanned<Self>>, Vec<Spanned<Self>>),
FnClause(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
@ -382,7 +387,7 @@ where
.clone()
.then_ignore(just(Token::Punctuation("->")))
.then(expr.clone())
.map_with(|(cond, body), e| (Ast::WhenClause(Box::new(cond), Box::new(body)), e.span()));
.map_with(|(cond, body), e| (WhenClause { cond, body }, e.span()));
let when = just(Token::Reserved("when"))
.ignore_then(

View File

@ -1,6 +1,7 @@
use crate::parser::*;
use crate::spans::*;
use imbl::*;
use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
@ -31,6 +32,7 @@ pub enum Value<'src> {
List(Rc<Vector<Self>>),
// ref-counted, immutable, persistent
Dict(Rc<HashMap<&'src str, Self>>),
Box(&'src str, Box<Self>),
// Fn(Rc<Fn<'src>>),
// Set(HashSet<Self>),
// Sets are hard
@ -55,6 +57,7 @@ impl<'src> Clone for Value<'src> {
Value::Tuple(t) => Value::Tuple(t.clone()),
Value::List(l) => Value::List(l.clone()),
Value::Dict(d) => Value::Dict(d.clone()),
Value::Box(name, b) => Value::Box(name, b.clone()),
}
}
}
@ -85,6 +88,7 @@ impl<'src> fmt::Display for Value<'src> {
.join(", ")
),
Value::Dict(d) => write!(f, "#{{{:?}}}", d),
Value::Box(name, b) => write!(f, "box {} [ {} ]", name, b),
}
}
}

View File

@ -5,7 +5,7 @@ use std::rc::Rc;
#[derive(Clone, Debug)]
pub struct LudusError {
msg: &'static str,
msg: String,
}
// oy
@ -156,7 +156,9 @@ pub fn eval<'src, 'a>(
let val = eval(&expr.0, ctx)?;
match matchh(&patt.0, &val, ctx) {
Some(_) => Ok(val),
None => Err(LudusError { msg: "No match" }),
None => Err(LudusError {
msg: "No match".to_string(),
}),
}
}
Ast::Placeholder => todo!(),
@ -166,15 +168,45 @@ pub fn eval<'src, 'a>(
Ast::Pair(_, _) => todo!(),
Ast::Box(_, _) => todo!(),
Ast::Synthetic(_, _, _) => todo!(),
Ast::When(_) => todo!(),
Ast::WhenClause(_, _) => todo!(),
Ast::When(clauses) => {
for clause in clauses.iter() {
let WhenClause { cond, body } = &clause.0;
if eval(&cond.0, ctx)?.bool() {
return eval(&body.0, ctx);
};
}
return Err(LudusError {
msg: "no match".to_string(),
});
}
Ast::Match(_, _) => todo!(),
Ast::MatchClause(_, _) => todo!(),
Ast::Fn(_, _) => todo!(),
Ast::FnDeclaration(_) => todo!(),
Ast::FnClause(_, _) => todo!(),
Ast::Panic(_) => todo!(),
Ast::Repeat(_, _) => todo!(),
Ast::Panic(msg) => {
let msg = eval(&msg.0, ctx)?;
Err(LudusError {
msg: msg.to_string(),
})
}
Ast::Repeat(times, body) => {
let mut times_num = 0;
match eval(&times.0, ctx) {
Ok(Value::Number(n)) => {
times_num = n as usize;
}
_ => {
return Err(LudusError {
msg: "repeat may only take numbers".to_string(),
})
}
}
for _ in 0..times_num {
let _ = eval(&body.0, ctx)?;
}
Ok(Value::Nil)
}
Ast::Do(_) => todo!(),
Ast::Loop(_, _) => todo!(),
Ast::Recur(_) => todo!(),