helpers for reading ast Data and getting children of ast nodes

This commit is contained in:
Janis 2024-09-09 15:41:56 +02:00
parent 45653380cf
commit 6f3a7dc56c

View file

@ -870,7 +870,7 @@ enum Tag {
/// `data` is none
ReturnStmt,
/// `data` is an index to an expr
ReturnValueStmt,
ReturnExprStmt,
/// `data` is a range from a..b into `extra` of an intern to a name and an optional intern to a type
VarDecl,
/// `data` is a range from a..b into `extra` of an intern to a name and an optional intern to a type
@ -976,6 +976,9 @@ enum ParseError {
pub struct Index(NonZero<u32>);
impl Index {
pub fn new(i: u32) -> Index {
Self(NonZero::<u32>::new(i).unwrap())
}
pub fn as_u32(&self) -> &u32 {
unsafe { core::mem::transmute(self) }
}
@ -1010,6 +1013,42 @@ union Data {
index_and_extra_offset: (Index, u32),
}
impl Data {
fn as_error(self) -> ParseError {
unsafe { self.error }
}
fn as_index(self) -> Index {
unsafe { self.index }
}
fn as_two_indices(self) -> (Index, Index) {
unsafe { self.two_indices }
}
fn as_index_range(self) -> (Index, Index) {
unsafe { self.range }
}
fn as_extra_range(self) -> (usize, usize) {
let (a, b) = unsafe { self.extra_range };
(a as usize, b as usize)
}
fn as_intern(self) -> Intern {
unsafe { self.intern }
}
fn as_two_indices(self) -> (Intern, Intern) {
unsafe { self.two_indices }
}
fn as_index_intern(self) -> (Index, intern::Index) {
unsafe { self.index_intern }
}
fn as_index_and_extra_offset(self) -> (Index, usize) {
let (i, e) = unsafe { self.index_and_extra_offset };
(i, e as usize)
}
fn as_intern_and_extra_offset(self) -> (intern::Index, usize) {
let (i, e) = unsafe { self.intern_and_extra_offset };
(i, e as usize)
}
}
impl Data {
fn none() -> Self {
Self { none: () }
@ -1124,7 +1163,7 @@ impl Ast {
let i = self.reserve_node();
match expr {
Some(expr) => {
self.set_tag_data_source_loc(i, Tag::ReturnValueStmt, Data::index(expr), loc)
self.set_tag_data_source_loc(i, Tag::ReturnExprStmt, Data::index(expr), loc)
}
None => self.set_tag_data_source_loc(i, Tag::ReturnStmt, Data::none(), loc),
}
@ -1145,7 +1184,8 @@ impl Ast {
let start = self.extra.len() as u32;
self.extra.push(name.into_u32());
_ = self.extend_extra(assignment.map(|i| i.into_u32()));
let (_, end) = self.extend_extra(ty.map(|i| i.into_u32()));
_ = self.extend_extra(ty.map(|i| i.into_u32()));
let end = self.extra.len() as u32;
let tag = match (is_let, assignment.is_some()) {
(true, false) => Tag::VarDecl,
@ -1387,6 +1427,111 @@ impl Ast {
}
}
impl Ast {
fn get_node_children(&self, index: Index) -> Vec<Index> {
let tag = self.tags[index.index()];
let data = self.datas[index.index()];
match tag {
Tag::File => {
let (a, b) = data.as_extra_range();
self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
}
Tag::FunctionProto => {
let (_, i) = data.as_intern_and_extra_offset();
vec![Index::new(self.extra[i + 1])]
}
Tag::FunctionDecl => {
let (a, b) = data.as_two_indices();
vec![a, b]
}
Tag::ParameterList => {
let (a, b) = data.as_extra_range();
self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
}
Tag::Block | Tag::BlockTrailingExpr => {
let (a, b) = data.as_extra_range();
self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
}
Tag::ExprStmt | Tag::ReturnExprStmt => {
let a = data.as_index();
vec![a]
}
Tag::Parameter => todo!(),
Tag::Constant => todo!(),
Tag::ReturnStmt => todo!(),
Tag::VarDecl => todo!(),
Tag::MutVarDecl => todo!(),
Tag::VarDeclAssignment | Tag::MutVarDeclAssignment => {
let (a, _) = data.as_extra_range();
let expr = Index::new(self.extra[a + 1]);
vec![expr]
}
Tag::GlobalDecl => {
let (a, _) = data.as_index_intern();
vec![a]
}
Tag::StructDecl => todo!(),
Tag::DeclRef => todo!(),
Tag::CallExpr => {
let (a, b) = data.as_two_indices();
vec![a, b]
}
Tag::ArgumentList => {
let (a, b) = data.as_extra_range();
self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
}
Tag::Argument => {
let a = data.as_index();
vec![a]
}
Tag::NamedArgument => {
let (a, _) = data.as_index_intern();
vec![a]
}
Tag::ExplicitCast => {
let (a, _) = data.as_index_intern();
vec![a]
}
Tag::Deref | Tag::AddressOf | Tag::Not | Tag::Negate => {
let a = data.as_index();
vec![a]
}
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
| Tag::Assign
| Tag::SubscriptExpr
| Tag::IfExpr => {
let (a, b) = data.as_two_indices();
vec![a, b]
}
Tag::IfElseExpr => {
let (a, b) = data.as_index_and_extra_offset();
let if_ = Index::new(self.extra[b]);
let else_ = Index::new(self.extra[b + 1]);
vec![a, if_, else_]
}
_ => vec![],
}
}
}
mod ast_gen {
use intern::{PointerFlags, SimpleType};
@ -1394,7 +1539,7 @@ mod ast_gen {
use num_bigint::{BigInt, BigUint};
use crate::{
common::{from_lo_hi_dwords, NextIf},
common::from_lo_hi_dwords,
comptime,
lexer::{Radix, TokenItem, TokenIterator},
tokens::PRECEDENCE_MAP,
@ -2449,17 +2594,6 @@ mod ast_gen {
}
}
fn parse_statement(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
let expr = self.parse_expr(tokens)?;
let stmt = match tokens.eat_token(Token::Semi) {
Some(_) => self.ast.push_expr_stmt(expr),
None => self.push_error(ParseError::ExpectedStatement, self.ast.get_loc(expr)),
};
Ok(stmt)
}
/// SUMTYPE_DECL <-
/// type IDENTIFIER = TYPE_UNION
/// TYPE_UNION <-