this should be correct?
This commit is contained in:
parent
51aa119af2
commit
6d70231c91
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue