helpers for reading ast Data
and getting children of ast nodes
This commit is contained in:
parent
45653380cf
commit
6f3a7dc56c
164
src/ast2/mod.rs
164
src/ast2/mod.rs
|
@ -870,7 +870,7 @@ enum Tag {
|
||||||
/// `data` is none
|
/// `data` is none
|
||||||
ReturnStmt,
|
ReturnStmt,
|
||||||
/// `data` is an index to an expr
|
/// `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
|
/// `data` is a range from a..b into `extra` of an intern to a name and an optional intern to a type
|
||||||
VarDecl,
|
VarDecl,
|
||||||
/// `data` is a range from a..b into `extra` of an intern to a name and an optional intern to a type
|
/// `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>);
|
pub struct Index(NonZero<u32>);
|
||||||
|
|
||||||
impl Index {
|
impl Index {
|
||||||
|
pub fn new(i: u32) -> Index {
|
||||||
|
Self(NonZero::<u32>::new(i).unwrap())
|
||||||
|
}
|
||||||
pub fn as_u32(&self) -> &u32 {
|
pub fn as_u32(&self) -> &u32 {
|
||||||
unsafe { core::mem::transmute(self) }
|
unsafe { core::mem::transmute(self) }
|
||||||
}
|
}
|
||||||
|
@ -1010,6 +1013,42 @@ union Data {
|
||||||
index_and_extra_offset: (Index, u32),
|
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 {
|
impl Data {
|
||||||
fn none() -> Self {
|
fn none() -> Self {
|
||||||
Self { none: () }
|
Self { none: () }
|
||||||
|
@ -1124,7 +1163,7 @@ impl Ast {
|
||||||
let i = self.reserve_node();
|
let i = self.reserve_node();
|
||||||
match expr {
|
match expr {
|
||||||
Some(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),
|
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;
|
let start = self.extra.len() as u32;
|
||||||
self.extra.push(name.into_u32());
|
self.extra.push(name.into_u32());
|
||||||
_ = self.extend_extra(assignment.map(|i| i.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()) {
|
let tag = match (is_let, assignment.is_some()) {
|
||||||
(true, false) => Tag::VarDecl,
|
(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 {
|
mod ast_gen {
|
||||||
|
|
||||||
use intern::{PointerFlags, SimpleType};
|
use intern::{PointerFlags, SimpleType};
|
||||||
|
@ -1394,7 +1539,7 @@ mod ast_gen {
|
||||||
use num_bigint::{BigInt, BigUint};
|
use num_bigint::{BigInt, BigUint};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::{from_lo_hi_dwords, NextIf},
|
common::from_lo_hi_dwords,
|
||||||
comptime,
|
comptime,
|
||||||
lexer::{Radix, TokenItem, TokenIterator},
|
lexer::{Radix, TokenItem, TokenIterator},
|
||||||
tokens::PRECEDENCE_MAP,
|
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 <-
|
/// SUMTYPE_DECL <-
|
||||||
/// type IDENTIFIER = TYPE_UNION
|
/// type IDENTIFIER = TYPE_UNION
|
||||||
/// TYPE_UNION <-
|
/// TYPE_UNION <-
|
||||||
|
|
Loading…
Reference in a new issue