cl-ast: Move loop expression into unary exprs (with lowest priority)
This commit is contained in:
parent
b0341f06fd
commit
b64cc232f9
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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)),
|
||||||
|
@ -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),
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user