WIP bc I forgot what I was doing

This commit is contained in:
Dane Johnson 2024-11-04 10:07:12 -06:00
parent 5436a706d7
commit 69ccf679e7
2 changed files with 38 additions and 10 deletions

View File

@ -1,7 +1,7 @@
use std::ops;
use std::collections::HashMap;
use crate::parser;
use crate::parser::{self, GuardedBlock};
use parser::Atom;
pub struct Env<'a> {
@ -42,6 +42,30 @@ pub fn eval(ast: &parser::Stmt, env: &mut Env) {
println!("{}", eval_expr(expr, env)),
parser::Stmt::Assignment(id, expr) =>
env.set(id.clone(), eval_expr(expr, env)),
parser::Stmt::Conditional(guarded_blocks, default_block) => {
let mut matched = false;
for GuardedBlock { guard, block } in guarded_blocks {
let res = eval_expr(&guard, env);
match res {
Atom::Bool(true) => {
matched = true;
for stmt in block {
eval(stmt, env);
}
break;
}
Atom::Bool(false) => continue,
_ => panic!("Conditional expression does not evaluate to a bool"),
}
}
if !matched {
if let Some(block) = default_block {
for expr in default_block {
eval_expr(expr, env);
}
}
}
}
_ => todo!(),
}
}

View File

@ -4,7 +4,7 @@ use std::fmt;
pub enum Stmt {
Assignment(String, Expr),
Funcall(Expr),
Conditional(Vec<Expr>, Option<Expr>),
Conditional(Vec<GuardedBlock>, Option<Expr>),
ReplPrint(Expr),
}
@ -20,7 +20,6 @@ pub enum Expr {
Mult(Box<Expr>, Box<Expr>),
Div(Box<Expr>, Box<Expr>),
Block(Vec<Stmt>),
GuardedBlock(Box<GuardedBlock>),
Object(Vec<Stmt>),
}
@ -28,6 +27,7 @@ pub enum Expr {
pub enum Atom {
String(String),
Num(f64),
Bool(bool),
}
impl fmt::Display for Atom {
@ -35,6 +35,7 @@ impl fmt::Display for Atom {
match self {
Atom::String(a) => write!(f, "\"{}\"", a),
Atom::Num(a) => write!(f, "{}", a),
Atom::Bool(a) => write!(f, "{}", a),
}
}
}
@ -68,7 +69,8 @@ peg::parser! {
f:funcall() { f }
f:funcdef() { f }
o:object() { o }
i:id() _ { Expr::Id(i) }
b:_bool() _ { Expr::Atom(Atom::Bool(b)) }
i:id() { Expr::Id(i) }
n:num() _ { Expr::Atom(Atom::Num(n)) }
}
@ -79,6 +81,8 @@ peg::parser! {
= i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) }
rule num() -> f64
= n:$(digit()+ "."? digit()* / "." digit()+) _ { n.parse().unwrap() }
rule _bool() -> bool
= "true" _ { true } / "false" _ { false }
rule funcall() -> Expr
= i:id() "(" _ e:(expr() ** ("," _)) ")" _ { Expr::Funcall(i, e) }
rule funcdef() -> Expr
@ -88,19 +92,19 @@ peg::parser! {
rule object() -> Expr
= "{" _ stop() indent() __* a:assignment()+ dedent() __* "}" _ { Expr::Object(a) }
rule _if() -> Expr
rule _if() -> GuardedBlock
= "if" _ g:expr() b:indented_block() {
Expr::GuardedBlock(Box::new(GuardedBlock {
GuardedBlock {
guard: g,
block: b,
}))
}
}
rule elif() -> Expr
rule elif() -> GuardedBlock
= "elif" _ g:expr() b:indented_block() {
Expr::GuardedBlock(Box::new(GuardedBlock {
GuardedBlock {
guard: g,
block: b
}))
}
}
rule _else() -> Expr
= "else" _ b:block() { b }