Chunk of work on if-expr AST
don't expect this to compile yet
This commit is contained in:
parent
61b757313d
commit
95e278d1b5
1
TODO.md
1
TODO.md
@ -1,6 +1,7 @@
|
|||||||
# TODO items
|
# TODO items
|
||||||
|
|
||||||
## General code cleanup
|
## General code cleanup
|
||||||
|
- I think I can restructure the parser to get rid of most instances of expect!, at least at the beginning of a rule
|
||||||
DONE -experiment with storing metadata via ItemIds on AST nodes (cf. https://rust-lang.github.io/rustc-guide/hir.html, https://github.com/rust-lang/rust/blob/master/src/librustc/hir/mod.rs )
|
DONE -experiment with storing metadata via ItemIds on AST nodes (cf. https://rust-lang.github.io/rustc-guide/hir.html, https://github.com/rust-lang/rust/blob/master/src/librustc/hir/mod.rs )
|
||||||
-implement and test open/use statements
|
-implement and test open/use statements
|
||||||
-implement field access
|
-implement field access
|
||||||
|
@ -189,8 +189,8 @@ pub enum ExpressionKind {
|
|||||||
indexers: Vec<Expression>,
|
indexers: Vec<Expression>,
|
||||||
},
|
},
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: Box<Discriminator>,
|
discriminator: Option<Box<Expression>>,
|
||||||
body: Box<IfExpressionBody>,
|
body: IfExpressionBody,
|
||||||
},
|
},
|
||||||
WhileExpression {
|
WhileExpression {
|
||||||
condition: Option<Box<Expression>>,
|
condition: Option<Box<Expression>>,
|
||||||
@ -218,36 +218,33 @@ pub enum InvocationArgument {
|
|||||||
Ignored
|
Ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub enum Discriminator {
|
|
||||||
Simple(Expression),
|
|
||||||
BinOp(Expression, BinOp)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum IfExpressionBody {
|
pub enum IfExpressionBody {
|
||||||
SimpleConditional(Block, Option<Block>),
|
SimpleConditional {
|
||||||
SimplePatternMatch(Pattern, Block, Option<Block>),
|
then_case: Block,
|
||||||
GuardList(Vec<GuardArm>)
|
else_case: Option<Block>
|
||||||
|
},
|
||||||
|
SimplePatternMatch {
|
||||||
|
pattern: Pattern,
|
||||||
|
then_case: Block,
|
||||||
|
else_case: Option<Block>
|
||||||
|
},
|
||||||
|
CondList(Vec<ConditionArm>)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct GuardArm {
|
pub struct ConditionArm {
|
||||||
pub guard: Guard,
|
pub condition: Condition,
|
||||||
|
pub guard: Option<Expression>,
|
||||||
pub body: Block,
|
pub body: Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Guard {
|
pub enum Condition {
|
||||||
None,
|
Pattern(Pattern),
|
||||||
Pat(Pattern),
|
TruncatedOp(BinOp, Box<Expression>),
|
||||||
HalfExpr(HalfExpr)
|
Expression(Box<Expression>),
|
||||||
}
|
Else,
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub struct HalfExpr {
|
|
||||||
pub op: Option<BinOp>,
|
|
||||||
pub expr: ExpressionKind,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -119,13 +119,14 @@
|
|||||||
//! discriminator
|
//! discriminator
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
//! if_expr := "if" discriminator ("then" simple_conditional | "is" simple_pattern_match | cond_block)
|
//! if_expr := "if" discriminator if_expr_body
|
||||||
|
//! if_expr_body := ("then" simple_conditional | "is" simple_pattern_match | cond_block)
|
||||||
//! discriminator := ε | expression
|
//! discriminator := ε | expression
|
||||||
//! simple_conditional := expr_or_block else_clause
|
//! simple_conditional := expr_or_block else_case
|
||||||
//! simple_pattern_match := pattern "then" simple_conditional
|
//! simple_pattern_match := pattern "then" simple_conditional
|
||||||
//! else_clause := "else" expr_or_block
|
//! else_case := "else" expr_or_block
|
||||||
//!
|
//!
|
||||||
//! cond_block := "{" (cond_arm comma_or_delimiter)* "}"
|
//! cond_block := "{" (cond_arm comma_or_delimiter)* ("else" expr_or_block) "}"
|
||||||
//! cond_arm := condition guard "then" expr_or_block
|
//! cond_arm := condition guard "then" expr_or_block
|
||||||
//! condition := "is" pattern | operator precedence_expr | expression
|
//! condition := "is" pattern | operator precedence_expr | expression
|
||||||
//! guard := "if" expression
|
//! guard := "if" expression
|
||||||
@ -811,54 +812,44 @@ impl Parser {
|
|||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn if_expr(&mut self) -> ParseResult<Expression> {
|
fn if_expr(&mut self) -> ParseResult<Expression> {
|
||||||
expect!(self, Keyword(Kw::If));
|
expect!(self, Keyword(Kw::If));
|
||||||
let discriminator = Box::new({
|
let discriminator = if let LCurlyBrace = self.token_handler.peek_kind() {
|
||||||
self.restrictions.no_struct_literal = true;
|
Some(Box::new(self.expression()?))
|
||||||
let x = self.discriminator();
|
} else {
|
||||||
self.restrictions.no_struct_literal = false;
|
None
|
||||||
x?
|
};
|
||||||
});
|
let body = if_expr_body()?;
|
||||||
|
|
||||||
let body = Box::new(match self.token_handler.peek_kind() {
|
|
||||||
Keyword(Kw::Then) => self.conditional()?,
|
|
||||||
Keyword(Kw::Is) => self.simple_pattern_match()? ,
|
|
||||||
_ => self.guard_block()?
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(Expression::new(self.id_store.fresh(), ExpressionKind::IfExpression { discriminator, body }))
|
Ok(Expression::new(self.id_store.fresh(), ExpressionKind::IfExpression { discriminator, body }))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn discriminator(&mut self) -> ParseResult<Discriminator> {
|
fn if_expr_body(&mut self) -> ParseResult<IfExpressionBody> {
|
||||||
let lhs = self.prefix_expr()?;
|
match self.token_handler.peek_kind() {
|
||||||
let ref next = self.token_handler.peek_kind();
|
Keyword(Kw::Then) => self.simple_conditional()?,
|
||||||
Ok(if let Some(op) = BinOp::from_sigil_token(next) {
|
Keyword(Kw::Is) => self.simple_pattern_match()? ,
|
||||||
self.token_handler.next();
|
_ => self.cond_block()?
|
||||||
Discriminator::BinOp(lhs, op)
|
}
|
||||||
} else {
|
|
||||||
Discriminator::Simple(lhs)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn conditional(&mut self) -> ParseResult<IfExpressionBody> {
|
fn simple_conditional(&mut self) -> ParseResult<IfExpressionBody> {
|
||||||
expect!(self, Keyword(Kw::Then));
|
expect!(self, Keyword(Kw::Then));
|
||||||
let then_clause = self.expr_or_block()?;
|
let then_case = self.expr_or_block()?;
|
||||||
let else_clause = self.else_clause()?;
|
let else_case = self.else_case()?;
|
||||||
Ok(IfExpressionBody::SimpleConditional(then_clause, else_clause))
|
Ok(IfExpressionBody::SimpleConditional {then_case, else_case })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn simple_pattern_match(&mut self) -> ParseResult<IfExpressionBody> {
|
fn simple_pattern_match(&mut self) -> ParseResult<IfExpressionBody> {
|
||||||
expect!(self, Keyword(Kw::Is));
|
expect!(self, Keyword(Kw::Is));
|
||||||
let pat = self.pattern()?;
|
let pattern = self.pattern()?;
|
||||||
expect!(self, Keyword(Kw::Then));
|
expect!(self, Keyword(Kw::Then));
|
||||||
let then_clause = self.expr_or_block()?;
|
let then_case = self.expr_or_block()?;
|
||||||
let else_clause = self.else_clause()?;
|
let else_case = self.else_case()?;
|
||||||
Ok(IfExpressionBody::SimplePatternMatch(pat, then_clause, else_clause))
|
Ok(IfExpressionBody::SimplePatternMatch { pattern, then_case, else_case })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn else_clause(&mut self) -> ParseResult<Option<Block>> {
|
fn else_case(&mut self) -> ParseResult<Option<Block>> {
|
||||||
Ok(if let Keyword(Kw::Else) = self.token_handler.peek_kind() {
|
Ok(if let Keyword(Kw::Else) = self.token_handler.peek_kind() {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
Some(self.expr_or_block()?)
|
Some(self.expr_or_block()?)
|
||||||
@ -868,7 +859,7 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn guard_block(&mut self) -> ParseResult<IfExpressionBody> {
|
fn cond_block(&mut self) -> ParseResult<IfExpressionBody> {
|
||||||
//TODO - delimited! isn't sophisticated enough to do thisa
|
//TODO - delimited! isn't sophisticated enough to do thisa
|
||||||
//let guards = delimited!(self, LCurlyBrace, guard_arm, Comma, RCurlyBrace);
|
//let guards = delimited!(self, LCurlyBrace, guard_arm, Comma, RCurlyBrace);
|
||||||
expect!(self, LCurlyBrace);
|
expect!(self, LCurlyBrace);
|
||||||
|
Loading…
Reference in New Issue
Block a user