placeness solver on ast after parsing
This commit is contained in:
parent
d6450b5f32
commit
8b3789d7b0
474
src/ast2/ir.rs
474
src/ast2/ir.rs
|
@ -17,7 +17,7 @@ enum Error {
|
||||||
use super::{
|
use super::{
|
||||||
intern::InternPoolWrapper as InternPool,
|
intern::InternPoolWrapper as InternPool,
|
||||||
visitor::{AstExt, AstVisitorTrait},
|
visitor::{AstExt, AstVisitorTrait},
|
||||||
TypeCache,
|
Ast, Data, PlaceOrValue, Tag, TypeCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IrBuilder {
|
struct IrBuilder {
|
||||||
|
@ -46,7 +46,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: super::Index,
|
idx: super::Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Block);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Block);
|
||||||
let (a, b) = data.as_extra_range();
|
let (a, b) = data.as_extra_range();
|
||||||
|
|
||||||
ast.extra[a..b]
|
ast.extra[a..b]
|
||||||
|
@ -64,7 +64,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::PlaceToValueConversion);
|
let data = ast.expect_node_data_for_tag(idx, Tag::PlaceToValueConversion);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
|
|
||||||
// idx's (this) type is the pointee type
|
// idx's (this) type is the pointee type
|
||||||
|
@ -81,7 +81,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::ValueToPlaceConversion);
|
let data = ast.expect_node_data_for_tag(idx, Tag::ValueToPlaceConversion);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
|
|
||||||
// expr's type is the pointee type
|
// expr's type is the pointee type
|
||||||
|
@ -108,7 +108,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::DeclRef);
|
let data = ast.expect_node_data_for_tag(idx, Tag::DeclRef);
|
||||||
let decl = data.as_index();
|
let decl = data.as_index();
|
||||||
|
|
||||||
let alloca = self.ref_lookup.get(&decl).cloned().expect("declref");
|
let alloca = self.ref_lookup.get(&decl).cloned().expect("declref");
|
||||||
|
@ -163,7 +163,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::ReturnExprStmt);
|
let data = ast.expect_node_data_for_tag(idx, Tag::ReturnExprStmt);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Constant);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Constant);
|
||||||
let (ty, value) = data.as_index_intern();
|
let (ty, value) = data.as_index_intern();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty);
|
||||||
|
@ -194,7 +194,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::SubscriptExpr);
|
let data = ast.expect_node_data_for_tag(idx, Tag::SubscriptExpr);
|
||||||
let (lhs, index) = data.as_two_indices();
|
let (lhs, index) = data.as_two_indices();
|
||||||
|
|
||||||
// pointer type
|
// pointer type
|
||||||
|
@ -217,7 +217,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::CallExpr);
|
let data = ast.expect_node_data_for_tag(idx, Tag::CallExpr);
|
||||||
let (func, arguments) = data.as_two_indices();
|
let (func, arguments) = data.as_two_indices();
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Argument);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Argument);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
|
|
||||||
let arg = self.visit_any(ast, expr)?.unwrap();
|
let arg = self.visit_any(ast, expr)?.unwrap();
|
||||||
|
@ -263,7 +263,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::ArgumentList);
|
let data = ast.expect_node_data_for_tag(idx, Tag::ArgumentList);
|
||||||
let (a, b) = data.as_extra_range();
|
let (a, b) = data.as_extra_range();
|
||||||
|
|
||||||
let args = ast.extra[a..b]
|
let args = ast.extra[a..b]
|
||||||
|
@ -292,7 +292,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::BlockTrailingExpr);
|
let data = ast.expect_node_data_for_tag(idx, Tag::BlockTrailingExpr);
|
||||||
|
|
||||||
let (a, b) = data.as_extra_range();
|
let (a, b) = data.as_extra_range();
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: super::Index,
|
idx: super::Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::FunctionProto);
|
let data = ast.expect_node_data_for_tag(idx, Tag::FunctionProto);
|
||||||
|
|
||||||
let (_, extra) = data.as_intern_and_extra_offset();
|
let (_, extra) = data.as_intern_and_extra_offset();
|
||||||
let (_return_type, parameter_list) = (
|
let (_return_type, parameter_list) = (
|
||||||
|
@ -330,7 +330,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::ParameterList);
|
let data = ast.expect_node_data_for_tag(idx, Tag::ParameterList);
|
||||||
let (a, b) = data.as_extra_range();
|
let (a, b) = data.as_extra_range();
|
||||||
|
|
||||||
ast.extra[a..b]
|
ast.extra[a..b]
|
||||||
|
@ -348,7 +348,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Parameter);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Parameter);
|
||||||
let (ty, _name) = data.as_index_intern();
|
let (ty, _name) = data.as_index_intern();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, ty);
|
||||||
|
@ -367,7 +367,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::AddressOf);
|
let data = ast.expect_node_data_for_tag(idx, Tag::AddressOf);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
||||||
|
@ -384,7 +384,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Assign);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Assign);
|
||||||
let (dst, src) = data.as_two_indices();
|
let (dst, src) = data.as_two_indices();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
||||||
|
@ -403,7 +403,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::ExplicitCast);
|
let data = ast.expect_node_data_for_tag(idx, Tag::ExplicitCast);
|
||||||
let (lhs, ty) = data.as_two_indices();
|
let (lhs, ty) = data.as_two_indices();
|
||||||
|
|
||||||
let lty = ast.get_type_of_node(&self.ip, &mut self.type_cache, lhs);
|
let lty = ast.get_type_of_node(&self.ip, &mut self.type_cache, lhs);
|
||||||
|
@ -424,7 +424,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::IfExpr);
|
let data = ast.expect_node_data_for_tag(idx, Tag::IfExpr);
|
||||||
let (cond, body) = data.as_two_indices();
|
let (cond, body) = data.as_two_indices();
|
||||||
|
|
||||||
let cond = self.visit_any(ast, cond)?.unwrap();
|
let cond = self.visit_any(ast, cond)?.unwrap();
|
||||||
|
@ -450,7 +450,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::IfElseExpr);
|
let data = ast.expect_node_data_for_tag(idx, Tag::IfElseExpr);
|
||||||
let (cond, extra) = data.as_index_and_extra_offset();
|
let (cond, extra) = data.as_index_and_extra_offset();
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Not);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Not);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
||||||
|
@ -510,7 +510,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Not);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Not);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
||||||
|
@ -525,7 +525,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Negate);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Negate);
|
||||||
let expr = data.as_index();
|
let expr = data.as_index();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, expr);
|
||||||
|
@ -542,7 +542,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Or);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Or);
|
||||||
let (a, b) = data.as_two_indices();
|
let (a, b) = data.as_two_indices();
|
||||||
|
|
||||||
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
let ty = ast.get_type_of_node(&self.ip, &mut self.type_cache, idx);
|
||||||
|
@ -580,7 +580,7 @@ impl<'b, 'a> AstVisitorTrait<&'a mut super::Ast> for IrFunctionBuilder<'b> {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::Or);
|
let data = ast.expect_node_data_for_tag(idx, Tag::Or);
|
||||||
let (a, b) = data.as_two_indices();
|
let (a, b) = data.as_two_indices();
|
||||||
|
|
||||||
// TODO: make this an error instead of a panic
|
// TODO: make this an error instead of a panic
|
||||||
|
@ -734,7 +734,7 @@ impl IrFunctionBuilder<'_> {
|
||||||
let _name = range.get(0).unwrap();
|
let _name = range.get(0).unwrap();
|
||||||
|
|
||||||
let (expr, typed_index) = match tag {
|
let (expr, typed_index) = match tag {
|
||||||
super::Tag::VarDecl | super::Tag::MutVarDecl => {
|
Tag::VarDecl | Tag::MutVarDecl => {
|
||||||
let typed_index = range
|
let typed_index = range
|
||||||
.get(1)
|
.get(1)
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -743,7 +743,7 @@ impl IrFunctionBuilder<'_> {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(None, typed_index)
|
(None, typed_index)
|
||||||
}
|
}
|
||||||
super::Tag::VarDeclAssignment | super::Tag::MutVarDeclAssignment => {
|
Tag::VarDeclAssignment | Tag::MutVarDeclAssignment => {
|
||||||
let expr = range
|
let expr = range
|
||||||
.get(1)
|
.get(1)
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -799,24 +799,24 @@ impl IrFunctionBuilder<'_> {
|
||||||
let rhs = self.visit_any(ast, rhs)?.unwrap();
|
let rhs = self.visit_any(ast, rhs)?.unwrap();
|
||||||
|
|
||||||
let (inst, data) = match tag {
|
let (inst, data) = match tag {
|
||||||
super::Tag::BitOr => (Inst::BitOr(ty), Data::new(lhs, rhs)),
|
Tag::BitOr => (Inst::BitOr(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::BitXOr => (Inst::BitOr(ty), Data::new(lhs, rhs)),
|
Tag::BitXOr => (Inst::BitOr(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::BitAnd => (Inst::BitOr(ty), Data::new(lhs, rhs)),
|
Tag::BitAnd => (Inst::BitOr(ty), Data::new(lhs, rhs)),
|
||||||
|
|
||||||
super::Tag::Eq => (Inst::Eq(ty), Data::new(lhs, rhs)),
|
Tag::Eq => (Inst::Eq(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::NEq => (Inst::Neq(ty), Data::new(lhs, rhs)),
|
Tag::NEq => (Inst::Neq(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Lt => (Inst::Lt(ty), Data::new(lhs, rhs)),
|
Tag::Lt => (Inst::Lt(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Gt => (Inst::Gt(ty), Data::new(lhs, rhs)),
|
Tag::Gt => (Inst::Gt(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Le => (Inst::Le(ty), Data::new(lhs, rhs)),
|
Tag::Le => (Inst::Le(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Ge => (Inst::Ge(ty), Data::new(lhs, rhs)),
|
Tag::Ge => (Inst::Ge(ty), Data::new(lhs, rhs)),
|
||||||
|
|
||||||
super::Tag::Shl => (Inst::ShiftLeft(ty), Data::new(lhs, rhs)),
|
Tag::Shl => (Inst::ShiftLeft(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Shr => (Inst::ShiftRight(ty), Data::new(lhs, rhs)),
|
Tag::Shr => (Inst::ShiftRight(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Add => (Inst::Add(ty), Data::new(lhs, rhs)),
|
Tag::Add => (Inst::Add(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Sub => (Inst::Sub(ty), Data::new(lhs, rhs)),
|
Tag::Sub => (Inst::Sub(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Div => (Inst::Div(ty), Data::new(lhs, rhs)),
|
Tag::Div => (Inst::Div(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Rem => (Inst::Rem(ty), Data::new(lhs, rhs)),
|
Tag::Rem => (Inst::Rem(ty), Data::new(lhs, rhs)),
|
||||||
super::Tag::Mul => (Inst::Mul(ty), Data::new(lhs, rhs)),
|
Tag::Mul => (Inst::Mul(ty), Data::new(lhs, rhs)),
|
||||||
_ => panic!("not a binop"),
|
_ => panic!("not a binop"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -834,7 +834,7 @@ impl<'a> AstVisitorTrait<&'a mut super::Ast> for IrBuilder {
|
||||||
ast: &'a mut super::Ast,
|
ast: &'a mut super::Ast,
|
||||||
idx: super::Index,
|
idx: super::Index,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
let data = ast.expect_node_data_for_tag(idx, super::Tag::FunctionDecl);
|
let data = ast.expect_node_data_for_tag(idx, Tag::FunctionDecl);
|
||||||
let (proto, block) = data.as_two_indices();
|
let (proto, block) = data.as_two_indices();
|
||||||
|
|
||||||
// visit proto
|
// visit proto
|
||||||
|
@ -844,3 +844,389 @@ impl<'a> AstVisitorTrait<&'a mut super::Ast> for IrBuilder {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PlacenessSolver;
|
||||||
|
|
||||||
|
impl<'a> AstVisitorTrait<&'a mut Ast> for PlacenessSolver {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
type Value = PlaceOrValue;
|
||||||
|
|
||||||
|
const UNIMPL: Self::Error = ();
|
||||||
|
|
||||||
|
fn visit_subscript_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::SubscriptExpr);
|
||||||
|
let (lhs, index) = data.as_two_indices();
|
||||||
|
|
||||||
|
let lhs = self.visit_any(ast, lhs)?;
|
||||||
|
let index = self.visit_any(ast, index)?;
|
||||||
|
|
||||||
|
let lhs = ast.convert_to_value_expr(lhs);
|
||||||
|
let index = ast.convert_to_value_expr(index);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::two_indices(lhs, index);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Place(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_deref_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::Deref);
|
||||||
|
|
||||||
|
let expr = self.visit_any(ast, data.as_index())?;
|
||||||
|
let expr = ast.convert_to_value_expr(expr);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::index(expr);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Place(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_parameter(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_var_decl(&mut self, ast: &'a mut Ast, idx: Index) -> Result<Self::Value, Self::Error> {
|
||||||
|
Ok(PlaceOrValue::Place(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_global_decl(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
Ok(PlaceOrValue::Place(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_address_of_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_decl_ref(&mut self, ast: &'a mut Ast, idx: Index) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::DeclRef);
|
||||||
|
let decl = self.visit_any(ast, data.as_index())?;
|
||||||
|
|
||||||
|
// copy the placeness of the decl referenced.
|
||||||
|
// parameters are values, var decls are places
|
||||||
|
Ok(decl.with_index(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_function_decl(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::FunctionDecl);
|
||||||
|
let (_, body) = data.as_two_indices();
|
||||||
|
|
||||||
|
let body = self.visit_block_maybe_trailing_as_value(ast, body)?;
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_block(&mut self, ast: &'a mut Ast, idx: Index) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.visit_children(ast, idx)?;
|
||||||
|
|
||||||
|
// this block returns nothing, so it can safely be a value
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_block_trailing_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let (a, b) = ast.datas[idx].as_extra_range();
|
||||||
|
let children = unsafe { Index::from_slice_unchecked(&ast.extra[a..b]) }.to_vec();
|
||||||
|
let (expr, statements) = children.split_last().unwrap();
|
||||||
|
|
||||||
|
for statement in statements {
|
||||||
|
self.visit_any(ast, *statement)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy placeness of trailing expression
|
||||||
|
Ok(self.visit_any(ast, *expr)?.with_index(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_return_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::ReturnExprStmt);
|
||||||
|
let expr = self.visit_any(ast, data.as_index())?;
|
||||||
|
let expr = ast.convert_to_value_expr(expr);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::index(expr);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_assign(&mut self, ast: &'a mut Ast, idx: Index) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::Assign);
|
||||||
|
let (dst, src) = data.as_two_indices();
|
||||||
|
|
||||||
|
let dst = self.visit_any(ast, dst)?;
|
||||||
|
let src = self.visit_any(ast, src)?;
|
||||||
|
|
||||||
|
let dst = ast.convert_to_place_expr(dst);
|
||||||
|
let src = ast.convert_to_value_expr(src);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::two_indices(dst, src);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_if_expr(&mut self, ast: &'a mut Ast, idx: Index) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::IfExpr);
|
||||||
|
let (cond, body) = data.as_two_indices();
|
||||||
|
|
||||||
|
let cond = self.visit_any(ast, cond)?;
|
||||||
|
let body = self.visit_any(ast, body)?;
|
||||||
|
|
||||||
|
let cond = ast.convert_to_value_expr(cond);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::two_indices(cond, body.into_index());
|
||||||
|
|
||||||
|
Ok(body.with_index(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_if_else_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::IfElseExpr);
|
||||||
|
let (cond, extra) = data.as_index_and_extra_offset();
|
||||||
|
let bodies = unsafe { Index::from_slice_unchecked(&ast.extra[extra..][..2]) };
|
||||||
|
let &[a, b] = bodies else { unreachable!() };
|
||||||
|
|
||||||
|
let a = self.visit_any(ast, a)?;
|
||||||
|
let b = self.visit_any(ast, b)?;
|
||||||
|
|
||||||
|
let bodies = if !a.eq_discriminant(&b) {
|
||||||
|
[ast.convert_to_value_expr(a), ast.convert_to_value_expr(b)]
|
||||||
|
} else {
|
||||||
|
[a.into_index(), b.into_index()]
|
||||||
|
}
|
||||||
|
.map(|a| a.as_u32());
|
||||||
|
|
||||||
|
ast.extra[extra..][..2].copy_from_slice(&bodies);
|
||||||
|
|
||||||
|
Ok(a.with_index(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_call_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::CallExpr);
|
||||||
|
let (func, arguments) = data.as_two_indices();
|
||||||
|
let func = self.visit_any(ast, func)?;
|
||||||
|
let func = ast.convert_to_value_expr(func);
|
||||||
|
let arguments = self.visit_argument_list(ast, arguments)?;
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::two_indices(func, arguments);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_argument_list(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::ArgumentList);
|
||||||
|
let (a, b) = data.as_extra_range();
|
||||||
|
|
||||||
|
let children = unsafe { Index::from_slice_unchecked(&ast.extra[a..b]) }.to_vec();
|
||||||
|
|
||||||
|
for child in children {
|
||||||
|
self.visit_any_argument(ast, child)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_argument(&mut self, ast: &'a mut Ast, idx: Index) -> Result<Self::Value, Self::Error> {
|
||||||
|
self.value_index(ast, idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_explicit_cast_expr(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<Self::Value, Self::Error> {
|
||||||
|
let data = ast.expect_node_data_for_tag(idx, Tag::ExplicitCast);
|
||||||
|
let (lhs, ty) = data.as_two_indices();
|
||||||
|
|
||||||
|
let lhs = self.visit_any(ast, lhs)?;
|
||||||
|
let lhs = ast.convert_to_value_expr(lhs);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::two_indices(lhs, ty);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_any(&mut self, ast: &'a mut Ast, idx: Index) -> Result<Self::Value, Self::Error> {
|
||||||
|
let tag = ast.tags[idx];
|
||||||
|
match tag {
|
||||||
|
Tag::Parameter => self.visit_parameter(ast, idx)?,
|
||||||
|
Tag::VarDecl | Tag::MutVarDecl | Tag::VarDeclAssignment | Tag::MutVarDeclAssignment => {
|
||||||
|
self.visit_var_decl_common(ast, idx)?
|
||||||
|
}
|
||||||
|
Tag::GlobalDecl => self.visit_global_decl(ast, idx)?,
|
||||||
|
Tag::DeclRef => self.visit_decl_ref(ast, idx)?,
|
||||||
|
Tag::Deref => self.visit_deref_expr(ast, idx)?,
|
||||||
|
Tag::AddressOf => self.visit_address_of_expr(ast, idx)?,
|
||||||
|
Tag::SubscriptExpr => self.visit_subscript_expr(ast, idx)?,
|
||||||
|
Tag::FunctionDecl => self.visit_function_decl(ast, idx)?,
|
||||||
|
Tag::Block => self.visit_block(ast, idx)?,
|
||||||
|
Tag::BlockTrailingExpr => self.visit_block_trailing_expr(ast, idx)?,
|
||||||
|
Tag::ExprStmt | Tag::Constant | Tag::ReturnStmt => PlaceOrValue::Value(idx),
|
||||||
|
Tag::ReturnExprStmt => self.visit_return_expr(ast, idx)?,
|
||||||
|
Tag::ArgumentList => self.visit_argument_list(ast, idx)?,
|
||||||
|
Tag::ExplicitCast => self.visit_explicit_cast_expr(ast, idx)?,
|
||||||
|
Tag::CallExpr => self.visit_call_expr(ast, idx)?,
|
||||||
|
Tag::Argument | Tag::Not | Tag::Negate => self.value_index(ast, idx)?,
|
||||||
|
Tag::Or
|
||||||
|
| Tag::And
|
||||||
|
| Tag::BitOr
|
||||||
|
| Tag::BitXOr
|
||||||
|
| Tag::BitAnd
|
||||||
|
| Tag::Eq
|
||||||
|
| Tag::NEq
|
||||||
|
| Tag::Lt
|
||||||
|
| Tag::Gt
|
||||||
|
| Tag::Le
|
||||||
|
| Tag::Ge
|
||||||
|
| Tag::Shl
|
||||||
|
| Tag::Shr
|
||||||
|
| Tag::Add
|
||||||
|
| Tag::Sub
|
||||||
|
| Tag::Mul
|
||||||
|
| Tag::Div
|
||||||
|
| Tag::Rem => self.value_two_indices(ast, idx)?,
|
||||||
|
Tag::Assign => self.visit_assign(ast, idx)?,
|
||||||
|
Tag::IfExpr => self.visit_if_expr(ast, idx)?,
|
||||||
|
Tag::IfElseExpr => self.visit_if_else_expr(ast, idx)?,
|
||||||
|
Tag::File | Tag::Root => self.visit_children(ast, idx)?,
|
||||||
|
|
||||||
|
Tag::FieldAccess => todo!(),
|
||||||
|
Tag::PlaceToValueConversion => todo!(),
|
||||||
|
Tag::ValueToPlaceConversion => todo!(),
|
||||||
|
Tag::NamedArgument => todo!(),
|
||||||
|
Tag::StructDecl => todo!(),
|
||||||
|
Tag::FieldDecl => todo!(),
|
||||||
|
Tag::TypeDeclRef => todo!(),
|
||||||
|
|
||||||
|
Tag::DeclRefUnresolved => todo!(),
|
||||||
|
Tag::InternedType => todo!(),
|
||||||
|
Tag::TypeDeclRefUnresolved => todo!(),
|
||||||
|
Tag::PointerType => todo!(),
|
||||||
|
Tag::ArrayType => todo!(),
|
||||||
|
Tag::Error => todo!(),
|
||||||
|
Tag::Undefined => todo!(),
|
||||||
|
};
|
||||||
|
//_ => Err(())?,
|
||||||
|
|
||||||
|
Ok(todo!())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlacenessSolver {
|
||||||
|
fn value_two_indices<'a>(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut super::Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<PlaceOrValue, ()> {
|
||||||
|
let (a, b) = ast.datas[idx].as_two_indices();
|
||||||
|
|
||||||
|
let a = self.visit_any(ast, a)?;
|
||||||
|
let b = self.visit_any(ast, b)?;
|
||||||
|
|
||||||
|
let a = ast.convert_to_value_expr(a);
|
||||||
|
let b = ast.convert_to_value_expr(b);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::two_indices(a, b);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value_index<'a>(&mut self, ast: &'a mut super::Ast, idx: Index) -> Result<PlaceOrValue, ()> {
|
||||||
|
let a = ast.datas[idx].as_index();
|
||||||
|
|
||||||
|
let a = self.visit_any(ast, a)?;
|
||||||
|
|
||||||
|
let a = ast.convert_to_value_expr(a);
|
||||||
|
|
||||||
|
ast.datas[idx] = Data::index(a);
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// this ensures the trailing expression of a block is a value-expression
|
||||||
|
fn visit_block_maybe_trailing_as_value<'a>(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut super::Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<PlaceOrValue, ()> {
|
||||||
|
// self.visit_children(ast, idx)?;
|
||||||
|
match ast.tags[idx] {
|
||||||
|
Tag::BlockTrailingExpr => {
|
||||||
|
let (a, b) = ast.datas[idx].as_extra_range();
|
||||||
|
let children = unsafe { Index::from_slice_unchecked(&ast.extra[a..b]).to_vec() };
|
||||||
|
let (expr, statements) = children.split_last().unwrap();
|
||||||
|
|
||||||
|
for statement in statements {
|
||||||
|
self.visit_any(ast, *statement)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let expr = self.visit_any(ast, *expr)?;
|
||||||
|
ast.extra[b - 1] = ast.convert_to_value_expr(expr).into_u32();
|
||||||
|
}
|
||||||
|
Tag::Block => {
|
||||||
|
self.visit_block(ast, idx)?;
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_var_decl_common<'a>(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut super::Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<PlaceOrValue, ()> {
|
||||||
|
self.visit_children(ast, idx)?;
|
||||||
|
Ok(PlaceOrValue::Place(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_children<'a>(
|
||||||
|
&mut self,
|
||||||
|
ast: &'a mut super::Ast,
|
||||||
|
idx: Index,
|
||||||
|
) -> Result<PlaceOrValue, ()> {
|
||||||
|
for child in ast.get_node_children(idx) {
|
||||||
|
self.visit_any(ast, child)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(PlaceOrValue::Value(idx))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -522,6 +522,24 @@ impl PlaceOrValue {
|
||||||
PlaceOrValue::Place(_) => Self::Place(index),
|
PlaceOrValue::Place(_) => Self::Place(index),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn map_value<F>(self, f: F) -> Self
|
||||||
|
where
|
||||||
|
F: FnOnce(Index) -> Self,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
PlaceOrValue::Value(index) => f(index),
|
||||||
|
_ => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn map_place<F>(self, f: F) -> Self
|
||||||
|
where
|
||||||
|
F: FnOnce(Index) -> Self,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
PlaceOrValue::Place(index) => f(index),
|
||||||
|
_ => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<index::Index> for PlaceOrValue {
|
impl From<index::Index> for PlaceOrValue {
|
||||||
|
@ -592,6 +610,14 @@ mod index {
|
||||||
|
|
||||||
inner.map(Self)
|
inner.map(Self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_slice(slice: &[u32]) -> &[Option<Self>] {
|
||||||
|
unsafe { core::mem::transmute(slice) }
|
||||||
|
}
|
||||||
|
pub unsafe fn from_slice_unchecked(slice: &[u32]) -> &[Self] {
|
||||||
|
unsafe { core::mem::transmute(slice) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn kind(&self) -> Kind {
|
pub fn kind(&self) -> Kind {
|
||||||
Kind::try_from(((self.0.get() >> 28) & 0b1111) as u8).unwrap()
|
Kind::try_from(((self.0.get() >> 28) & 0b1111) as u8).unwrap()
|
||||||
}
|
}
|
||||||
|
@ -1025,21 +1051,37 @@ 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, index: Index) -> Index {
|
fn push_place_to_value_conversion(&mut self, index: Index) -> PlaceOrValue {
|
||||||
let loc = self.get_loc(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(i, Tag::PlaceToValueConversion, Data::index(index), loc);
|
self.set_tag_data_source_loc(i, Tag::PlaceToValueConversion, Data::index(index), loc);
|
||||||
|
|
||||||
i
|
PlaceOrValue::Value(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, index: Index) -> Index {
|
fn push_value_to_place_conversion(&mut self, index: Index) -> PlaceOrValue {
|
||||||
let loc = self.get_loc(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(i, Tag::ValueToPlaceConversion, Data::index(index), loc);
|
self.set_tag_data_source_loc(i, Tag::ValueToPlaceConversion, Data::index(index), loc);
|
||||||
|
|
||||||
i
|
PlaceOrValue::Place(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// converts the expression to a value expression, if it isn't one already.
|
||||||
|
fn convert_to_value_expr(&mut self, lrvalue: PlaceOrValue) -> Index {
|
||||||
|
match lrvalue {
|
||||||
|
PlaceOrValue::Value(index) => index,
|
||||||
|
PlaceOrValue::Place(index) => self.push_place_to_value_conversion(index).into_index(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// converts the expression to a place expression, if it isn't one already.
|
||||||
|
fn convert_to_place_expr(&mut self, lrvalue: PlaceOrValue) -> Index {
|
||||||
|
match lrvalue {
|
||||||
|
PlaceOrValue::Place(index) => index,
|
||||||
|
PlaceOrValue::Value(index) => self.push_value_to_place_conversion(index).into_index(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_binary(&mut self, tag: Tag, lhs: Index, rhs: Index, loc: SourceLocation) -> Index {
|
fn push_binary(&mut self, tag: Tag, lhs: Index, rhs: Index, loc: SourceLocation) -> Index {
|
||||||
|
|
|
@ -1167,18 +1167,12 @@ impl Parser {
|
||||||
|
|
||||||
/// 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 {
|
||||||
match lrvalue {
|
self.ast.convert_to_value_expr(lrvalue)
|
||||||
PlaceOrValue::Value(index) => index,
|
|
||||||
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 {
|
||||||
match lrvalue {
|
self.ast.convert_to_place_expr(lrvalue)
|
||||||
PlaceOrValue::Place(index) => index,
|
|
||||||
PlaceOrValue::Value(index) => self.ast.push_value_to_place_conversion(index),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PREFIX_EXPR <-
|
/// PREFIX_EXPR <-
|
||||||
|
|
|
@ -287,8 +287,8 @@ pub trait AstVisitorTrait<Ast: AstExt> {
|
||||||
idx: Index,
|
idx: Index,
|
||||||
) -> Result<Self::Value, Self::Error> {
|
) -> Result<Self::Value, Self::Error> {
|
||||||
match ast.get_node_tag_and_data(idx).0 {
|
match ast.get_node_tag_and_data(idx).0 {
|
||||||
Tag::BlockTrailingExpr => self.visit_block(ast, idx),
|
Tag::BlockTrailingExpr => self.visit_block_trailing_expr(ast, idx),
|
||||||
Tag::Block => self.visit_block_trailing_expr(ast, idx),
|
Tag::Block => self.visit_block(ast, idx),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue