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),
/// A [Tuple] expression: `(` [`Expr`] (`,` [`Expr`])+ `)`
Tuple(Tuple),
/// A [Loop] expression: `loop` [`Block`]
Loop(Loop),
/// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]?
While(While),
/// An [If] expression: `if` [`Expr`] [`Block`] [`Else`]?
@ -482,6 +480,8 @@ pub enum UnaryKind {
Deref,
Neg,
Not,
/// A Loop expression: `loop` [`Block`]
Loop,
/// Unused
At,
/// Unused
@ -570,12 +570,6 @@ pub struct Tuple {
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`]?
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct While {

View File

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

View File

@ -339,10 +339,6 @@ pub trait Fold {
let Tuple { exprs } = t;
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 {
let While { cond, pass, fail } = w;
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::Group(g) => ExprKind::Group(folder.fold_group(g)),
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::If(i) => ExprKind::If(folder.fold_if(i)),
ExprKind::For(f) => ExprKind::For(folder.fold_for(f)),

View File

@ -297,10 +297,6 @@ pub trait Visit<'a>: Sized {
let Tuple { exprs } = t;
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) {
let While { cond, pass, fail } = w;
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::Group(g) => visitor.visit_group(g),
ExprKind::Tuple(t) => visitor.visit_tuple(t),
ExprKind::Loop(l) => visitor.visit_loop(l),
ExprKind::While(w) => visitor.visit_while(w),
ExprKind::If(i) => visitor.visit_if(i),
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 loop_body = If { cond, pass, fail: Else { body: Some(Box::new(break_expr)) } };
let loop_body = Expr { extents, kind: ExprKind::If(loop_body) };
ExprKind::Loop(Loop { body: Box::new(loop_body) })
let loop_body = ExprKind::If(loop_body);
ExprKind::Unary(Unary { kind: UnaryKind::Loop, tail: Box::new(loop_body) })
}
_ => kind,
}

View File

@ -151,7 +151,6 @@ impl Interpret for ExprKind {
ExprKind::Block(v) => v.interpret(env),
ExprKind::Group(v) => v.interpret(env),
ExprKind::Tuple(v) => v.interpret(env),
ExprKind::Loop(v) => v.interpret(env),
ExprKind::While(v) => v.interpret(env),
ExprKind::If(v) => v.interpret(env),
ExprKind::For(v) => v.interpret(env),
@ -323,12 +322,28 @@ impl Interpret for Binary {
impl Interpret for Unary {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
let Unary { kind, tail } = self;
let operand = tail.interpret(env)?;
match kind {
UnaryKind::Deref => env.call("deref".into(), &[operand]),
UnaryKind::Neg => env.call("neg".into(), &[operand]),
UnaryKind::Not => env.call("not".into(), &[operand]),
UnaryKind::Loop => loop {
match tail.interpret(env) {
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 => {
let operand = tail.interpret(env)?;
println!("{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 {
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
let Self { cond, pass, fail } = self;

View File

@ -843,10 +843,6 @@ impl<'t> Parser<'t> {
TokenKind::LBrack => self.exprkind_arraylike()?,
TokenKind::LParen => self.exprkind_tuplelike()?,
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::If => ExprKind::If(self.parse_if()?),
TokenKind::For => ExprKind::For(self.parse_for()?),
@ -1250,6 +1246,7 @@ impl Precedence {
}
pub fn prefix(self) -> Option<((), u8)> {
match self {
Self::Assign => Some(((), self.level())),
Self::Unary => Some(((), self.level())),
_ => None,
}
@ -1294,6 +1291,7 @@ impl From<UnaryKind> for Precedence {
fn from(value: UnaryKind) -> Self {
use UnaryKind as Op;
match value {
Op::Loop => Precedence::Assign,
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! {
from_prefix (TokenKind => UnaryKind) {
Loop => Loop,
Star => Deref,
Minus => Neg,
Bang => Not,

View File

@ -406,7 +406,6 @@ pub mod yamlify {
ExprKind::Empty => {}
ExprKind::Group(k) => k.yaml(y),
ExprKind::Tuple(k) => k.yaml(y),
ExprKind::Loop(k) => k.yaml(y),
ExprKind::While(k) => k.yaml(y),
ExprKind::If(k) => k.yaml(y),
ExprKind::For(k) => k.yaml(y),
@ -537,12 +536,6 @@ pub mod yamlify {
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 {
fn yaml(&self, y: &mut Yamler) {
let Self { cond, pass, fail } = self;