aaaaaaaaaaaaaaaa

This commit is contained in:
Janis 2025-03-06 23:46:45 +01:00
parent 1bde8f3ccd
commit 4c7813aa98
5 changed files with 940 additions and 589 deletions

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,7 @@ pub mod intern;
pub mod ir;
pub mod parser;
pub mod tag;
pub mod typecheck;
pub mod visitor;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

View file

@ -328,8 +328,8 @@ impl AstNodeExt for Ast {
AstNode::Assign { lhs, rhs }
}
Tag::SubscriptExpr => {
let (lhs, rhs) = data.as_two_indices();
AstNode::SubscriptExpr { lhs, rhs }
let (lhs, index) = data.as_two_indices();
AstNode::SubscriptExpr { lhs, index }
}
Tag::IfExpr => {
let (cond, body) = data.as_two_indices();
@ -609,7 +609,7 @@ pub enum AstNode {
},
SubscriptExpr {
lhs: Index,
rhs: Index,
index: Index,
},
IfExpr {
cond: Index,

330
src/ast2/typecheck.rs Normal file
View file

@ -0,0 +1,330 @@
use crate::variant;
use super::{
intern::{self},
tag::{AstNode, AstNodeExt},
visitor::{AstExt, AstVisitorTrait},
Ast, Data, Index, Tag,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ErrorKind {
MismatchingTypes,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Error {
idx: Index,
kind: ErrorKind,
}
struct TypeChecker<'a> {
ip: &'a mut intern::InternPool,
errors: Vec<Error>,
}
impl<'a> TypeChecker<'a> {
fn visit_children<'b>(
&mut self,
ast: &'b mut super::Ast,
idx: Index,
) -> Result<Option<intern::Index>, ()> {
for child in ast.get_node_children(idx) {
self.visit_any(ast, child)?;
}
Ok(None)
}
}
// TODO: actually handle errors here instead of aborting.
impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> {
type Error = ();
type Value = Option<intern::Index>;
const UNIMPL: Self::Error = ();
fn visit_parameter_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
ty: Index,
name: intern::Index,
) -> Result<Self::Value, Self::Error> {
_ = (idx, name);
self.visit_any(ast, ty)
}
fn visit_array_type_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
length: Index,
pointer: Index,
) -> Result<Self::Value, Self::Error> {
_ = self.visit_any(ast, length)?;
let pointee = self.visit_any(ast, pointer)?.expect("no type?");
variant!(self.ip.get_key(pointee) => intern::Key::PointerType { pointee, flags });
// get interened value from constant node
let length = {
let value = ast.datas[length].as_index_intern().1;
match self.ip.get_key(value) {
intern::Key::SIntSmall { bits } => bits as u32,
intern::Key::UIntSmall { bits } => bits as u32,
intern::Key::SInt64 { bits } => bits as u32,
intern::Key::UInt64 { bits } => bits as u32,
intern::Key::NegativeInt { bigint } | intern::Key::PositiveInt { bigint } => {
bigint.iter_u32_digits().next().unwrap_or(0)
}
_ => 0,
}
};
let ty = self.ip.get_array_type(pointee, Some(flags), length);
ast.tags[idx] = Tag::InternedType;
ast.datas[idx] = Data::intern(ty);
Ok(Some(ty))
}
fn visit_pointer_type_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
ty: Index,
flags: intern::PointerFlags,
) -> Result<Self::Value, Self::Error> {
let pointee = self.visit_any(ast, ty)?.expect("no type?");
let ty = self.ip.get_pointer_type(pointee, Some(flags));
ast.tags[idx] = Tag::InternedType;
ast.datas[idx] = Data::intern(ty);
Ok(Some(ty))
}
fn visit_type_decl_ref_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
decl: Index,
) -> Result<Self::Value, Self::Error> {
let ty = self.visit_any(ast, decl)?.expect("no type?");
ast.tags[idx] = Tag::InternedType;
ast.datas[idx] = Data::intern(ty);
Ok(Some(ty))
}
fn visit_function_proto_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
name: intern::Index,
return_type: Index,
parameter_list: Index,
) -> Result<Self::Value, Self::Error> {
variant!(ast.get_ast_node(parameter_list) => AstNode::ParameterList { params });
let return_type = self.visit_any(ast, return_type)?.expect("no type?");
let params = params
.into_iter()
.map(|param| self.visit_parameter(ast, param).map(|a| a.unwrap()))
.collect::<Result<Vec<_>, _>>()?;
let ty = self.ip.get_function_type(return_type, params);
ast.tags[idx] = Tag::FunctionProtoInterned;
ast.datas[idx] = Data::two_interns(name, ty);
Ok(Some(ty))
}
fn visit_function_proto_interned_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
name: intern::Index,
ty: intern::Index,
) -> Result<Self::Value, Self::Error> {
Ok(Some(ty))
}
fn visit_struct_decl_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
name: intern::Index,
flags: intern::StructFlags,
field_names: Vec<intern::Index>,
field_types: Vec<Index>,
) -> Result<Self::Value, Self::Error> {
let types = field_types
.into_iter()
.map(|i| self.visit_any(ast, i).map(Option::unwrap))
.collect::<Result<Vec<_>, _>>()?;
let ty = self.ip.insert_or_replace_struct_type(
name,
idx,
flags.packed,
flags.c_like,
field_names.into_iter().zip(types),
);
ast.tags[idx] = Tag::StructDeclInterned;
ast.datas[idx] = Data::two_interns(name, ty);
Ok(Some(ty))
}
fn visit_function_decl_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
proto: Index,
body: Index,
) -> Result<Self::Value, Self::Error> {
let ty = self.visit_any(ast, proto)?.expect("no type?");
let body = self.visit_block(ast, body)?.unwrap_or(intern::Index::VOID);
let ret_ty = self.ip.try_get_return_type(ty).expect("no type?");
if body != ret_ty {
self.errors.push(Error {
idx,
kind: ErrorKind::MismatchingTypes,
});
Ok(Some(intern::Index::VOID))
} else {
Ok(Some(ty))
}
}
fn visit_block_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
statements: Vec<Index>,
expr: Option<Index>,
) -> Result<Self::Value, Self::Error> {
for stmt in statements {
self.visit_any(ast, stmt)?;
}
expr.map(|expr| self.visit_any(ast, expr))
.transpose()
.map(Option::flatten)
}
fn visit_file_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
decls: Vec<Index>,
) -> Result<Self::Value, Self::Error> {
for decl in decls {
self.visit_any(ast, decl)?;
}
Ok(None)
}
fn visit_struct_decl_interned_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
name: intern::Index,
ty: intern::Index,
) -> Result<Self::Value, Self::Error> {
Ok(Some(ty))
}
fn visit_any(
&mut self,
ast: &'a mut Ast,
idx: super::Index,
) -> Result<Self::Value, Self::Error> {
let (tag, data) = ast.get_node_tag_and_data(idx);
let _ty = match tag {
Tag::Root => unreachable!(),
Tag::InternedType => Some(data.as_intern()),
Tag::File => self.visit_children(ast, idx)?,
Tag::ArrayType => self.visit_array_type(ast, idx)?,
Tag::PointerType => self.visit_pointer_type(ast, idx)?,
Tag::TypeDeclRef => self.visit_type_decl_ref(ast, idx)?,
Tag::FunctionProtoInterned => self.visit_function_proto_interned(ast, idx)?,
Tag::FunctionProto => self.visit_function_proto(ast, idx)?,
Tag::Parameter => self.visit_parameter(ast, idx)?,
Tag::StructDecl => self.visit_struct_decl(ast, idx)?,
Tag::StructDeclInterned => {
let (_, ty) = data.as_two_interns();
Some(ty)
}
Tag::FunctionDecl => self.visit_function_decl(ast, idx)?,
Tag::ParameterList => todo!(),
Tag::Block => todo!(),
Tag::BlockTrailingExpr => todo!(),
Tag::Constant => todo!(),
Tag::ExprStmt => todo!(),
Tag::ReturnStmt => todo!(),
Tag::ReturnExprStmt => todo!(),
Tag::VarDecl => todo!(),
Tag::MutVarDecl => todo!(),
Tag::VarDeclAssignment => todo!(),
Tag::MutVarDeclAssignment => todo!(),
Tag::GlobalDecl => todo!(),
Tag::FieldDecl => todo!(),
Tag::DeclRef => todo!(),
Tag::DeclRefUnresolved => todo!(),
Tag::TypeDeclRefUnresolved => todo!(),
Tag::CallExpr => todo!(),
Tag::FieldAccess => todo!(),
Tag::ArgumentList => todo!(),
Tag::Argument => todo!(),
Tag::NamedArgument => todo!(),
Tag::ExplicitCast => todo!(),
Tag::Deref => todo!(),
Tag::AddressOf => todo!(),
Tag::Not => todo!(),
Tag::Negate => todo!(),
Tag::PlaceToValueConversion => todo!(),
Tag::ValueToPlaceConversion => todo!(),
Tag::Or => todo!(),
Tag::And => todo!(),
Tag::BitOr => todo!(),
Tag::BitXOr => todo!(),
Tag::BitAnd => todo!(),
Tag::Eq => todo!(),
Tag::NEq => todo!(),
Tag::Lt => todo!(),
Tag::Gt => todo!(),
Tag::Le => todo!(),
Tag::Ge => todo!(),
Tag::Shl => todo!(),
Tag::Shr => todo!(),
Tag::Add => todo!(),
Tag::Sub => todo!(),
Tag::Mul => todo!(),
Tag::Div => todo!(),
Tag::Rem => todo!(),
Tag::Assign => todo!(),
Tag::SubscriptExpr => todo!(),
Tag::IfExpr => todo!(),
Tag::IfElseExpr => todo!(),
Tag::Error => todo!(),
Tag::Undefined => todo!(),
};
todo!()
}
}

