From 6d70231c9121ff733a1e1c502b5c18caa5432ea2 Mon Sep 17 00:00:00 2001 From: Janis Date: Wed, 5 Mar 2025 22:21:36 +0100 Subject: [PATCH] this should be correct? --- src/ast2/mod.rs | 54 ++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs index 43c574a..d7ef354 100644 --- a/src/ast2/mod.rs +++ b/src/ast2/mod.rs @@ -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 { + fn parse_as_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { 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 { + ) -> ParseResult { 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 { + fn parse_assignment_expr( + &mut self, + tokens: &mut TokenIterator, + ) -> ParseResult { 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)