From b64cc232f924670fed08bd7b19e6dfa0f2bff3aa Mon Sep 17 00:00:00 2001 From: John Date: Tue, 30 Jul 2024 18:21:25 -0500 Subject: [PATCH] cl-ast: Move loop expression into unary exprs (with lowest priority) --- compiler/cl-ast/src/ast.rs | 10 ++---- compiler/cl-ast/src/ast_impl.rs | 10 +----- compiler/cl-ast/src/ast_visitor/fold.rs | 5 --- compiler/cl-ast/src/ast_visitor/visit.rs | 5 --- compiler/cl-ast/src/desugar/while_else.rs | 4 +-- compiler/cl-interpret/src/interpret.rs | 37 ++++++++++++----------- compiler/cl-parser/src/parser.rs | 7 ++--- compiler/cl-repl/examples/yaml.rs | 7 ----- 8 files changed, 28 insertions(+), 57 deletions(-) diff --git a/compiler/cl-ast/src/ast.rs b/compiler/cl-ast/src/ast.rs index 663fcd0..18b31cc 100644 --- a/compiler/cl-ast/src/ast.rs +++ b/compiler/cl-ast/src/ast.rs @@ -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, } -/// A [Loop] expression: `loop` [`Block`] -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Loop { - pub body: Box, -} - /// A [While] expression: `while` [`Expr`] [`Block`] [`Else`]? #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct While { diff --git a/compiler/cl-ast/src/ast_impl.rs b/compiler/cl-ast/src/ast_impl.rs index e3693e3..543b98b 100644 --- a/compiler/cl-ast/src/ast_impl.rs +++ b/compiler/cl-ast/src/ast_impl.rs @@ -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, diff --git a/compiler/cl-ast/src/ast_visitor/fold.rs b/compiler/cl-ast/src/ast_visitor/fold.rs index 7f9c4ad..20fc7bd 100644 --- a/compiler/cl-ast/src/ast_visitor/fold.rs +++ b/compiler/cl-ast/src/ast_visitor/fold.rs @@ -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(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)), diff --git a/compiler/cl-ast/src/ast_visitor/visit.rs b/compiler/cl-ast/src/ast_visitor/visit.rs index 5c99353..6c60cec 100644 --- a/compiler/cl-ast/src/ast_visitor/visit.rs +++ b/compiler/cl-ast/src/ast_visitor/visit.rs @@ -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), diff --git a/compiler/cl-ast/src/desugar/while_else.rs b/compiler/cl-ast/src/desugar/while_else.rs index 0cac483..3a75f02 100644 --- a/compiler/cl-ast/src/desugar/while_else.rs +++ b/compiler/cl-ast/src/desugar/while_else.rs @@ -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, } diff --git a/compiler/cl-interpret/src/interpret.rs b/compiler/cl-interpret/src/interpret.rs index 49ccf6a..75ca6c3 100644 --- a/compiler/cl-interpret/src/interpret.rs +++ b/compiler/cl-interpret/src/interpret.rs @@ -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 { 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 { - 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 { let Self { cond, pass, fail } = self; diff --git a/compiler/cl-parser/src/parser.rs b/compiler/cl-parser/src/parser.rs index 32fdbd6..0b1ad27 100644 --- a/compiler/cl-parser/src/parser.rs +++ b/compiler/cl-parser/src/parser.rs @@ -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 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, diff --git a/compiler/cl-repl/examples/yaml.rs b/compiler/cl-repl/examples/yaml.rs index 16655d0..cce7153 100644 --- a/compiler/cl-repl/examples/yaml.rs +++ b/compiler/cl-repl/examples/yaml.rs @@ -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;