View file

@ -279,314 +279,347 @@ pub trait AstVisitorTrait<Ast: AstExt + AstNodeExt> {
type Value;
const UNIMPL: Self::Error;
fn visit_function_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_parameter(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_parameter_list(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_block(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_block_trailing_expr(
&mut self,
ast: Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_block_maybe_trailing(
&mut self,
ast: Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
match ast.get_node_tag_and_data(idx).0 {
Tag::BlockTrailingExpr => self.visit_block_trailing_expr(ast, idx),
Tag::Block => self.visit_block(ast, idx),
_ => unreachable!(),
}
}
fn visit_function_proto(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_call_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_add_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_sub_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_mul_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_div_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_rem_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_eq_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_neq_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_lt_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_gt_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_le_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_ge_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_shl_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_shr_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_bitor_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_bitxor_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_bitand_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_or_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_and_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_not_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_negate_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_deref_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_address_of_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_explicit_cast_expr(
&mut self,
ast: Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_assign(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_subscript_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_if_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_if_else_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_argument(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_any_argument(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
match ast.get_node_tag_and_data(idx).0 {
Tag::Argument => self.visit_argument(ast, idx),
Tag::NamedArgument => self.visit_named_argument(ast, idx),
_ => unreachable!(),
}
}
fn visit_named_argument(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_argument_list(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_constant(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_return(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_return_expr(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_global_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_var_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_mut_var_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_var_assign_decl(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_mut_var_assign_decl(
&mut self,
ast: Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_decl_ref(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
_ = (ast, idx);
Err(Self::UNIMPL)
}
fn visit_value_to_place_conversion(
&mut self,
ast: Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
let idx = ast
.get_node_data_for_tag(idx, Tag::ValueToPlaceConversion)
.unwrap()
.as_index();
self.visit_any(ast, idx)
}
fn visit_place_to_value_conversion(
&mut self,
ast: Ast,
idx: Index,
) -> Result<Self::Value, Self::Error> {
let idx = ast
.get_node_data_for_tag(idx, Tag::PlaceToValueConversion)
.unwrap()
.as_index();
self.visit_any(ast, idx)
}
tag_visit_fn!(
File {
decls: Vec<Index>,
},
FunctionProto {
name: Interned,
return_type: Index,
parameter_list: Index,
},
FunctionProtoInterned {
name: Interned,
ty: Interned,
},
FunctionDecl {
proto: Index,
body: Index,
},
ParameterList {
params: Vec<Index>,
},
Parameter {
ty: Index,
name: Interned,
},
Block {
statements: Vec<Index>,
expr: Option<Index>,
},
Constant {
ty: Index,
value: Interned,
},
ExprStmt {
expr: Index,
},
ReturnStmt {},
ReturnExprStmt {
expr: Index,
},
VarDecl {
name: Interned,
ty: Index,
},
MutVarDecl {
name: Interned,
ty: Index,
},
VarDeclAssignment {
name: Interned,
expr: Index,
ty: Option<Index>,
},
MutVarDeclAssignment {
name: Interned,
expr: Index,
ty: Option<Index>,
},
GlobalDecl {
name: Interned,
expr: Index,
ty: Index,
},
StructDecl {
name: Interned,
flags: StructFlags,
field_names: Vec<Interned>,
field_types: Vec<Index>,
},
StructDeclInterned {
name: Interned,
ty: Interned,
},
FieldDecl {
name: Interned,
ty: Index,
},
DeclRef {
decl: Index,
},
DeclRefUnresolved {
scope: Index,
name: Interned,
},
InternedType {
intern: Interned,
},
TypeDeclRef {
decl: Index,
},
TypeDeclRefUnresolved {
scope: Index,
name: Interned,
},
PointerType {
ty: Index,
flags: PointerFlags,
},
ArrayType {
length: Index,
pointer: Index,
},
CallExpr {
func: Index,
argument_list: Index,
},
FieldAccess {
field_name: Interned,
expr: Index,
},
ArgumentList {
arguments: Vec<Index>,
},
Argument {
expr: Index,
name: Option<Interned>,
},
ExplicitCast {
expr: Index,
ty: Index,
},
Deref {
expr: Index,
},
AddressOf {
expr: Index,
},
Not {
expr: Index,
},
Negate {
expr: Index,
},
PlaceToValueConversion {
expr: Index,
},
ValueToPlaceConversion {
expr: Index,
},
Or {
lhs: Index,
rhs: Index,
},
And {
lhs: Index,
rhs: Index,
},
BitOr {
lhs: Index,
rhs: Index,
},
BitXOr {
lhs: Index,
rhs: Index,
},
BitAnd {
lhs: Index,
rhs: Index,
},
Eq {
lhs: Index,
rhs: Index,
},
NEq {
lhs: Index,
rhs: Index,
},
Lt {
lhs: Index,
rhs: Index,
},
Gt {
lhs: Index,
rhs: Index,
},
Le {
lhs: Index,
rhs: Index,
},
Ge {
lhs: Index,
rhs: Index,
},
Shl {
lhs: Index,
rhs: Index,
},
Shr {
lhs: Index,
rhs: Index,
},
Add {
lhs: Index,
rhs: Index,
},
Sub {
lhs: Index,
rhs: Index,
},
Mul {
lhs: Index,
rhs: Index,
},
Div {
lhs: Index,
rhs: Index,
},
Rem {
lhs: Index,
rhs: Index,
},
Assign {
lhs: Index,
rhs: Index,
},
SubscriptExpr {
lhs: Index,
index: Index,
},
IfExpr {
cond: Index,
body: Index,
},
IfElseExpr {
cond: Index,
a: Index,
b: Index,
},
Error {
err: ParseError,
},
Undefined {},
);
fn visit_any(&mut self, ast: Ast, idx: Index) -> Result<Self::Value, Self::Error> {
match ast.get_node_tag_and_data(idx).0 {
Tag::FunctionProto => self.visit_function_proto(ast, idx),
Tag::FunctionDecl => self.visit_function_decl(ast, idx),
Tag::ParameterList => self.visit_parameter_list(ast, idx),
Tag::Parameter => self.visit_parameter(ast, idx),
Tag::Block => self.visit_block(ast, idx),
Tag::BlockTrailingExpr => self.visit_block_trailing_expr(ast, idx),
Tag::Constant => self.visit_constant(ast, idx),
Tag::ExprStmt => todo!(),
Tag::ReturnStmt => self.visit_return(ast, idx),
Tag::ReturnExprStmt => self.visit_return_expr(ast, idx),
Tag::VarDecl => self.visit_var_decl(ast, idx),
Tag::MutVarDecl => self.visit_mut_var_decl(ast, idx),
Tag::VarDeclAssignment => self.visit_var_assign_decl(ast, idx),
Tag::MutVarDeclAssignment => self.visit_mut_var_assign_decl(ast, idx),
Tag::GlobalDecl => self.visit_global_decl(ast, idx),
Tag::StructDecl => todo!(),
Tag::StructDeclInterned => todo!(),
Tag::FunctionProtoInterned => todo!(),
Tag::FieldDecl => todo!(),
Tag::DeclRef => self.visit_decl_ref(ast, idx),
Tag::DeclRefUnresolved => todo!(),
Tag::InternedType => todo!(),
Tag::TypeDeclRef => todo!(),
Tag::TypeDeclRefUnresolved => todo!(),
Tag::PointerType => todo!(),
Tag::ArrayType => todo!(),
Tag::CallExpr => self.visit_call_expr(ast, idx),
Tag::FieldAccess => todo!(),
Tag::ArgumentList => self.visit_argument_list(ast, idx),
Tag::Argument => self.visit_argument(ast, idx),
Tag::NamedArgument => self.visit_named_argument(ast, idx),
Tag::ExplicitCast => self.visit_explicit_cast_expr(ast, idx),
Tag::Deref => self.visit_deref_expr(ast, idx),
Tag::AddressOf => self.visit_add_expr(ast, idx),
Tag::Not => self.visit_not_expr(ast, idx),
Tag::Negate => self.visit_negate_expr(ast, idx),
Tag::Or => self.visit_or_expr(ast, idx),
Tag::And => self.visit_and_expr(ast, idx),
Tag::BitOr => self.visit_bitor_expr(ast, idx),
Tag::BitXOr => self.visit_bitxor_expr(ast, idx),
Tag::BitAnd => self.visit_bitand_expr(ast, idx),
Tag::Eq => self.visit_eq_expr(ast, idx),
Tag::NEq => self.visit_neq_expr(ast, idx),
Tag::Lt => self.visit_lt_expr(ast, idx),
Tag::Gt => self.visit_gt_expr(ast, idx),
Tag::Le => self.visit_le_expr(ast, idx),
Tag::Ge => self.visit_ge_expr(ast, idx),
Tag::Shl => self.visit_shl_expr(ast, idx),
Tag::Shr => self.visit_shr_expr(ast, idx),
Tag::Add => self.visit_add_expr(ast, idx),
Tag::Sub => self.visit_sub_expr(ast, idx),
Tag::Mul => self.visit_mul_expr(ast, idx),
Tag::Div => self.visit_div_expr(ast, idx),
Tag::Rem => self.visit_rem_expr(ast, idx),
Tag::Assign => self.visit_assign(ast, idx),
Tag::SubscriptExpr => self.visit_subscript_expr(ast, idx),
Tag::IfExpr => self.visit_if_expr(ast, idx),
Tag::IfElseExpr => self.visit_if_else_expr(ast, idx),
Tag::PlaceToValueConversion => self.visit_place_to_value_conversion(ast, idx),
Tag::ValueToPlaceConversion => self.visit_value_to_place_conversion(ast, idx),
Tag::Error => todo!(),
Tag::Undefined => todo!(),
Tag::Root => todo!(),
Tag::File => todo!(),
match ast.get_ast_node(idx) {
AstNode::File { decls } => self.visit_file_impl(ast, idx, decls),
AstNode::FunctionProto {
name,
return_type,
parameter_list,
} => self.visit_function_proto_impl(ast, idx, name, return_type, parameter_list),
AstNode::FunctionProtoInterned { name, ty } => {
self.visit_function_proto_interned_impl(ast, idx, name, ty)
}
AstNode::FunctionDecl { proto, body } => {
self.visit_function_decl_impl(ast, idx, proto, body)
}
AstNode::ParameterList { params } => self.visit_parameter_list_impl(ast, idx, params),
AstNode::Parameter { ty, name } => self.visit_parameter_impl(ast, idx, ty, name),
AstNode::Block { statements, expr } => {
self.visit_block_impl(ast, idx, statements, expr)
}
AstNode::Constant { ty, value } => self.visit_constant_impl(ast, idx, ty, value),
AstNode::ExprStmt { expr } => self.visit_expr_stmt_impl(ast, idx, expr),
AstNode::ReturnStmt => self.visit_return_stmt_impl(ast, idx),
AstNode::ReturnExprStmt { expr } => self.visit_return_expr_stmt_impl(ast, idx, expr),
AstNode::VarDecl { name, ty } => self.visit_var_decl_impl(ast, idx, name, ty),
AstNode::MutVarDecl { name, ty } => self.visit_mut_var_decl_impl(ast, idx, name, ty),
AstNode::VarDeclAssignment { name, expr, ty } => {
self.visit_var_decl_assignment_impl(ast, idx, name, expr, ty)
}
AstNode::MutVarDeclAssignment { name, expr, ty } => {
self.visit_mut_var_decl_assignment_impl(ast, idx, name, expr, ty)
}
AstNode::GlobalDecl { name, expr, ty } => {
self.visit_global_decl_impl(ast, idx, name, expr, ty)
}
AstNode::StructDecl {
name,
flags,
field_names,
field_types,
} => self.visit_struct_decl_impl(ast, idx, name, flags, field_names, field_types),
AstNode::StructDeclInterned { name, ty } => {
self.visit_struct_decl_interned_impl(ast, idx, name, ty)
}
AstNode::FieldDecl { name, ty } => self.visit_field_decl_impl(ast, idx, name, ty),
AstNode::DeclRef { decl } => self.visit_decl_ref_impl(ast, idx, decl),
AstNode::DeclRefUnresolved { scope, name } => {
self.visit_decl_ref_unresolved_impl(ast, idx, scope, name)
}
AstNode::InternedType { intern } => self.visit_interned_type_impl(ast, idx, intern),
AstNode::TypeDeclRef { decl } => self.visit_type_decl_ref_impl(ast, idx, decl),
AstNode::TypeDeclRefUnresolved { scope, name } => {
self.visit_type_decl_ref_unresolved_impl(ast, idx, scope, name)
}
AstNode::PointerType { ty, flags } => self.visit_pointer_type_impl(ast, idx, ty, flags),
AstNode::ArrayType { length, pointer } => {
self.visit_array_type_impl(ast, idx, length, pointer)
}
AstNode::CallExpr {
func,
argument_list,
} => self.visit_call_expr_impl(ast, idx, func, argument_list),
AstNode::FieldAccess { field_name, expr } => {
self.visit_field_access_impl(ast, idx, field_name, expr)
}
AstNode::ArgumentList { arguments } => {
self.visit_argument_list_impl(ast, idx, arguments)
}
AstNode::Argument { expr, name } => self.visit_argument_impl(ast, idx, expr, name),
AstNode::ExplicitCast { expr, ty } => self.visit_explicit_cast_impl(ast, idx, expr, ty),
AstNode::Deref { expr } => self.visit_deref_impl(ast, idx, expr),
AstNode::AddressOf { expr } => self.visit_address_of_impl(ast, idx, expr),
AstNode::Not { expr } => self.visit_not_impl(ast, idx, expr),
AstNode::Negate { expr } => self.visit_negate_impl(ast, idx, expr),
AstNode::PlaceToValueConversion { expr } => {
self.visit_place_to_value_conversion_impl(ast, idx, expr)
}
AstNode::ValueToPlaceConversion { expr } => {
self.visit_value_to_place_conversion_impl(ast, idx, expr)
}
AstNode::Or { lhs, rhs } => self.visit_or_impl(ast, idx, lhs, rhs),
AstNode::And { lhs, rhs } => self.visit_and_impl(ast, idx, lhs, rhs),
AstNode::BitOr { lhs, rhs } => self.visit_bit_or_impl(ast, idx, lhs, rhs),
AstNode::BitXOr { lhs, rhs } => self.visit_bit_x_or_impl(ast, idx, lhs, rhs),
AstNode::BitAnd { lhs, rhs } => self.visit_bit_and_impl(ast, idx, lhs, rhs),
AstNode::Eq { lhs, rhs } => self.visit_eq_impl(ast, idx, lhs, rhs),
AstNode::NEq { lhs, rhs } => self.visit_n_eq_impl(ast, idx, lhs, rhs),
AstNode::Lt { lhs, rhs } => self.visit_lt_impl(ast, idx, lhs, rhs),
AstNode::Gt { lhs, rhs } => self.visit_gt_impl(ast, idx, lhs, rhs),
AstNode::Le { lhs, rhs } => self.visit_le_impl(ast, idx, lhs, rhs),
AstNode::Ge { lhs, rhs } => self.visit_ge_impl(ast, idx, lhs, rhs),
AstNode::Shl { lhs, rhs } => self.visit_shl_impl(ast, idx, lhs, rhs),
AstNode::Shr { lhs, rhs } => self.visit_shr_impl(ast, idx, lhs, rhs),
AstNode::Add { lhs, rhs } => self.visit_add_impl(ast, idx, lhs, rhs),
AstNode::Sub { lhs, rhs } => self.visit_sub_impl(ast, idx, lhs, rhs),
AstNode::Mul { lhs, rhs } => self.visit_mul_impl(ast, idx, lhs, rhs),
AstNode::Div { lhs, rhs } => self.visit_div_impl(ast, idx, lhs, rhs),
AstNode::Rem { lhs, rhs } => self.visit_rem_impl(ast, idx, lhs, rhs),
AstNode::Assign { lhs, rhs } => self.visit_assign_impl(ast, idx, lhs, rhs),
AstNode::SubscriptExpr { lhs, index: rhs } => {
self.visit_subscript_expr_impl(ast, idx, lhs, rhs)
}
AstNode::IfExpr { cond, body } => self.visit_if_expr_impl(ast, idx, cond, body),
AstNode::IfElseExpr { cond, a, b } => {
self.visit_if_else_expr_impl(ast, idx, cond, a, b)
}
AstNode::Error { err } => self.visit_error_impl(ast, idx, err),
AstNode::Undefined => self.visit_undefined_impl(ast, idx),
AstNode::Root { .. } => unreachable!(),
}
}
}