cl-ast: Move loop expression into unary exprs (with lowest priority)

This commit is contained in:
John 2024-07-30 18:21:25 -05:00
parent b0341f06fd
commit b64cc232f9
8 changed files with 28 additions and 57 deletions

View File

@ -392,8 +392,6 @@ pub enum ExprKind {
Group(Group), Group(Group),
/// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)` /// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)`
Tuple(Tuple), Tuple(Tuple),
/// A [Loop] expression: `loop` [`Block`]
Loop(Loop),
/// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]? /// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]?
While(While), While(While),
/// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]? /// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]?
@ -482,6 +480,8 @@ pub enum UnaryKind {
Deref, Deref,
Neg, Neg,
Not, Not,
/// A Loop expression: `loop` [`Block`]
Loop,
/// Unused /// Unused
At, At,
/// Unused /// Unused
@ -570,12 +570,6 @@ pub struct Tuple {
pub exprs: Vec<Expr>, pub exprs: Vec<Expr>,
} }
/// A [Loop] expression: `loop` [`Block`]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Loop {
pub body: Box<Expr>,
}
/// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]? /// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]?
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct While { pub struct While {

View File

@ -448,7 +448,6 @@ mod display {
ExprKind::Block(v) => v.fmt(f), ExprKind::Block(v) => v.fmt(f),
ExprKind::Group(v) => v.fmt(f), ExprKind::Group(v) => v.fmt(f),
ExprKind::Tuple(v) => v.fmt(f), ExprKind::Tuple(v) => v.fmt(f),
ExprKind::Loop(v) => v.fmt(f),
ExprKind::While(v) => v.fmt(f), ExprKind::While(v) => v.fmt(f),
ExprKind::If(v) => v.fmt(f), ExprKind::If(v) => v.fmt(f),
ExprKind::For(v) => v.fmt(f), ExprKind::For(v) => v.fmt(f),
@ -542,6 +541,7 @@ mod display {
impl Display for UnaryKind { impl Display for UnaryKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
UnaryKind::Loop => "loop ",
UnaryKind::Deref => "*", UnaryKind::Deref => "*",
UnaryKind::Neg => "-", UnaryKind::Neg => "-",
UnaryKind::Not => "!", UnaryKind::Not => "!",
@ -644,13 +644,6 @@ mod display {
} }
} }
impl Display for Loop {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { body } = self;
write!(f, "loop {body}")
}
}
impl Display for While { impl Display for While {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { cond, pass, fail } = self; let Self { cond, pass, fail } = self;
@ -786,7 +779,6 @@ mod convert {
Block => ExprKind::Block, Block => ExprKind::Block,
Group => ExprKind::Group, Group => ExprKind::Group,
Tuple => ExprKind::Tuple, Tuple => ExprKind::Tuple,
Loop => ExprKind::Loop,
While => ExprKind::While, While => ExprKind::While,
If => ExprKind::If, If => ExprKind::If,
For => ExprKind::For, For => ExprKind::For,

View File

@ -339,10 +339,6 @@ pub trait Fold {
let Tuple { exprs } = t; let Tuple { exprs } = t;
Tuple { exprs: exprs.into_iter().map(|e| self.fold_expr(e)).collect() } Tuple { exprs: exprs.into_iter().map(|e| self.fold_expr(e)).collect() }
} }
fn fold_loop(&mut self, l: Loop) -> Loop {
let Loop { body } = l;
Loop { body: Box::new(self.fold_expr(*body)) }
}
fn fold_while(&mut self, w: While) -> While { fn fold_while(&mut self, w: While) -> While {
let While { cond, pass, fail } = w; let While { cond, pass, fail } = w;
While { While {
@ -552,7 +548,6 @@ pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> Ex
ExprKind::Block(b) => ExprKind::Block(folder.fold_block(b)), ExprKind::Block(b) => ExprKind::Block(folder.fold_block(b)),
ExprKind::Group(g) => ExprKind::Group(folder.fold_group(g)), ExprKind::Group(g) => ExprKind::Group(folder.fold_group(g)),
ExprKind::Tuple(t) => ExprKind::Tuple(folder.fold_tuple(t)), ExprKind::Tuple(t) => ExprKind::Tuple(folder.fold_tuple(t)),
ExprKind::Loop(l) => ExprKind::Loop(folder.fold_loop(l)),
ExprKind::While(w) => ExprKind::While(folder.fold_while(w)), ExprKind::While(w) => ExprKind::While(folder.fold_while(w)),
ExprKind::If(i) => ExprKind::If(folder.fold_if(i)), ExprKind::If(i) => ExprKind::If(folder.fold_if(i)),
ExprKind::For(f) => ExprKind::For(folder.fold_for(f)), ExprKind::For(f) => ExprKind::For(folder.fold_for(f)),

View File

@ -297,10 +297,6 @@ pub trait Visit<'a>: Sized {
let Tuple { exprs } = t; let Tuple { exprs } = t;
exprs.iter().for_each(|e| self.visit_expr(e)) exprs.iter().for_each(|e| self.visit_expr(e))
} }
fn visit_loop(&mut self, l: &'a Loop) {
let Loop { body } = l;
self.visit_expr(body)
}
fn visit_while(&mut self, w: &'a While) { fn visit_while(&mut self, w: &'a While) {
let While { cond, pass, fail } = w; let While { cond, pass, fail } = w;
self.visit_expr(cond); self.visit_expr(cond);
@ -476,7 +472,6 @@ pub fn or_visit_expr_kind<'a, V: Visit<'a>>(visitor: &mut V, e: &'a ExprKind) {
ExprKind::Block(b) => visitor.visit_block(b), ExprKind::Block(b) => visitor.visit_block(b),
ExprKind::Group(g) => visitor.visit_group(g), ExprKind::Group(g) => visitor.visit_group(g),
ExprKind::Tuple(t) => visitor.visit_tuple(t), ExprKind::Tuple(t) => visitor.visit_tuple(t),
ExprKind::Loop(l) => visitor.visit_loop(l),
ExprKind::While(w) => visitor.visit_while(w), ExprKind::While(w) => visitor.visit_while(w),
ExprKind::If(i) => visitor.visit_if(i), ExprKind::If(i) => visitor.visit_if(i),
ExprKind::For(f) => visitor.visit_for(f), ExprKind::For(f) => visitor.visit_for(f),

View File

@ -26,8 +26,8 @@ fn desugar_while(extents: Span, kind: ExprKind) -> ExprKind {
let break_expr = Expr { extents: fail_span, kind: ExprKind::Break(Break { body }) }; let break_expr = Expr { extents: fail_span, kind: ExprKind::Break(Break { body }) };
let loop_body = If { cond, pass, fail: Else { body: Some(Box::new(break_expr)) } }; let loop_body = If { cond, pass, fail: Else { body: Some(Box::new(break_expr)) } };
let loop_body = Expr { extents, kind: ExprKind::If(loop_body) }; let loop_body = ExprKind::If(loop_body);
ExprKind::Loop(Loop { body: Box::new(loop_body) }) ExprKind::Unary(Unary { kind: UnaryKind::Loop, tail: Box::new(loop_body) })
} }
_ => kind, _ => kind,
} }

View File

@ -151,7 +151,6 @@ impl Interpret for ExprKind {
ExprKind::Block(v) => v.interpret(env), ExprKind::Block(v) => v.interpret(env),
ExprKind::Group(v) => v.interpret(env), ExprKind::Group(v) => v.interpret(env),
ExprKind::Tuple(v) => v.interpret(env), ExprKind::Tuple(v) => v.interpret(env),
ExprKind::Loop(v) => v.interpret(env),
ExprKind::While(v) => v.interpret(env), ExprKind::While(v) => v.interpret(env),
ExprKind::If(v) => v.interpret(env), ExprKind::If(v) => v.interpret(env),
ExprKind::For(v) => v.interpret(env), ExprKind::For(v) => v.interpret(env),
@ -323,12 +322,28 @@ impl Interpret for Binary {
impl Interpret for Unary { impl Interpret for Unary {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> { fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
let Unary { kind, tail } = self; let Unary { kind, tail } = self;
let operand = tail.interpret(env)?;
match kind { match kind {
UnaryKind::Deref => env.call("deref".into(), &[operand]), UnaryKind::Loop => loop {
UnaryKind::Neg => env.call("neg".into(), &[operand]), match tail.interpret(env) {
UnaryKind::Not => env.call("not".into(), &[operand]), Err(Error::Break(value)) => return Ok(value),
Err(Error::Continue) => continue,
e => e?,
};
},
UnaryKind::Deref => {
let operand = tail.interpret(env)?;
env.call("deref".into(), &[operand])
}
UnaryKind::Neg => {
let operand = tail.interpret(env)?;
env.call("neg".into(), &[operand])
}
UnaryKind::Not => {
let operand = tail.interpret(env)?;
env.call("not".into(), &[operand])
}
UnaryKind::At => { UnaryKind::At => {
let operand = tail.interpret(env)?;
println!("{operand}"); println!("{operand}");
Ok(operand) Ok(operand)
} }
@ -505,18 +520,6 @@ impl Interpret for Tuple {
)) ))
} }
} }
impl Interpret for Loop {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
let Self { body } = self;
loop {
match body.interpret(env) {
Err(Error::Break(value)) => return Ok(value),
Err(Error::Continue) => continue,
e => e?,
};
}
}
}
impl Interpret for While { impl Interpret for While {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> { fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
let Self { cond, pass, fail } = self; let Self { cond, pass, fail } = self;

View File

@ -843,10 +843,6 @@ impl<'t> Parser<'t> {
TokenKind::LBrack => self.exprkind_arraylike()?, TokenKind::LBrack => self.exprkind_arraylike()?,
TokenKind::LParen => self.exprkind_tuplelike()?, TokenKind::LParen => self.exprkind_tuplelike()?,
TokenKind::Let => self.parse_let()?.into(), TokenKind::Let => self.parse_let()?.into(),
TokenKind::Loop => {
self.consume_peeked();
Loop { body: self.expr()?.into() }.into()
}
TokenKind::While => ExprKind::While(self.parse_while()?), TokenKind::While => ExprKind::While(self.parse_while()?),
TokenKind::If => ExprKind::If(self.parse_if()?), TokenKind::If => ExprKind::If(self.parse_if()?),
TokenKind::For => ExprKind::For(self.parse_for()?), TokenKind::For => ExprKind::For(self.parse_for()?),
@ -1250,6 +1246,7 @@ impl Precedence {
} }
pub fn prefix(self) -> Option<((), u8)> { pub fn prefix(self) -> Option<((), u8)> {
match self { match self {
Self::Assign => Some(((), self.level())),
Self::Unary => Some(((), self.level())), Self::Unary => Some(((), self.level())),
_ => None, _ => None,
} }
@ -1294,6 +1291,7 @@ impl From<UnaryKind> for Precedence {
fn from(value: UnaryKind) -> Self { fn from(value: UnaryKind) -> Self {
use UnaryKind as Op; use UnaryKind as Op;
match value { match value {
Op::Loop => Precedence::Assign,
Op::Deref | Op::Neg | Op::Not | Op::At | Op::Tilde => Precedence::Unary, Op::Deref | Op::Neg | Op::Not | Op::At | Op::Tilde => Precedence::Unary,
} }
} }
@ -1311,6 +1309,7 @@ macro operator($($name:ident ($takes:ident => $returns:ident) {$($t:ident => $p:
operator! { operator! {
from_prefix (TokenKind => UnaryKind) { from_prefix (TokenKind => UnaryKind) {
Loop => Loop,
Star => Deref, Star => Deref,
Minus => Neg, Minus => Neg,
Bang => Not, Bang => Not,

View File

@ -406,7 +406,6 @@ pub mod yamlify {
ExprKind::Empty => {} ExprKind::Empty => {}
ExprKind::Group(k) => k.yaml(y), ExprKind::Group(k) => k.yaml(y),
ExprKind::Tuple(k) => k.yaml(y), ExprKind::Tuple(k) => k.yaml(y),
ExprKind::Loop(k) => k.yaml(y),
ExprKind::While(k) => k.yaml(y), ExprKind::While(k) => k.yaml(y),
ExprKind::If(k) => k.yaml(y), ExprKind::If(k) => k.yaml(y),
ExprKind::For(k) => k.yaml(y), ExprKind::For(k) => k.yaml(y),
@ -537,12 +536,6 @@ pub mod yamlify {
y.key("Group").yaml(expr); y.key("Group").yaml(expr);
} }
} }
impl Yamlify for Loop {
fn yaml(&self, y: &mut Yamler) {
let Self { body } = self;
y.key("Loop").yaml(body);
}
}
impl Yamlify for While { impl Yamlify for While {
fn yaml(&self, y: &mut Yamler) { fn yaml(&self, y: &mut Yamler) {
let Self { cond, pass, fail } = self; let Self { cond, pass, fail } = self;