i declare victory (not)

This commit is contained in:
nora 2022-06-25 17:49:14 +02:00
parent 3576ccef01
commit 908c5c7615
5 changed files with 93 additions and 27 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
/target /target
.idea
.vscode

View file

@ -24,6 +24,8 @@ pub enum TypeSpecifier {
// typedef-name // typedef-name
} }
pub type Ident = Spanned<String>;
#[derive(Debug, Default, DebugPls)] #[derive(Debug, Default, DebugPls)]
pub struct DeclAttr { pub struct DeclAttr {
pub is_extern: bool, pub is_extern: bool,
@ -39,18 +41,29 @@ pub struct DeclSpec {
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub enum Declaration { pub enum Declaration {
Normal { Normal(NormalDeclaration),
decl_spec: DeclSpec,
name: Option<String>,
initializer: Option<()>,
pointer: bool,
},
StaticAssert, StaticAssert,
} }
#[derive(Debug, DebugPls)]
pub struct NormalDeclaration {
pub decl_spec: DeclSpec,
pub declarator: Declarator,
pub initializer: Option<()>,
}
#[derive(Debug, DebugPls)]
pub enum DirectDeclarator {
Ident(Ident),
WithParams {
ident: Ident,
params: Vec<NormalDeclaration>,
},
}
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub struct Declarator { pub struct Declarator {
pub identifier: String, pub decl: DirectDeclarator,
pub pointer: bool, pub pointer: bool,
} }
@ -63,13 +76,13 @@ pub struct FunctionParamDecl {
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub enum FunctionParameters { pub enum FunctionParameters {
Void(Span), Void(Span),
List(Vec<Spanned<FunctionParamDecl>>), List(Vec<Spanned<NormalDeclaration>>),
} }
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub struct FunctionDefinition { pub struct FunctionDefinition {
pub decl_spec: Spanned<DeclSpec>, pub decl_spec: Spanned<DeclSpec>,
pub declarator: Spanned<String>, pub name: Ident,
pub declaration_list: FunctionParameters, pub parameter_list: FunctionParameters,
pub body: Vec<()>, pub body: Vec<()>,
} }

View file

@ -2,8 +2,8 @@ use peekmore::PeekMoreIterator;
use crate::{ use crate::{
ast::{ ast::{
DeclAttr, DeclSpec, Declaration, Declarator, FunctionDefinition, FunctionParamDecl, DeclAttr, DeclSpec, Declaration, Declarator, DirectDeclarator, FunctionDefinition,
FunctionParameters, Spanned, TypeSpecifier, FunctionParamDecl, FunctionParameters, Ident, Spanned, TypeSpecifier,
}, },
pre::Punctuator as Punct, pre::Punctuator as Punct,
token::{Keyword as Kw, Token as Tok}, token::{Keyword as Kw, Token as Tok},
@ -56,6 +56,15 @@ macro_rules! expect {
}; };
} }
macro_rules! eat {
($self:ident, $pat:pat) => {
match $self.peek_t() {
Ok(($pat, _)) => Some($self.next_t()?),
_ => None,
}
};
}
/// Can be called for the start of a sequence of tokens that could be a type. /// Can be called for the start of a sequence of tokens that could be a type.
#[rustfmt::skip] #[rustfmt::skip]
fn is_tok_start_of_ty(tok: &Tok<'_>) -> bool { fn is_tok_start_of_ty(tok: &Tok<'_>) -> bool {
@ -75,7 +84,7 @@ fn is_tok_start_of_ty(tok: &Tok<'_>) -> bool {
// function specifiers // function specifiers
| Kw::Inline | Kw::Noreturn | Kw::Inline | Kw::Noreturn
) => true, ) => true,
Tok::Identifier(_) => false, // TODO: lookup typedefs! Tok::Ident(_) => false, // TODO: lookup typedefs!
_ => false, _ => false,
} }
} }
@ -104,9 +113,9 @@ where
self.lex.peek_nth(n).ok_or_else(ParserError::eof) self.lex.peek_nth(n).ok_or_else(ParserError::eof)
} }
fn ident(&mut self) -> Result<Spanned<String>> { fn ident(&mut self) -> Result<Ident> {
match self.next_t()? { match self.next_t()? {
(Tok::Identifier(ident), span) => Ok((ident.to_string(), span)), (Tok::Ident(ident), span) => Ok((ident.to_string(), span)),
(tok, span) => Err(ParserError::new( (tok, span) => Err(ParserError::new(
span, span,
format!("expected identifier, found `{tok}`"), format!("expected identifier, found `{tok}`"),
@ -232,7 +241,48 @@ where
/// (6.7.6) declarator: /// (6.7.6) declarator:
/// pointer.opt direct-declarator /// pointer.opt direct-declarator
///
/// It's only really known after the parsing of a declarator which kind of declaration we are
/// facing. For example: `int uwu` vs `int uwu()`. The parentheses indicate a function
/// declaration. Therefore, we have no idea what we're parsing before entering this function.
fn declarator(&mut self) -> Result<Spanned<Declarator>> { fn declarator(&mut self) -> Result<Spanned<Declarator>> {
if let Some((_, span)) = eat!(self, Tok::Punct(Punct::Asterisk)) {
let (decl, span2) = self.direct_declarator()?;
Ok((
Declarator {
decl,
pointer: true,
},
span.extend(span2),
))
} else {
let (decl, span) = self.direct_declarator()?;
Ok((
Declarator {
decl,
pointer: false,
},
span,
))
}
}
/// direct-declarator:
/// identifier
/// ( declarator )
/// direct-declarator \[ type-qualifier-listopt assignment-expressionopt ]
/// direct-declarator \[ static type-qualifier-listopt assignment-expression ]
/// direct-declarator \[ type-qualifier-list static assignment-expression ]
/// direct-declarator \[ type-qualifier-listopt * ]
/// direct-declarator ( parameter-type-list )
/// direct-declarator ( identifier-listopt )
fn direct_declarator(&mut self) -> Result<Spanned<DirectDeclarator>> {
if let Some((Tok::Ident(name), span)) = eat!(self, Tok::Ident(_)) {
return Ok((DirectDeclarator::Ident((name.to_owned(), span)), span));
}
todo!() todo!()
} }
@ -244,9 +294,8 @@ where
/// function-definition /// function-definition
/// declaration /// declaration
fn external_declaration(&mut self) -> Result<Spanned<FunctionDefinition>> { fn external_declaration(&mut self) -> Result<Spanned<FunctionDefinition>> {
let (next, span) = self.peek_t()?; if let Some((token, span)) = eat!(self, Tok::Kw(Kw::StaticAssert)) {
if let Tok::Kw(Kw::StaticAssert) = next { return Err(ParserError::unsupported(span, &token));
return Err(ParserError::unsupported(*span, next));
} }
let decl_spec = self.declaration_specifiers()?; let decl_spec = self.declaration_specifiers()?;
@ -269,6 +318,8 @@ where
&mut self, &mut self,
decl_spec: Spanned<DeclSpec>, decl_spec: Spanned<DeclSpec>,
) -> Result<Spanned<FunctionDefinition>> { ) -> Result<Spanned<FunctionDefinition>> {
let _oh_fuck = self.declarator()?;
let declarator = self.ident()?; let declarator = self.ident()?;
let decl_spec_span = decl_spec.1; let decl_spec_span = decl_spec.1;
@ -283,8 +334,8 @@ where
let def = FunctionDefinition { let def = FunctionDefinition {
decl_spec, decl_spec,
declarator, name: declarator,
declaration_list, parameter_list: declaration_list,
body: Vec::new(), body: Vec::new(),
}; };
@ -300,6 +351,7 @@ where
// shall follow. // shall follow.
if let &(Tok::Kw(Kw::Void), span) = self.peek_t()? { if let &(Tok::Kw(Kw::Void), span) = self.peek_t()? {
if let (Tok::Punct(Punct::ParenClose), _) = self.peek_t_n(1)? { if let (Tok::Punct(Punct::ParenClose), _) = self.peek_t_n(1)? {
self.next_t()?;
self.next_t()?; self.next_t()?;
return Ok(FunctionParameters::Void(span)); return Ok(FunctionParameters::Void(span));
} }
@ -328,10 +380,9 @@ where
}; };
params.push((param, span1.extend(span2))); params.push((param, span1.extend(span2)));
} }
Ok(FunctionParameters::List(params)) Ok(FunctionParameters::List(todo!()))
} }
} }

View file

@ -10,7 +10,7 @@ expression: tokens
1..4, 1..4,
), ),
( (
Identifier( Ident(
"main", "main",
), ),
5..9, 5..9,
@ -34,7 +34,7 @@ expression: tokens
12..13, 12..13,
), ),
( (
Identifier( Ident(
"puts", "puts",
), ),
18..22, 18..22,

View file

@ -14,7 +14,7 @@ use crate::{
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Token<'src> { pub enum Token<'src> {
Kw(Keyword), Kw(Keyword),
Identifier(&'src str), Ident(&'src str),
Constant(Constant), Constant(Constant),
StringLiteral(&'src str), StringLiteral(&'src str),
Punct(Punctuator), Punct(Punctuator),
@ -140,7 +140,7 @@ pub fn pre_tokens_to_tokens<'src>(
PToken::HeaderName(_) => todo!("header names aren't real, wake up"), PToken::HeaderName(_) => todo!("header names aren't real, wake up"),
PToken::Identifier(ident) => match ident_to_keyword(ident) { PToken::Identifier(ident) => match ident_to_keyword(ident) {
Some(keyword) => Token::Kw(keyword), Some(keyword) => Token::Kw(keyword),
None => Token::Identifier(ident), None => Token::Ident(ident),
}, },
PToken::PpNumber(number) => pp_number_to_constant(number) PToken::PpNumber(number) => pp_number_to_constant(number)
.map(Token::Constant) .map(Token::Constant)
@ -159,7 +159,7 @@ impl Display for Token<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Token::Kw(kw) => Display::fmt(kw, f), Token::Kw(kw) => Display::fmt(kw, f),
Token::Identifier(ident) => Display::fmt(ident, f), Token::Ident(ident) => Display::fmt(ident, f),
Token::Constant(c) => Display::fmt(c, f), Token::Constant(c) => Display::fmt(c, f),
Token::StringLiteral(str) => write!(f, "\"{}\"", str), Token::StringLiteral(str) => write!(f, "\"{}\"", str),
Token::Punct(p) => Display::fmt(p, f), Token::Punct(p) => Display::fmt(p, f),