mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-16 17:45:11 +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
|
// enum-specifier
|
||||||
// typedef-name
|
// 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 pre;
|
||||||
mod token;
|
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) {
|
pub fn parse_file(src: &str) {
|
||||||
println!("{src}");
|
println!("{src}");
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use peekmore::PeekMoreIterator;
|
use peekmore::PeekMoreIterator;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Spanned, TypeSpecifier},
|
ast::{DeclAttr, DeclSpec, Spanned, TypeSpecifier},
|
||||||
token::{Keyword as Kw, Token as Tok},
|
token::{Keyword as Kw, Token as Tok},
|
||||||
Span,
|
Span,
|
||||||
};
|
};
|
||||||
|
|
@ -17,7 +17,11 @@ impl ParserError {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eof() -> Self {
|
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
|
where
|
||||||
I: Iterator<Item = (Tok<'src>, Span)>,
|
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>> {
|
fn type_specifier(&mut self) -> Result<Spanned<TypeSpecifier>> {
|
||||||
let (token, span) = self.next_t()?;
|
let (token, span) = self.next_t()?;
|
||||||
let ty = match token {
|
let ty = match token {
|
||||||
|
|
@ -47,13 +131,43 @@ where
|
||||||
Tok::Kw(Kw::Signed) => TypeSpecifier::Signed,
|
Tok::Kw(Kw::Signed) => TypeSpecifier::Signed,
|
||||||
Tok::Kw(Kw::Unsigned) => TypeSpecifier::Unsigned,
|
Tok::Kw(Kw::Unsigned) => TypeSpecifier::Unsigned,
|
||||||
Tok::Kw(Kw::Bool) => TypeSpecifier::Bool,
|
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}`"))),
|
tok => return Err(ParserError::new(span, format!("Invalid token: `{tok}`"))),
|
||||||
};
|
};
|
||||||
Ok((ty, span))
|
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.
|
//! Code might be bad. Possibly.
|
||||||
|
|
||||||
use std::{ops::Not, fmt::Display};
|
use std::{fmt::Display, ops::Not};
|
||||||
|
|
||||||
use peekmore::PeekMore;
|
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 {
|
let lexer = PLexer {
|
||||||
src_str: src,
|
src_str: src,
|
||||||
src: src.bytes().enumerate().peekmore(),
|
src: src.bytes().enumerate().peekmore(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue