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. /// 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(); let i = self.reserve_node_other();
self.set_tag_data_source_loc( self.set_tag_data_source_loc(index, Tag::PlaceToValueConversion, Data::index(index), loc);
rvalue,
Tag::PlaceToValueConversion,
Data::index(rvalue),
loc,
);
i i
} }
/// converts from a value expression to a place expression. /// 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(); let i = self.reserve_node_other();
self.set_tag_data_source_loc( self.set_tag_data_source_loc(
rvalue, rvalue,
@ -3645,19 +3642,17 @@ pub mod ast_gen {
/// converts the expression to a value expression, if it isn't one already. /// converts the expression to a value expression, if it isn't one already.
fn convert_to_value_expr(&mut self, lrvalue: PlaceOrValue) -> Index { fn convert_to_value_expr(&mut self, lrvalue: PlaceOrValue) -> Index {
let loc = self.ast.get_loc(lrvalue.into_index());
match lrvalue { match lrvalue {
PlaceOrValue::Value(index) => index, 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. /// converts the expression to a place expression, if it isn't one already.
fn convert_to_place_expr(&mut self, lrvalue: PlaceOrValue) -> Index { fn convert_to_place_expr(&mut self, lrvalue: PlaceOrValue) -> Index {
let loc = self.ast.get_loc(lrvalue.into_index());
match lrvalue { match lrvalue {
PlaceOrValue::Place(index) => index, 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 <- /// AS_EXPR <-
/// PREFIX_EXPR /// PREFIX_EXPR
/// 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<PlaceOrValue> {
let loc = tokens.current_source_location(); let loc = tokens.current_source_location();
let maybe_rvalue = self.parse_prefix_expr(tokens)?; let expr = 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)?;
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 { } else {
return Ok(expr); return Ok(expr);
} }
@ -3751,7 +3746,7 @@ pub mod ast_gen {
&mut self, &mut self,
tokens: &mut TokenIterator, tokens: &mut TokenIterator,
precedence: u32, precedence: u32,
) -> ParseResult<Index> { ) -> ParseResult<PlaceOrValue> {
let mut node = self.parse_as_expr(tokens)?; let mut node = self.parse_as_expr(tokens)?;
loop { loop {
@ -3770,8 +3765,9 @@ pub mod ast_gen {
// SAFETY: we peeked `tok` // SAFETY: we peeked `tok`
let tok = tokens.next().unwrap(); 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.parse_binary_expr(tokens, prec + 1)?;
let rhs = self.convert_to_value_expr(rhs);
let tag = match tok.token() { let tag = match tok.token() {
Token::PipePipe => Tag::Or, Token::PipePipe => Tag::Or,
@ -3795,7 +3791,7 @@ pub mod ast_gen {
_ => unreachable!(), _ => unreachable!(),
}; };
node = self.ast.push_binary(tag, lhs, rhs, loc); node = PlaceOrValue::Value(self.ast.push_binary(tag, lhs, rhs, loc));
} }
Ok(node) Ok(node)
@ -3806,7 +3802,10 @@ pub mod ast_gen {
/// BINARY_EXPRESSION ASSIGNMENT_OP EXPRESSION /// BINARY_EXPRESSION ASSIGNMENT_OP EXPRESSION
/// ASSIGNMENT_OP <- /// 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)?; let lhs = self.parse_binary_expr(tokens, 0)?;
if tokens if tokens
@ -3817,7 +3816,8 @@ 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_place_expr(tokens)?; // rhs (src) must be a value
let rhs = self.parse_value_expr(tokens)?;
let rhs = if op.token() == Token::Equal { let rhs = if op.token() == Token::Equal {
rhs rhs
@ -3837,11 +3837,19 @@ pub mod ast_gen {
unreachable!() unreachable!()
} }
}; };
// convert lhs (dest) to value
let lhs = self.convert_to_value_expr(lhs);
self.ast.push_binary(tag, lhs, rhs, loc) 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 { } else {
// but if we don't have an assignment, this might be a place
Ok(lhs) Ok(lhs)
} }
} }
@ -3916,7 +3924,7 @@ pub mod ast_gen {
let expr = match next.token() { let expr = match next.token() {
Token::If => self.parse_if_expr(tokens)?, Token::If => self.parse_if_expr(tokens)?,
_ => PlaceOrValue::Value(self.parse_assignment_expr(tokens)?), _ => self.parse_assignment_expr(tokens)?,
}; };
Ok(expr) Ok(expr)