Skip to content

Commit

Permalink
Merge #119
Browse files Browse the repository at this point in the history
119: Add loop and other control flow expressions  r=Niki4tap a=xFrednet

This PR adds loop expressions and control flow expressions to Marker's API. With this `cargo dogfood` only complains about the path resolution of two generic parameters (which I'm planning to fix soon) and closures. The rest seems to be working 🎉.

For and While loops again have some interesting desugar, I tried to document them in the code. It seems to be working well, at least according to the test output.

Most of the changes should be test output and documentation as usual. Sorry, that it involves so many changes at once. (I'm totally not using Marker to procrastinate) 😅 

---

r? `@Niki4tap` If you have the time, I'd appreciate your feedback :)

cc: #52

Not much more to say. For everyone reading this, have a wonderful day :)

Co-authored-by: xFrednet <xFrednet@gmail.com>
  • Loading branch information
bors[bot] and xFrednet committed Mar 8, 2023
2 parents 2904e56 + 8d6f2cb commit 374befb
Show file tree
Hide file tree
Showing 10 changed files with 1,494 additions and 261 deletions.
16 changes: 13 additions & 3 deletions marker_api/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{fmt::Debug, marker::PhantomData};

mod block_expr;
mod call_exprs;
mod cond_expr;
mod control_flow_expr;
mod ctor_expr;
mod lit_expr;
mod op_exprs;
Expand All @@ -13,7 +13,7 @@ mod place_expr;
mod unstable_expr;
pub use block_expr::*;
pub use call_exprs::*;
pub use cond_expr::*;
pub use control_flow_expr::*;
pub use ctor_expr::*;
pub use lit_expr::*;
pub use op_exprs::*;
Expand Down Expand Up @@ -63,6 +63,12 @@ pub enum ExprKind<'ast> {
If(&'ast IfExpr<'ast>),
Let(&'ast LetExpr<'ast>),
Match(&'ast MatchExpr<'ast>),
Break(&'ast BreakExpr<'ast>),
Return(&'ast ReturnExpr<'ast>),
Continue(&'ast ContinueExpr<'ast>),
For(&'ast ForExpr<'ast>),
Loop(&'ast LoopExpr<'ast>),
While(&'ast WhileExpr<'ast>),
Unstable(&'ast UnstableExpr<'ast>),
}

Expand All @@ -81,6 +87,9 @@ pub enum ExprPrecedence {
Block = 0x1400_0001,
Ctor = 0x1400_0002,
Assign = 0x1400_0003,
For = 0x1400_0004,
Loop = 0x1400_0005,
While = 0x1400_0006,

Path = 0x1300_0000,

Expand Down Expand Up @@ -154,6 +163,7 @@ pub enum ExprPrecedence {
Closure = 0x0100_0000,
Break = 0x0100_0001,
Return = 0x0100_0002,
Continue = 0x0100_0003,
/// The precedence originates from an unstable source. The stored value provides
/// the current precedence of this expression. This might change in the future
Unstable(i32),
Expand All @@ -168,7 +178,7 @@ macro_rules! impl_expr_kind_fn {
Path, Index, Field,
Call, Method,
Array, Tuple, Ctor, Range,
If, Let, Match,
If, Let, Match, Break, Return, Continue, For, Loop, While,
Unstable
);
};
Expand Down
34 changes: 33 additions & 1 deletion marker_api/src/ast/expr/block_expr.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
use crate::{
ast::stmt::StmtKind,
ast::{stmt::StmtKind, Ident},
ffi::{FfiOption, FfiSlice},
};

use super::{CommonExprData, ExprKind};

/// A block expression is one of the most fundamental expressions in Rust. It
/// is used by items and expressions to group statements together and express
/// scopes.
///
/// ```
/// // vv The function body has an empty block
/// fn foo() {}
///
/// // vvvvvvv An unsafe block
/// let _ = unsafe {
/// 1 + 2
/// // ^^^^^ An expression which value is returned from the block, indicated
/// // by the missing semicolon at the end.
/// };
///
/// // vvvvvv An optional label to be targeted by break expressions
/// let _ = 'label: {
/// 12
/// };
/// ```
///
/// [`BlockExpr`] nodes are often simply called *blocks*, while the optional
/// expression at the end of a block is called *block expression*. The meaning
/// depends on the context. Marker's documentation will try to make the meaning
/// clear by linking directly to the [`BlockExpr`] struct or calling it a *block*.
#[repr(C)]
#[derive(Debug)]
pub struct BlockExpr<'ast> {
data: CommonExprData<'ast>,
stmts: FfiSlice<'ast, StmtKind<'ast>>,
expr: FfiOption<ExprKind<'ast>>,
label: FfiOption<Ident<'ast>>,
is_unsafe: bool,
}

Expand All @@ -27,6 +53,10 @@ impl<'ast> BlockExpr<'ast> {
self.expr.copy()
}

pub fn label(&self) -> Option<&Ident<'ast>> {
self.label.get()
}

pub fn is_unsafe(&self) -> bool {
self.is_unsafe
}
Expand All @@ -40,12 +70,14 @@ impl<'ast> BlockExpr<'ast> {
data: CommonExprData<'ast>,
stmts: &'ast [StmtKind<'ast>],
expr: Option<ExprKind<'ast>>,
label: Option<Ident<'ast>>,
is_unsafe: bool,
) -> Self {
Self {
data,
stmts: stmts.into(),
expr: expr.into(),
label: label.into(),
is_unsafe,
}
}
Expand Down
233 changes: 0 additions & 233 deletions marker_api/src/ast/expr/cond_expr.rs

This file was deleted.

Loading

0 comments on commit 374befb

Please sign in to comment.