mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-14 16:45:07 +01:00
parse some things
This commit is contained in:
parent
eb68c2b207
commit
5cf64dfc55
4 changed files with 150 additions and 9 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use peekmore::PeekMoreIterator;
|
||||
|
||||
use crate::{
|
||||
ast::{Spanned, TypeSpecifier},
|
||||
ast::{DeclAttr, DeclSpec, Spanned, TypeSpecifier},
|
||||
token::{Keyword as Kw, Token as Tok},
|
||||
Span,
|
||||
};
|
||||
|
|
@ -17,7 +17,11 @@ impl ParserError {
|
|||
}
|
||||
|
||||
fn eof() -> Self {
|
||||
Self::new(0..0, "unexpected end of file".to_string())
|
||||
Self::new(Span::default(), "unexpected end of file".to_string())
|
||||
}
|
||||
|
||||
fn unsupported(span: Span, token: &Tok<'_>) -> Self {
|
||||
Self::new(span, format!("`{token}` is not supported"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -34,6 +38,86 @@ impl<'src, I> Parser<'src, I>
|
|||
where
|
||||
I: Iterator<Item = (Tok<'src>, Span)>,
|
||||
{
|
||||
fn find_typedef(&self, ident: &str) -> Option<()> {
|
||||
None // TODO: this
|
||||
}
|
||||
|
||||
fn next_t(&mut self) -> Result<(Tok<'src>, Span)> {
|
||||
self.lex.next().ok_or_else(ParserError::eof)
|
||||
}
|
||||
|
||||
fn peek_t(&mut self) -> Result<&(Tok<'src>, Span)> {
|
||||
self.lex.peek().ok_or_else(ParserError::eof)
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Declarations
|
||||
// -----------------------
|
||||
|
||||
/// (6.7) declaration:
|
||||
/// declaration-specifiers init-declarator-listopt ;
|
||||
/// static_assert-declaration
|
||||
fn declaration(&mut self) -> Result<Spanned<()>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// (6.7) declaration-specifiers:
|
||||
/// storage-class-specifier declaration-specifiers.opt
|
||||
/// type-specifier declaration-specifiers.opt
|
||||
/// type-qualifier declaration-specifiers.opt
|
||||
/// function-specifier declaration-specifiers.opt
|
||||
/// alignment-specifier declaration-specifiers.opt
|
||||
fn declaration_specifiers(&mut self) -> Result<Spanned<DeclSpec>> {
|
||||
let mut decl_attr = DeclAttr::default();
|
||||
let &(_, initial_span) = self.peek_t()?;
|
||||
let (ty, span) = loop {
|
||||
match self.peek_t()?.0 {
|
||||
// (6.7.1) storage-class-specifier
|
||||
Tok::Kw(Kw::Typedef | Kw::Auto | Kw::Register) => {
|
||||
self.next_t()?; // ignore
|
||||
}
|
||||
Tok::Kw(Kw::Extern) => {
|
||||
self.next_t()?;
|
||||
decl_attr.is_extern = true;
|
||||
}
|
||||
Tok::Kw(Kw::Static) => {
|
||||
self.next_t()?;
|
||||
decl_attr.is_static = true;
|
||||
}
|
||||
Tok::Kw(Kw::ThreadLocal) => {
|
||||
self.next_t()?;
|
||||
decl_attr.is_thread_local = true;
|
||||
}
|
||||
// (6.7.3) type-qualifier:
|
||||
Tok::Kw(Kw::Const | Kw::Restrict | Kw::Volatile | Kw::Atomic) => {
|
||||
self.next_t()?; // ignore
|
||||
}
|
||||
// (6.7.4) function-specifier:
|
||||
Tok::Kw(Kw::Inline | Kw::Noreturn) => {
|
||||
self.next_t()?; // ignore
|
||||
}
|
||||
// (6.7.5) alignment-specifier:
|
||||
Tok::Kw(Kw::Alignas) => {
|
||||
let (token, span) = self.next_t()?;
|
||||
return Err(ParserError::unsupported(span, &token));
|
||||
}
|
||||
// if it's neither of the above, it has to be a type-specifier
|
||||
_ => {
|
||||
let ty = self.type_specifier()?;
|
||||
break ty;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok((
|
||||
DeclSpec {
|
||||
ty,
|
||||
attrs: decl_attr,
|
||||
},
|
||||
initial_span.extend(span),
|
||||
))
|
||||
}
|
||||
|
||||
fn type_specifier(&mut self) -> Result<Spanned<TypeSpecifier>> {
|
||||
let (token, span) = self.next_t()?;
|
||||
let ty = match token {
|
||||
|
|
@ -47,13 +131,43 @@ where
|
|||
Tok::Kw(Kw::Signed) => TypeSpecifier::Signed,
|
||||
Tok::Kw(Kw::Unsigned) => TypeSpecifier::Unsigned,
|
||||
Tok::Kw(Kw::Bool) => TypeSpecifier::Bool,
|
||||
Tok::Kw(Kw::Complex) => return Err(ParserError::new(span, "tf are you doing with complex numbers".to_string())),
|
||||
Tok::Kw(Kw::Complex) => {
|
||||
return Err(ParserError::new(
|
||||
span,
|
||||
"tf are you doing with complex numbers".to_string(),
|
||||
))
|
||||
}
|
||||
tok => return Err(ParserError::new(span, format!("Invalid token: `{tok}`"))),
|
||||
};
|
||||
Ok((ty, span))
|
||||
}
|
||||
|
||||
fn next_t(&mut self) -> Result<(Tok<'src>, Span)> {
|
||||
self.lex.next().ok_or_else(ParserError::eof)
|
||||
// -----------------------
|
||||
// External definitions
|
||||
// -----------------------
|
||||
|
||||
|
||||
/// (6.9) external-declaration:
|
||||
/// function-definition
|
||||
/// declaration
|
||||
fn external_declaration(&mut self) -> Result<()> {
|
||||
let (next, span) = self.peek_t()?;
|
||||
if let Tok::Kw(Kw::StaticAssert) = next {
|
||||
return Err(ParserError::unsupported(*span, next));
|
||||
}
|
||||
|
||||
let decl_spec = self.declaration_specifiers()?;
|
||||
|
||||
// TODO: We just assume that it's a function, that's terrible!
|
||||
|
||||
self.function_definition(decl_spec)?;
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// (6.9.1) function-definition:
|
||||
/// declaration-specifiers declarator declaration-list.opt compound-statement
|
||||
fn function_definition(&mut self, specifiers: Spanned<DeclSpec>) -> Result<Spanned<()>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue