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
|
|
@ -23,3 +23,16 @@ pub enum TypeSpecifier {
|
|||
// enum-specifier
|
||||
// typedef-name
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, DebugPls)]
|
||||
pub struct DeclAttr {
|
||||
pub is_extern: bool,
|
||||
pub is_static: bool,
|
||||
pub is_thread_local: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, DebugPls)]
|
||||
pub struct DeclSpec {
|
||||
pub ty: TypeSpecifier,
|
||||
pub attrs: DeclAttr,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,21 @@ mod parser;
|
|||
mod pre;
|
||||
mod token;
|
||||
|
||||
pub type Span = std::ops::Range<usize>;
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
|
||||
pub struct Span {
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
}
|
||||
|
||||
impl Span {
|
||||
pub fn start_end(start: usize, end: usize) -> Self {
|
||||
Self { start, end }
|
||||
}
|
||||
|
||||
pub fn extend(&self, rhs: Self) -> Self {
|
||||
Self::start_end(self.start, rhs.end)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_file(src: &str) {
|
||||
println!("{src}");
|
||||
|
|
|
|||
|
|
@ -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!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
//!
|
||||
//! Code might be bad. Possibly.
|
||||
|
||||
use std::{ops::Not, fmt::Display};
|
||||
use std::{fmt::Display, ops::Not};
|
||||
|
||||
use peekmore::PeekMore;
|
||||
|
||||
|
|
@ -398,11 +398,11 @@ where
|
|||
}
|
||||
};
|
||||
|
||||
Some((token, start_span..end_span + 1))
|
||||
Some((token, Span::start_end(start_span, end_span + 1)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn preprocess_tokens(src: &str) -> impl Iterator<Item = (PToken<'_>, std::ops::Range<usize>)> {
|
||||
pub fn preprocess_tokens(src: &str) -> impl Iterator<Item = (PToken<'_>, Span)> {
|
||||
let lexer = PLexer {
|
||||
src_str: src,
|
||||
src: src.bytes().enumerate().peekmore(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue