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 ir;
pub mod parser; pub mod parser;
pub mod tag; pub mod tag;
pub mod typecheck;
pub mod visitor; pub mod visitor;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

View file

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