i dont think this is the right way to do this, in hindsight
This commit is contained in:
parent
028c74753e
commit
51aa119af2
299
src/ast2/mod.rs
299
src/ast2/mod.rs
|
@ -484,6 +484,48 @@ impl Data {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
enum PlaceOrValue {
|
||||||
|
Value(index::Index),
|
||||||
|
Place(index::Index),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlaceOrValue {
|
||||||
|
fn into_index(self) -> index::Index {
|
||||||
|
match self {
|
||||||
|
PlaceOrValue::Value(index) => index,
|
||||||
|
PlaceOrValue::Place(index) => index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn is_value(&self) -> bool {
|
||||||
|
matches!(self, &Self::Value(_))
|
||||||
|
}
|
||||||
|
fn is_place(&self) -> bool {
|
||||||
|
!self.is_value()
|
||||||
|
}
|
||||||
|
fn into_value(self) -> PlaceOrValue {
|
||||||
|
Self::Value(self.into_index())
|
||||||
|
}
|
||||||
|
fn into_place(self) -> PlaceOrValue {
|
||||||
|
Self::Place(self.into_index())
|
||||||
|
}
|
||||||
|
fn eq_discriminant(&self, other: &Self) -> bool {
|
||||||
|
core::mem::discriminant(self).eq(&core::mem::discriminant(other))
|
||||||
|
}
|
||||||
|
fn with_index(self, index: Index) -> PlaceOrValue {
|
||||||
|
match self {
|
||||||
|
PlaceOrValue::Value(_) => Self::Value(index),
|
||||||
|
PlaceOrValue::Place(_) => Self::Place(index),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<index::Index> for PlaceOrValue {
|
||||||
|
fn from(value: index::Index) -> Self {
|
||||||
|
Self::Value(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod index {
|
mod index {
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
|
|
||||||
|
@ -968,10 +1010,39 @@ impl Ast {
|
||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_unary(&mut self, tag: Tag, lhs: Index, loc: SourceLocation) -> Index {
|
fn push_unary(&mut self, tag: Tag, lhs: Index, loc: SourceLocation) -> PlaceOrValue {
|
||||||
let i = self.reserve_node_other();
|
let i = self.reserve_node_other();
|
||||||
self.set_tag_data_source_loc(i, tag, Data::index(lhs), loc);
|
self.set_tag_data_source_loc(i, tag, Data::index(lhs), loc);
|
||||||
|
|
||||||
|
match tag {
|
||||||
|
Tag::Deref => PlaceOrValue::Place(i),
|
||||||
|
_ => PlaceOrValue::Value(i),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// converts from a place expression to a value expression.
|
||||||
|
fn push_place_to_value_conversion(&mut self, rvalue: Index, loc: SourceLocation) -> Index {
|
||||||
|
let i = self.reserve_node_other();
|
||||||
|
self.set_tag_data_source_loc(
|
||||||
|
rvalue,
|
||||||
|
Tag::PlaceToValueConversion,
|
||||||
|
Data::index(rvalue),
|
||||||
|
loc,
|
||||||
|
);
|
||||||
|
|
||||||
|
i
|
||||||
|
}
|
||||||
|
|
||||||
|
/// converts from a value expression to a place expression.
|
||||||
|
fn push_value_to_place_conversion(&mut self, rvalue: Index, loc: SourceLocation) -> Index {
|
||||||
|
let i = self.reserve_node_other();
|
||||||
|
self.set_tag_data_source_loc(
|
||||||
|
rvalue,
|
||||||
|
Tag::ValueToPlaceConversion,
|
||||||
|
Data::index(rvalue),
|
||||||
|
loc,
|
||||||
|
);
|
||||||
|
|
||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,11 +1169,11 @@ impl Ast {
|
||||||
expr: Index,
|
expr: Index,
|
||||||
name: intern::Index,
|
name: intern::Index,
|
||||||
loc: SourceLocation,
|
loc: SourceLocation,
|
||||||
) -> Index {
|
) -> PlaceOrValue {
|
||||||
let i = self.reserve_node_other();
|
let i = self.reserve_node_other();
|
||||||
self.set_tag_data_source_loc(i, Tag::FieldAccess, Data::index_and_intern(expr, name), loc);
|
self.set_tag_data_source_loc(i, Tag::FieldAccess, Data::index_and_intern(expr, name), loc);
|
||||||
|
|
||||||
i
|
PlaceOrValue::Place(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_interend_type(&mut self, ty: intern::Index, loc: SourceLocation) -> Index {
|
fn push_interend_type(&mut self, ty: intern::Index, loc: SourceLocation) -> Index {
|
||||||
|
@ -2786,7 +2857,7 @@ pub mod ast_gen {
|
||||||
fn parse_array_type(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_array_type(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
||||||
let loc = tokens.current_source_location();
|
let loc = tokens.current_source_location();
|
||||||
let length_expr = self.parse_bracketed(tokens, |this, tokens| {
|
let length_expr = self.parse_bracketed(tokens, |this, tokens| {
|
||||||
this.parse_expr(tokens)
|
this.parse_value_expr(tokens)
|
||||||
// let next = tokens.peek_token().ok_or(ErrorInfo {
|
// let next = tokens.peek_token().ok_or(ErrorInfo {
|
||||||
// error: ParseError::UnexpectedEndOfTokens,
|
// error: ParseError::UnexpectedEndOfTokens,
|
||||||
// loc: tokens.current_source_location(),
|
// loc: tokens.current_source_location(),
|
||||||
|
@ -3069,7 +3140,7 @@ pub mod ast_gen {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
let expr = match self.parse_expr(tokens) {
|
let expr = match self.parse_value_expr(tokens) {
|
||||||
Ok(i) => i,
|
Ok(i) => i,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
break 'blk err;
|
break 'blk err;
|
||||||
|
@ -3147,10 +3218,13 @@ pub mod ast_gen {
|
||||||
self.pop_scope();
|
self.pop_scope();
|
||||||
e
|
e
|
||||||
})?;
|
})?;
|
||||||
let body = self.parse_block(tokens).map_err(|e| {
|
let body = self
|
||||||
self.pop_scope();
|
.parse_block(tokens)
|
||||||
e
|
.map(|pv| self.convert_to_value_expr(pv))
|
||||||
})?;
|
.map_err(|e| {
|
||||||
|
self.pop_scope();
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
|
||||||
self.pop_scope();
|
self.pop_scope();
|
||||||
|
|
||||||
|
@ -3184,7 +3258,7 @@ pub mod ast_gen {
|
||||||
let expr = if tokens.eat_token(Token::Semi).is_some() {
|
let expr = if tokens.eat_token(Token::Semi).is_some() {
|
||||||
self.ast.push_ret(None, loc)
|
self.ast.push_ret(None, loc)
|
||||||
} else {
|
} else {
|
||||||
match self.parse_expr(tokens) {
|
match self.parse_value_expr(tokens) {
|
||||||
Ok(i) => {
|
Ok(i) => {
|
||||||
tokens.eat_token(Token::Semi).ok_or(ErrorInfo {
|
tokens.eat_token(Token::Semi).ok_or(ErrorInfo {
|
||||||
error: ParseError::ExpectedToken(Token::Semi),
|
error: ParseError::ExpectedToken(Token::Semi),
|
||||||
|
@ -3243,7 +3317,7 @@ pub mod ast_gen {
|
||||||
};
|
};
|
||||||
|
|
||||||
let assignment = if tokens.eat_token(Token::Equal).is_some() {
|
let assignment = if tokens.eat_token(Token::Equal).is_some() {
|
||||||
Some(self.parse_expr(tokens)?)
|
Some(self.parse_value_expr(tokens)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -3263,7 +3337,7 @@ pub mod ast_gen {
|
||||||
&mut self,
|
&mut self,
|
||||||
block: Index,
|
block: Index,
|
||||||
tokens: &mut TokenIterator,
|
tokens: &mut TokenIterator,
|
||||||
) -> ParseResult<Index> {
|
) -> ParseResult<PlaceOrValue> {
|
||||||
let loc = tokens.current_source_location();
|
let loc = tokens.current_source_location();
|
||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
|
|
||||||
|
@ -3291,7 +3365,7 @@ pub mod ast_gen {
|
||||||
// expr -> statements
|
// expr -> statements
|
||||||
let expr = self
|
let expr = self
|
||||||
.parse_with_trailing_semi(tokens, |this, tokens| {
|
.parse_with_trailing_semi(tokens, |this, tokens| {
|
||||||
this.parse_expr(tokens)
|
Ok(this.parse_expr(tokens)?.into_index())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
statements.push(expr);
|
statements.push(expr);
|
||||||
|
@ -3312,13 +3386,22 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.ast.set_block(block, statements, trailing, loc);
|
self.ast.set_block(
|
||||||
|
block,
|
||||||
|
statements,
|
||||||
|
trailing.map(PlaceOrValue::into_index),
|
||||||
|
loc,
|
||||||
|
);
|
||||||
|
|
||||||
|
let block = trailing
|
||||||
|
.map(|pv| pv.with_index(block))
|
||||||
|
.unwrap_or(PlaceOrValue::Value(block));
|
||||||
Ok(block)
|
Ok(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// BLOCK <-
|
/// BLOCK <-
|
||||||
/// { STATEMENT* EXPRESSION? }
|
/// { STATEMENT* EXPRESSION? }
|
||||||
fn parse_block(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_block(&mut self, tokens: &mut TokenIterator) -> ParseResult<PlaceOrValue> {
|
||||||
let block = self.parse_braced(tokens, |this, tokens| {
|
let block = self.parse_braced(tokens, |this, tokens| {
|
||||||
let block = this.ast.reserve_node_other();
|
let block = this.ast.reserve_node_other();
|
||||||
this.push_scope(block, intern::Index::invalid());
|
this.push_scope(block, intern::Index::invalid());
|
||||||
|
@ -3388,7 +3471,7 @@ pub mod ast_gen {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let expr = self.parse_expr(tokens)?;
|
let expr = self.parse_value_expr(tokens)?;
|
||||||
|
|
||||||
let i = match name {
|
let i = match name {
|
||||||
Some(name) => self.ast.push_named_argument(name, expr, loc),
|
Some(name) => self.ast.push_named_argument(name, expr, loc),
|
||||||
|
@ -3425,7 +3508,7 @@ pub mod ast_gen {
|
||||||
/// FLOATING_CONSTANT
|
/// FLOATING_CONSTANT
|
||||||
/// ( EXPRESSION )
|
/// ( EXPRESSION )
|
||||||
/// BLOCK
|
/// BLOCK
|
||||||
fn parse_primary_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_primary_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<PlaceOrValue> {
|
||||||
let loc = tokens.current_source_location();
|
let loc = tokens.current_source_location();
|
||||||
|
|
||||||
let Some(next) = tokens.peek_token() else {
|
let Some(next) = tokens.peek_token() else {
|
||||||
|
@ -3441,14 +3524,18 @@ pub mod ast_gen {
|
||||||
| Token::IntegerOctConstant
|
| Token::IntegerOctConstant
|
||||||
| Token::IntegerConstant => {
|
| Token::IntegerConstant => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
return Ok(self.parse_integral_constant(&next, next.source_location()));
|
return Ok(PlaceOrValue::Value(
|
||||||
|
self.parse_integral_constant(&next, next.source_location()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Token::FloatingConstant
|
Token::FloatingConstant
|
||||||
| Token::FloatingExpConstant
|
| Token::FloatingExpConstant
|
||||||
| Token::DotFloatingConstant
|
| Token::DotFloatingConstant
|
||||||
| Token::DotFloatingExpConstant => {
|
| Token::DotFloatingExpConstant => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
return Ok(self.parse_floating_constant(&next, next.source_location()));
|
return Ok(PlaceOrValue::Value(
|
||||||
|
self.parse_floating_constant(&next, next.source_location()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::OpenParens => {
|
Token::OpenParens => {
|
||||||
|
@ -3458,7 +3545,7 @@ pub mod ast_gen {
|
||||||
return Ok(expr);
|
return Ok(expr);
|
||||||
}
|
}
|
||||||
Token::OpenBrace => {
|
Token::OpenBrace => {
|
||||||
return self.parse_block(tokens);
|
return Ok(self.parse_block(tokens)?);
|
||||||
}
|
}
|
||||||
Token::Ident => {
|
Token::Ident => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
|
@ -3466,9 +3553,12 @@ pub mod ast_gen {
|
||||||
let ident = self
|
let ident = self
|
||||||
.intern
|
.intern
|
||||||
.get_or_insert(intern::Key::String { str: ident });
|
.get_or_insert(intern::Key::String { str: ident });
|
||||||
return Ok(self
|
|
||||||
.ast
|
return Ok(PlaceOrValue::Place(self.ast.push_decl_ref_unresolved(
|
||||||
.push_decl_ref_unresolved(self.current_scope(), ident, loc));
|
self.current_scope(),
|
||||||
|
ident,
|
||||||
|
loc,
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
// TODO: eventually handle paths
|
// TODO: eventually handle paths
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -3486,7 +3576,7 @@ pub mod ast_gen {
|
||||||
/// PRIMARY_EXPR ( ARGUMENT_LIST )
|
/// PRIMARY_EXPR ( ARGUMENT_LIST )
|
||||||
/// PRIMARY_EXPR [ EXPR ]
|
/// PRIMARY_EXPR [ EXPR ]
|
||||||
/// POSTFIX_EXPR . IDENTIFIER
|
/// POSTFIX_EXPR . IDENTIFIER
|
||||||
fn parse_postfix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_postfix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<PlaceOrValue> {
|
||||||
let mut lhs = self.parse_primary_expr(tokens)?;
|
let mut lhs = self.parse_primary_expr(tokens)?;
|
||||||
while let Some(postfix) = self.try_parse_postfix_expr_inner(tokens, lhs)? {
|
while let Some(postfix) = self.try_parse_postfix_expr_inner(tokens, lhs)? {
|
||||||
lhs = postfix;
|
lhs = postfix;
|
||||||
|
@ -3498,8 +3588,8 @@ pub mod ast_gen {
|
||||||
fn try_parse_postfix_expr_inner(
|
fn try_parse_postfix_expr_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
tokens: &mut TokenIterator,
|
tokens: &mut TokenIterator,
|
||||||
lhs: Index,
|
lhs: PlaceOrValue,
|
||||||
) -> ParseResult<Option<Index>> {
|
) -> ParseResult<Option<PlaceOrValue>> {
|
||||||
let lhs = if let Some(next) = tokens.peek_token() {
|
let lhs = if let Some(next) = tokens.peek_token() {
|
||||||
let loc = next.source_location();
|
let loc = next.source_location();
|
||||||
match next.token() {
|
match next.token() {
|
||||||
|
@ -3511,21 +3601,30 @@ pub mod ast_gen {
|
||||||
this.parse_argument_list(tokens)
|
this.parse_argument_list(tokens)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
let lhs = self.convert_to_value_expr(lhs);
|
||||||
|
|
||||||
Some(self.ast.push_call_expr(lhs, arguments, loc))
|
Some(PlaceOrValue::Value(
|
||||||
|
self.ast.push_call_expr(lhs, arguments, loc),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Token::OpenSquareBracket => {
|
Token::OpenSquareBracket => {
|
||||||
let subscript =
|
let subscript = self.parse_bracketed(tokens, |this, tokens| {
|
||||||
self.parse_bracketed(tokens, |this, tokens| this.parse_expr(tokens))?;
|
this.parse_value_expr(tokens)
|
||||||
|
})?;
|
||||||
|
|
||||||
Some(
|
let lhs = self.convert_to_value_expr(lhs);
|
||||||
self.ast
|
|
||||||
.push_binary(Tag::SubscriptExpr, lhs, subscript, loc),
|
Some(PlaceOrValue::Place(self.ast.push_binary(
|
||||||
)
|
Tag::SubscriptExpr,
|
||||||
|
lhs,
|
||||||
|
subscript,
|
||||||
|
loc,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
Token::Dot if tokens.is_next_token2(Token::Ident) => {
|
Token::Dot if tokens.is_next_token2(Token::Ident) => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
let loc = tokens.current_source_location();
|
let loc = tokens.current_source_location();
|
||||||
|
let lhs = self.convert_to_place_expr(lhs);
|
||||||
let name = self.parse_ident(tokens)?;
|
let name = self.parse_ident(tokens)?;
|
||||||
|
|
||||||
Some(self.ast.push_field_access(lhs, name, loc))
|
Some(self.ast.push_field_access(lhs, name, loc))
|
||||||
|
@ -3544,13 +3643,31 @@ pub mod ast_gen {
|
||||||
self.ast.push_error(error, loc)
|
self.ast.push_error(error, loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// converts the expression to a value expression, if it isn't one already.
|
||||||
|
fn convert_to_value_expr(&mut self, lrvalue: PlaceOrValue) -> Index {
|
||||||
|
let loc = self.ast.get_loc(lrvalue.into_index());
|
||||||
|
match lrvalue {
|
||||||
|
PlaceOrValue::Value(index) => index,
|
||||||
|
PlaceOrValue::Place(index) => self.ast.push_place_to_value_conversion(index, loc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// converts the expression to a place expression, if it isn't one already.
|
||||||
|
fn convert_to_place_expr(&mut self, lrvalue: PlaceOrValue) -> Index {
|
||||||
|
let loc = self.ast.get_loc(lrvalue.into_index());
|
||||||
|
match lrvalue {
|
||||||
|
PlaceOrValue::Place(index) => index,
|
||||||
|
PlaceOrValue::Value(index) => self.ast.push_value_to_place_conversion(index, loc),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// PREFIX_EXPR <-
|
/// PREFIX_EXPR <-
|
||||||
/// POSTFIX_EXPR
|
/// POSTFIX_EXPR
|
||||||
/// ! POSTFIX_EXPR
|
/// ! POSTFIX_EXPR
|
||||||
/// - POSTFIX_EXPR
|
/// - POSTFIX_EXPR
|
||||||
/// & POSTFIX_EXPR
|
/// & POSTFIX_EXPR
|
||||||
/// * POSTFIX_EXPR
|
/// * POSTFIX_EXPR
|
||||||
fn parse_prefix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_prefix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<PlaceOrValue> {
|
||||||
let next = tokens.peek_token().ok_or(ErrorInfo {
|
let next = tokens.peek_token().ok_or(ErrorInfo {
|
||||||
error: ParseError::ExpectedPrefixExpression,
|
error: ParseError::ExpectedPrefixExpression,
|
||||||
loc: tokens.current_source_location(),
|
loc: tokens.current_source_location(),
|
||||||
|
@ -3561,23 +3678,31 @@ pub mod ast_gen {
|
||||||
let expr = match next.token() {
|
let expr = match next.token() {
|
||||||
Token::Bang => {
|
Token::Bang => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
let lhs = self.parse_postfix_expr(tokens)?;
|
let lhs = self.parse_prefix_expr(tokens)?;
|
||||||
|
let lhs = self.convert_to_value_expr(lhs);
|
||||||
self.ast.push_unary(Tag::Not, lhs, loc)
|
self.ast.push_unary(Tag::Not, lhs, loc)
|
||||||
}
|
}
|
||||||
Token::Minus => {
|
Token::Minus => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
let lhs = self.parse_postfix_expr(tokens)?;
|
let lhs = self.parse_prefix_expr(tokens)?;
|
||||||
|
let lhs = self.convert_to_value_expr(lhs);
|
||||||
self.ast.push_unary(Tag::Negate, lhs, loc)
|
self.ast.push_unary(Tag::Negate, lhs, loc)
|
||||||
}
|
}
|
||||||
Token::Ampersand => {
|
Token::Ampersand => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
let lhs = self.parse_postfix_expr(tokens)?;
|
// the address-of operator requires lhs to be a place
|
||||||
|
// expression. not all expressions that might be the lhs
|
||||||
|
// are automatically place expressions: the construct `let a
|
||||||
|
// = &3;` has `3`, which is a value expression, as the lhs
|
||||||
|
// of the address-of operator.
|
||||||
|
let lhs = self.parse_prefix_expr(tokens)?;
|
||||||
|
let lhs = self.convert_to_place_expr(lhs);
|
||||||
self.ast.push_unary(Tag::AddressOf, lhs, loc)
|
self.ast.push_unary(Tag::AddressOf, lhs, loc)
|
||||||
}
|
}
|
||||||
Token::Star => {
|
Token::Star => {
|
||||||
_ = tokens.next();
|
_ = tokens.next();
|
||||||
let lhs = self.parse_postfix_expr(tokens)?;
|
let lhs = self.parse_prefix_expr(tokens)?;
|
||||||
self.ast.push_unary(Tag::Deref, lhs, loc)
|
self.ast.push_unary(Tag::Deref, lhs.into_index(), loc)
|
||||||
}
|
}
|
||||||
_ => self.parse_postfix_expr(tokens)?,
|
_ => self.parse_postfix_expr(tokens)?,
|
||||||
};
|
};
|
||||||
|
@ -3590,7 +3715,8 @@ pub mod ast_gen {
|
||||||
/// PREFIX_EXPR as TYPENAME
|
/// PREFIX_EXPR as TYPENAME
|
||||||
fn parse_as_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_as_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
||||||
let loc = tokens.current_source_location();
|
let loc = tokens.current_source_location();
|
||||||
let expr = self.parse_prefix_expr(tokens)?;
|
let maybe_rvalue = self.parse_prefix_expr(tokens)?;
|
||||||
|
let expr = self.convert_to_value_expr(maybe_rvalue);
|
||||||
|
|
||||||
if tokens.eat_token(Token::As).is_some() {
|
if tokens.eat_token(Token::As).is_some() {
|
||||||
let typename = self.parse_type(tokens)?;
|
let typename = self.parse_type(tokens)?;
|
||||||
|
@ -3691,7 +3817,7 @@ pub mod ast_gen {
|
||||||
// SAFETY: we peeked
|
// SAFETY: we peeked
|
||||||
let op = tokens.next().unwrap();
|
let op = tokens.next().unwrap();
|
||||||
let loc = op.source_location();
|
let loc = op.source_location();
|
||||||
let rhs = self.parse_expr(tokens)?;
|
let rhs = self.parse_place_expr(tokens)?;
|
||||||
|
|
||||||
let rhs = if op.token() == Token::Equal {
|
let rhs = if op.token() == Token::Equal {
|
||||||
rhs
|
rhs
|
||||||
|
@ -3722,7 +3848,7 @@ pub mod ast_gen {
|
||||||
|
|
||||||
/// ELSE_EXPR <-
|
/// ELSE_EXPR <-
|
||||||
/// 'else' (IF_EXPR | EXPR_OR_STATEMENT_OR_BLOCK)
|
/// 'else' (IF_EXPR | EXPR_OR_STATEMENT_OR_BLOCK)
|
||||||
fn parse_else_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_else_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<PlaceOrValue> {
|
||||||
// SAFETY: function invariance
|
// SAFETY: function invariance
|
||||||
let _else_ = tokens.eat_token(Token::Else).unwrap();
|
let _else_ = tokens.eat_token(Token::Else).unwrap();
|
||||||
|
|
||||||
|
@ -3735,27 +3861,33 @@ pub mod ast_gen {
|
||||||
|
|
||||||
/// IF_EXPR <-
|
/// IF_EXPR <-
|
||||||
/// 'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR?
|
/// 'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR?
|
||||||
fn parse_if_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_if_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<PlaceOrValue> {
|
||||||
// SAFETY: function invariance
|
// SAFETY: function invariance
|
||||||
let iff = tokens.eat_token(Token::If).unwrap();
|
let iff = tokens.eat_token(Token::If).unwrap();
|
||||||
let loc = iff.source_location();
|
let loc = iff.source_location();
|
||||||
|
|
||||||
let cond = self.parse_parenthesised(tokens, |this, tokens| this.parse_expr(tokens))?;
|
let cond =
|
||||||
|
self.parse_parenthesised(tokens, |this, tokens| this.parse_value_expr(tokens))?;
|
||||||
|
|
||||||
let body = self.parse_expr_or_block_as_block(tokens)?;
|
let body = self.parse_expr_or_block_as_block(tokens)?;
|
||||||
|
|
||||||
if tokens.is_next_token(Token::Else) {
|
if tokens.is_next_token(Token::Else) {
|
||||||
let else_expr = self.parse_else_expr(tokens)?;
|
let else_expr = self.parse_else_expr(tokens)?;
|
||||||
Ok(self.ast.push_if_else(cond, body, else_expr, loc))
|
Ok(body.with_index(self.ast.push_if_else(
|
||||||
|
cond,
|
||||||
|
body.into_index(),
|
||||||
|
else_expr.into_index(),
|
||||||
|
loc,
|
||||||
|
)))
|
||||||
} else {
|
} else {
|
||||||
Ok(self.ast.push_if(cond, body, loc))
|
Ok(body.with_index(self.ast.push_if(cond, body.into_index(), loc)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expr_or_block_as_block(
|
fn parse_expr_or_block_as_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
tokens: &mut TokenIterator,
|
tokens: &mut TokenIterator,
|
||||||
) -> ParseResult<Index> {
|
) -> ParseResult<PlaceOrValue> {
|
||||||
let Some(next) = tokens.peek_token() else {
|
let Some(next) = tokens.peek_token() else {
|
||||||
return Err(ErrorInfo {
|
return Err(ErrorInfo {
|
||||||
error: ParseError::ExpectedExpression,
|
error: ParseError::ExpectedExpression,
|
||||||
|
@ -3768,12 +3900,12 @@ pub mod ast_gen {
|
||||||
_ => {
|
_ => {
|
||||||
let loc = tokens.current_source_location();
|
let loc = tokens.current_source_location();
|
||||||
let expr = self.parse_expr(tokens)?;
|
let expr = self.parse_expr(tokens)?;
|
||||||
Ok(self.ast.push_block([], Some(expr), loc))
|
Ok(expr.with_index(self.ast.push_block([], Some(expr.into_index()), loc)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
fn parse_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<PlaceOrValue> {
|
||||||
let loc = tokens.current_source_location();
|
let loc = tokens.current_source_location();
|
||||||
let Some(next) = tokens.peek_token() else {
|
let Some(next) = tokens.peek_token() else {
|
||||||
return Err(ErrorInfo {
|
return Err(ErrorInfo {
|
||||||
|
@ -3782,10 +3914,27 @@ pub mod ast_gen {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
match next.token() {
|
let expr = match next.token() {
|
||||||
Token::If => self.parse_if_expr(tokens),
|
Token::If => self.parse_if_expr(tokens)?,
|
||||||
_ => self.parse_assignment_expr(tokens),
|
_ => PlaceOrValue::Value(self.parse_assignment_expr(tokens)?),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Ok(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_place_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
||||||
|
// TODO: panic if not place expr
|
||||||
|
let expr = self.parse_expr(tokens)?;
|
||||||
|
let expr = self.convert_to_place_expr(expr);
|
||||||
|
|
||||||
|
Ok(expr)
|
||||||
|
}
|
||||||
|
fn parse_value_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
|
||||||
|
// TODO: convert from place to value (lvalue-to-rvalue)
|
||||||
|
let expr = self.parse_expr(tokens)?;
|
||||||
|
let expr = self.convert_to_value_expr(expr);
|
||||||
|
|
||||||
|
Ok(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TYPE_DECL <-
|
/// TYPE_DECL <-
|
||||||
|
@ -3925,13 +4074,14 @@ pub mod ast_gen {
|
||||||
Ok(decl)
|
Ok(decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_with_trailing_semi<F>(
|
fn parse_with_trailing_semi<F, I>(
|
||||||
&mut self,
|
&mut self,
|
||||||
tokens: &mut TokenIterator,
|
tokens: &mut TokenIterator,
|
||||||
parse: F,
|
parse: F,
|
||||||
) -> ParseResult<Index>
|
) -> ParseResult<I>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
|
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<I>,
|
||||||
|
Index: Into<I>,
|
||||||
{
|
{
|
||||||
match parse(self, tokens) {
|
match parse(self, tokens) {
|
||||||
Ok(i) => {
|
Ok(i) => {
|
||||||
|
@ -3947,22 +4097,22 @@ pub mod ast_gen {
|
||||||
error: ParseError::ExpectedToken(Token::Semi),
|
error: ParseError::ExpectedToken(Token::Semi),
|
||||||
loc: tokens.current_source_location(),
|
loc: tokens.current_source_location(),
|
||||||
})?;
|
})?;
|
||||||
Ok(self.push_error(err.error, err.loc))
|
Ok(self.push_error(err.error, err.loc).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_inner<F, E>(
|
fn parse_inner<F, I, E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
tokens: &mut TokenIterator,
|
tokens: &mut TokenIterator,
|
||||||
open: Token,
|
open: Token,
|
||||||
close: Token,
|
close: Token,
|
||||||
parse: F,
|
parse: F,
|
||||||
on_err: E,
|
on_err: E,
|
||||||
) -> ParseResult<Index>
|
) -> ParseResult<I>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
|
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<I>,
|
||||||
E: FnOnce(&mut Self, &mut TokenIterator, ErrorInfo, TokenItem) -> ParseResult<Index>,
|
E: FnOnce(&mut Self, &mut TokenIterator, ErrorInfo, TokenItem) -> ParseResult<I>,
|
||||||
{
|
{
|
||||||
let Some(start) = tokens.eat_token(open) else {
|
let Some(start) = tokens.eat_token(open) else {
|
||||||
return Err(ErrorInfo {
|
return Err(ErrorInfo {
|
||||||
|
@ -3993,15 +4143,17 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_inner2<F>(
|
fn parse_inner2<F, I>(
|
||||||
&mut self,
|
&mut self,
|
||||||
tokens: &mut TokenIterator,
|
tokens: &mut TokenIterator,
|
||||||
open: Token,
|
open: Token,
|
||||||
close: Token,
|
close: Token,
|
||||||
parse: F,
|
parse: F,
|
||||||
) -> ParseResult<Index>
|
) -> ParseResult<I>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
|
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<I>,
|
||||||
|
Index: Into<I>,
|
||||||
|
// I: From<Index>,
|
||||||
{
|
{
|
||||||
self.parse_inner(tokens, open, close, parse, |this, tokens, err, start| {
|
self.parse_inner(tokens, open, close, parse, |this, tokens, err, start| {
|
||||||
match close {
|
match close {
|
||||||
|
@ -4031,13 +4183,14 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
Ok(this.push_error(err.error, err.loc))
|
Ok(this.push_error(err.error, err.loc).into())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_bracketed<F>(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult<Index>
|
fn parse_bracketed<F, I>(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult<I>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
|
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<I>,
|
||||||
|
Index: Into<I>,
|
||||||
{
|
{
|
||||||
self.parse_inner2(
|
self.parse_inner2(
|
||||||
tokens,
|
tokens,
|
||||||
|
@ -4047,20 +4200,22 @@ pub mod ast_gen {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_braced<F>(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult<Index>
|
fn parse_braced<F, I>(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult<I>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
|
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<I>,
|
||||||
|
Index: Into<I>,
|
||||||
{
|
{
|
||||||
self.parse_inner2(tokens, Token::OpenBrace, Token::CloseBrace, parse)
|
self.parse_inner2(tokens, Token::OpenBrace, Token::CloseBrace, parse)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_parenthesised<F>(
|
fn parse_parenthesised<F, I>(
|
||||||
&mut self,
|
&mut self,
|
||||||
tokens: &mut TokenIterator,
|
tokens: &mut TokenIterator,
|
||||||
parse: F,
|
parse: F,
|
||||||
) -> ParseResult<Index>
|
) -> ParseResult<I>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
|
F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<I>,
|
||||||
|
Index: Into<I>,
|
||||||
{
|
{
|
||||||
self.parse_inner2(tokens, Token::OpenParens, Token::CloseParens, parse)
|
self.parse_inner2(tokens, Token::OpenParens, Token::CloseParens, parse)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue