this should be correct?

This commit is contained in:
Janis 2025-03-05 22:21:36 +01:00
parent 51aa119af2
commit 6d70231c91

View file

@ -1021,20 +1021,17 @@ impl Ast {
}
/// converts from a place expression to a value expression.
fn push_place_to_value_conversion(&mut self, rvalue: Index, loc: SourceLocation) -> Index {
fn push_place_to_value_conversion(&mut self, index: Index) -> Index {
let loc = self.get_loc(index);
let i = self.reserve_node_other();
self.set_tag_data_source_loc(
rvalue,
Tag::PlaceToValueConversion,
Data::index(rvalue),
loc,
);
self.set_tag_data_source_loc(index, Tag::PlaceToValueConversion, Data::index(index), loc);
i
}
/// converts from a value expression to a place expression.
fn push_value_to_place_conversion(&mut self, rvalue: Index, loc: SourceLocation) -> Index {
fn push_value_to_place_conversion(&mut self, rvalue: Index) -> Index {
let loc = self.get_loc(index);
let i = self.reserve_node_other();
self.set_tag_data_source_loc(
rvalue,
@ -3645,19 +3642,17 @@ pub mod ast_gen {
/// 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),
PlaceOrValue::Place(index) => self.ast.push_place_to_value_conversion(index),
}
}
/// 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),
PlaceOrValue::Value(index) => self.ast.push_value_to_place_conversion(index),
}
}
@ -3713,15 +3708,15 @@ pub mod ast_gen {
/// AS_EXPR <-
/// PREFIX_EXPR
/// 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<PlaceOrValue> {
let loc = tokens.current_source_location();
let maybe_rvalue = self.parse_prefix_expr(tokens)?;
let expr = self.convert_to_value_expr(maybe_rvalue);
let expr = self.parse_prefix_expr(tokens)?;
if tokens.eat_token(Token::As).is_some() {
let typename = self.parse_type(tokens)?;
let expr = self.convert_to_value_expr(expr);
return Ok(self.ast.push_cast(expr, typename, loc));
return Ok(PlaceOrValue::Value(self.ast.push_cast(expr, typename, loc)));
} else {
return Ok(expr);
}
@ -3751,7 +3746,7 @@ pub mod ast_gen {
&mut self,
tokens: &mut TokenIterator,
precedence: u32,
) -> ParseResult<Index> {
) -> ParseResult<PlaceOrValue> {
let mut node = self.parse_as_expr(tokens)?;
loop {
@ -3770,8 +3765,9 @@ pub mod ast_gen {
// SAFETY: we peeked `tok`
let tok = tokens.next().unwrap();
let lhs = node;
let lhs = self.convert_to_value_expr(node);
let rhs = self.parse_binary_expr(tokens, prec + 1)?;
let rhs = self.convert_to_value_expr(rhs);
let tag = match tok.token() {
Token::PipePipe => Tag::Or,
@ -3795,7 +3791,7 @@ pub mod ast_gen {
_ => unreachable!(),
};
node = self.ast.push_binary(tag, lhs, rhs, loc);
node = PlaceOrValue::Value(self.ast.push_binary(tag, lhs, rhs, loc));
}
Ok(node)
@ -3806,7 +3802,10 @@ pub mod ast_gen {
/// BINARY_EXPRESSION ASSIGNMENT_OP EXPRESSION
/// ASSIGNMENT_OP <-
/// = += -= *= /= %= ...
fn parse_assignment_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
fn parse_assignment_expr(
&mut self,
tokens: &mut TokenIterator,
) -> ParseResult<PlaceOrValue> {
let lhs = self.parse_binary_expr(tokens, 0)?;
if tokens
@ -3817,7 +3816,8 @@ pub mod ast_gen {
// SAFETY: we peeked
let op = tokens.next().unwrap();
let loc = op.source_location();
let rhs = self.parse_place_expr(tokens)?;
// rhs (src) must be a value
let rhs = self.parse_value_expr(tokens)?;
let rhs = if op.token() == Token::Equal {
rhs
@ -3837,11 +3837,19 @@ pub mod ast_gen {
unreachable!()
}
};
// convert lhs (dest) to value
let lhs = self.convert_to_value_expr(lhs);
self.ast.push_binary(tag, lhs, rhs, loc)
};
Ok(self.ast.push_assign(lhs, rhs, loc))
// for the assignment, lhs (dest) must be a place
// I think this is the only case where the AST is a dag.
let lhs = self.convert_to_place_expr(lhs);
// the assignment is a value
Ok(PlaceOrValue::Value(self.ast.push_assign(lhs, rhs, loc)))
} else {
// but if we don't have an assignment, this might be a place
Ok(lhs)
}
}
@ -3916,7 +3924,7 @@ pub mod ast_gen {
let expr = match next.token() {
Token::If => self.parse_if_expr(tokens)?,
_ => PlaceOrValue::Value(self.parse_assignment_expr(tokens)?),
_ => self.parse_assignment_expr(tokens)?,
};
Ok(expr)