actually remove catchall pattern in eval
This commit is contained in:
parent
fd55604608
commit
32ab5f7944
|
@ -43,7 +43,7 @@ mod vm;
|
||||||
use crate::vm::*;
|
use crate::vm::*;
|
||||||
|
|
||||||
pub fn main() {
|
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();
|
let (tokens, lex_errs) = lexer().parse(src).into_output_errors();
|
||||||
if lex_errs.len() > 0 {
|
if lex_errs.len() > 0 {
|
||||||
println!("{:?}", lex_errs);
|
println!("{:?}", lex_errs);
|
||||||
|
|
|
@ -3,6 +3,12 @@ use crate::spans::*;
|
||||||
use chumsky::{input::ValueInput, prelude::*, recursive::Recursive};
|
use chumsky::{input::ValueInput, prelude::*, recursive::Recursive};
|
||||||
use std::fmt;
|
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)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Ast<'src> {
|
pub enum Ast<'src> {
|
||||||
Error,
|
Error,
|
||||||
|
@ -23,8 +29,7 @@ pub enum Ast<'src> {
|
||||||
Let(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
|
Let(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
|
||||||
Box(&'src str, Box<Spanned<Self>>),
|
Box(&'src str, Box<Spanned<Self>>),
|
||||||
Synthetic(Box<Spanned<Self>>, Box<Spanned<Self>>, Vec<Spanned<Self>>),
|
Synthetic(Box<Spanned<Self>>, Box<Spanned<Self>>, Vec<Spanned<Self>>),
|
||||||
WhenClause(Box<Spanned<Self>>, Box<Spanned<Self>>),
|
When(Vec<Spanned<WhenClause<'src>>>),
|
||||||
When(Vec<Spanned<Self>>),
|
|
||||||
MatchClause(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
|
MatchClause(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
|
||||||
Match(Box<Spanned<Self>>, Vec<Spanned<Self>>),
|
Match(Box<Spanned<Self>>, Vec<Spanned<Self>>),
|
||||||
FnClause(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
|
FnClause(Box<Spanned<Pattern<'src>>>, Box<Spanned<Self>>),
|
||||||
|
@ -382,7 +387,7 @@ where
|
||||||
.clone()
|
.clone()
|
||||||
.then_ignore(just(Token::Punctuation("->")))
|
.then_ignore(just(Token::Punctuation("->")))
|
||||||
.then(expr.clone())
|
.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"))
|
let when = just(Token::Reserved("when"))
|
||||||
.ignore_then(
|
.ignore_then(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::parser::*;
|
use crate::parser::*;
|
||||||
use crate::spans::*;
|
use crate::spans::*;
|
||||||
use imbl::*;
|
use imbl::*;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ pub enum Value<'src> {
|
||||||
List(Rc<Vector<Self>>),
|
List(Rc<Vector<Self>>),
|
||||||
// ref-counted, immutable, persistent
|
// ref-counted, immutable, persistent
|
||||||
Dict(Rc<HashMap<&'src str, Self>>),
|
Dict(Rc<HashMap<&'src str, Self>>),
|
||||||
|
Box(&'src str, Box<Self>),
|
||||||
// Fn(Rc<Fn<'src>>),
|
// Fn(Rc<Fn<'src>>),
|
||||||
// Set(HashSet<Self>),
|
// Set(HashSet<Self>),
|
||||||
// Sets are hard
|
// Sets are hard
|
||||||
|
@ -55,6 +57,7 @@ impl<'src> Clone for Value<'src> {
|
||||||
Value::Tuple(t) => Value::Tuple(t.clone()),
|
Value::Tuple(t) => Value::Tuple(t.clone()),
|
||||||
Value::List(l) => Value::List(l.clone()),
|
Value::List(l) => Value::List(l.clone()),
|
||||||
Value::Dict(d) => Value::Dict(d.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(", ")
|
.join(", ")
|
||||||
),
|
),
|
||||||
Value::Dict(d) => write!(f, "#{{{:?}}}", d),
|
Value::Dict(d) => write!(f, "#{{{:?}}}", d),
|
||||||
|
Value::Box(name, b) => write!(f, "box {} [ {} ]", name, b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
44
src/vm.rs
44
src/vm.rs
|
@ -5,7 +5,7 @@ use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LudusError {
|
pub struct LudusError {
|
||||||
msg: &'static str,
|
msg: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// oy
|
// oy
|
||||||
|
@ -156,7 +156,9 @@ pub fn eval<'src, 'a>(
|
||||||
let val = eval(&expr.0, ctx)?;
|
let val = eval(&expr.0, ctx)?;
|
||||||
match matchh(&patt.0, &val, ctx) {
|
match matchh(&patt.0, &val, ctx) {
|
||||||
Some(_) => Ok(val),
|
Some(_) => Ok(val),
|
||||||
None => Err(LudusError { msg: "No match" }),
|
None => Err(LudusError {
|
||||||
|
msg: "No match".to_string(),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ast::Placeholder => todo!(),
|
Ast::Placeholder => todo!(),
|
||||||
|
@ -166,15 +168,45 @@ pub fn eval<'src, 'a>(
|
||||||
Ast::Pair(_, _) => todo!(),
|
Ast::Pair(_, _) => todo!(),
|
||||||
Ast::Box(_, _) => todo!(),
|
Ast::Box(_, _) => todo!(),
|
||||||
Ast::Synthetic(_, _, _) => todo!(),
|
Ast::Synthetic(_, _, _) => todo!(),
|
||||||
Ast::When(_) => todo!(),
|
Ast::When(clauses) => {
|
||||||
Ast::WhenClause(_, _) => todo!(),
|
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::Match(_, _) => todo!(),
|
||||||
Ast::MatchClause(_, _) => todo!(),
|
Ast::MatchClause(_, _) => todo!(),
|
||||||
Ast::Fn(_, _) => todo!(),
|
Ast::Fn(_, _) => todo!(),
|
||||||
Ast::FnDeclaration(_) => todo!(),
|
Ast::FnDeclaration(_) => todo!(),
|
||||||
Ast::FnClause(_, _) => todo!(),
|
Ast::FnClause(_, _) => todo!(),
|
||||||
Ast::Panic(_) => todo!(),
|
Ast::Panic(msg) => {
|
||||||
Ast::Repeat(_, _) => todo!(),
|
let msg = eval(&msg.0, ctx)?;
|
||||||
|
Err(LudusError {
|
||||||
|
msg: msg.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Ast::Repeat(times, body) => {
|
||||||
|
let mut times_num = 0;
|
||||||
|
match eval(×.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::Do(_) => todo!(),
|
||||||
Ast::Loop(_, _) => todo!(),
|
Ast::Loop(_, _) => todo!(),
|
||||||
Ast::Recur(_) => todo!(),
|
Ast::Recur(_) => todo!(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user