still works

This commit is contained in:
nora 2022-06-25 18:59:23 +02:00
parent 955effd621
commit f53c054a9a
5 changed files with 200 additions and 149 deletions

View file

@ -1,8 +1,6 @@
use dbg_pls::DebugPls; use dbg_pls::DebugPls;
use crate::Span; use crate::{Span, Spanned};
pub type Spanned<T> = (T, Span);
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub enum TypeSpecifier { pub enum TypeSpecifier {
@ -40,16 +38,21 @@ pub struct DeclSpec {
} }
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub enum Declaration { pub enum Decl {
Normal(NormalDeclaration), Normal(NormalDecl),
StaticAssert, StaticAssert,
} }
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub struct NormalDeclaration { pub struct InitDecl {
pub decl_spec: DeclSpec,
pub declarator: Declarator, pub declarator: Declarator,
pub initializer: Option<()>, pub init: Option<()>,
}
#[derive(Debug, DebugPls)]
pub struct NormalDecl {
pub decl_spec: DeclSpec,
pub init_declarators: Vec<Spanned<InitDecl>>,
} }
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
@ -57,7 +60,7 @@ pub enum DirectDeclarator {
Ident(Ident), Ident(Ident),
WithParams { WithParams {
ident: Ident, ident: Ident,
params: Vec<NormalDeclaration>, params: Vec<NormalDecl>,
}, },
} }
@ -74,15 +77,19 @@ pub struct FunctionParamDecl {
} }
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub enum FunctionParameters { pub enum FunctionParams {
Void(Span), Void(Span),
List(Vec<Spanned<NormalDeclaration>>), List(Vec<Spanned<NormalDecl>>),
} }
#[derive(Debug, DebugPls)] #[derive(Debug, DebugPls)]
pub struct FunctionDefinition { pub struct FunctionDef {
pub decl_spec: Spanned<DeclSpec>, pub declaration: Decl,
pub name: Ident,
pub parameter_list: FunctionParameters,
pub body: Vec<()>, pub body: Vec<()>,
} }
#[derive(Debug, DebugPls)]
pub enum ExternalDecl {
Decl(Decl),
FunctionDef(FunctionDef),
}

View file

@ -8,6 +8,8 @@ mod parser;
mod pre; mod pre;
mod token; mod token;
pub type Spanned<T> = (T, Span);
#[derive(PartialEq, Eq, Clone, Copy, Default)] #[derive(PartialEq, Eq, Clone, Copy, Default)]
pub struct Span { pub struct Span {
pub start: usize, pub start: usize,
@ -22,6 +24,16 @@ impl Span {
pub fn extend(&self, rhs: Self) -> Self { pub fn extend(&self, rhs: Self) -> Self {
Self::start_end(self.start, rhs.end) Self::start_end(self.start, rhs.end)
} }
pub fn extend_option(&self, rhs: Option<Self>) -> Self {
rhs.map(|s| self.extend(s)).unwrap_or(*self)
}
pub fn span_of_spanned_list<T>(list: &[Spanned<T>]) -> Option<Span> {
list.iter().fold(None, |old_span, &(_, span)| {
Some(old_span.map(|s| s.extend(span)).unwrap_or(span))
})
}
} }
impl dbg_pls::DebugPls for Span { impl dbg_pls::DebugPls for Span {

View file

@ -2,12 +2,12 @@ use peekmore::PeekMoreIterator;
use crate::{ use crate::{
ast::{ ast::{
DeclAttr, DeclSpec, Declaration, Declarator, DirectDeclarator, FunctionDefinition, Decl, DeclAttr, DeclSpec, Declarator, DirectDeclarator, ExternalDecl, FunctionDef,
FunctionParamDecl, FunctionParameters, Ident, Spanned, TypeSpecifier, FunctionParams, Ident, InitDecl, NormalDecl, TypeSpecifier,
}, },
pre::Punctuator as Punct, pre::Punctuator as Punct,
token::{Keyword as Kw, Token as Tok}, token::{Keyword as Kw, Token as Tok},
Span, Span, Spanned,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -89,6 +89,14 @@ fn is_tok_start_of_ty(tok: &Tok<'_>) -> bool {
} }
} }
/// Can be called for the start of a sequence of tokens that could be a type.
fn is_tok_start_of_declarator(tok: &Tok<'_>) -> bool {
matches!(
tok,
Tok::Ident(_) | Tok::Punct(Punct::ParenOpen | Punct::Asterisk)
)
}
impl<'src, I> Parser<'src, I> impl<'src, I> Parser<'src, I>
where where
I: Iterator<Item = (Tok<'src>, Span)>, I: Iterator<Item = (Tok<'src>, Span)>,
@ -130,6 +138,17 @@ where
} }
} }
fn is_peek_tok_start_of_declarator(&mut self) -> bool {
match self.peek_t() {
Ok((tok, _)) => is_tok_start_of_declarator(tok),
Err(_) => false,
}
}
fn is_peek_comma(&mut self) -> bool {
matches!(self.peek_t(), Ok((Tok::Punct(Punct::Comma), _)))
}
// ----------------------- // -----------------------
// Declarations // Declarations
// ----------------------- // -----------------------
@ -137,25 +156,59 @@ where
/// (6.7) declaration: /// (6.7) declaration:
/// declaration-specifiers init-declarator-listopt ; /// declaration-specifiers init-declarator-listopt ;
/// static_assert-declaration /// static_assert-declaration
fn declaration(&mut self) -> Result<Spanned<Declaration>> { fn declaration(&mut self) -> Result<Spanned<Decl>> {
if let &(tok @ Tok::Kw(Kw::StaticAssert), span) = self.peek_t()? { if let Some((tok, span)) = eat!(self, Tok::Kw(Kw::StaticAssert)) {
self.next_t()?;
return Err(ParserError::unsupported(span, &tok)); return Err(ParserError::unsupported(span, &tok));
} }
// first, some declaration-specifiers let (decl_spec, span) = self.declaration_specifiers()?;
let _decl_spec = self.declaration_specifiers()?;
// then (optionally), a declarator let init_declarators = self.init_declarator_list()?;
// (6.7.6) declarator: let init_declarators_span = Span::span_of_spanned_list(&init_declarators);
// pointer.opt direct-declarator
if let &(tok @ Tok::Punct(Punct::Asterisk), span) = self.peek_t()? { let span = span.extend_option(init_declarators_span);
self.next_t()?;
return Err(ParserError::unsupported(span, &tok)); Ok((
Decl::Normal(NormalDecl {
decl_spec,
init_declarators,
}),
span,
))
}
/// init-declarator-list:
/// init-declarator
/// init-declarator-list , init-declarator
///
/// init-declarator:
/// declarator
/// declarator = initializer
fn init_declarator_list(&mut self) -> Result<Vec<Spanned<InitDecl>>> {
let mut init_decls = Vec::new();
let mut first = true;
loop {
println!("LOOOOP");
if !self.is_peek_tok_start_of_declarator() && !self.is_peek_comma() {
break;
}
if !first {
expect!(self, Tok::Punct(Punct::Comma));
}
first = false;
let (declarator, span) = self.declarator()?;
if let Some((token, span)) = eat!(self, Tok::Punct(Punct::Eq)) {
return Err(ParserError::unsupported(span, &token));
}
let init_decl = InitDecl {
declarator,
init: None,
};
init_decls.push((init_decl, span));
} }
// then (optionally), an initializer Ok(init_decls)
todo!("this doesn't work like this")
} }
/// (6.7) declaration-specifiers: /// (6.7) declaration-specifiers:
@ -282,7 +335,15 @@ where
let (ident, span) = self.ident()?; let (ident, span) = self.ident()?;
if (eat!(self, Tok::Punct(Punct::ParenOpen))).is_some() { if (eat!(self, Tok::Punct(Punct::ParenOpen))).is_some() {
todo!("haha, no parentheses for you!") // nothing in the params supported yet.
expect!(self, Tok::Punct(Punct::ParenClose));
return Ok((
DirectDeclarator::WithParams {
ident: (ident, span),
params: Vec::new(),
},
span,
));
} }
Ok((DirectDeclarator::Ident((ident, span)), span)) Ok((DirectDeclarator::Ident((ident, span)), span))
@ -295,58 +356,26 @@ where
/// (6.9) external-declaration: /// (6.9) external-declaration:
/// function-definition /// function-definition
/// declaration /// declaration
fn external_declaration(&mut self) -> Result<Spanned<FunctionDefinition>> { fn external_declaration(&mut self) -> Result<Spanned<ExternalDecl>> {
if let Some((token, span)) = eat!(self, Tok::Kw(Kw::StaticAssert)) { let (declaration, span) = self.declaration()?;
return Err(ParserError::unsupported(span, &token));
// the declaration might be a function definition
if eat!(self, Tok::Punct(Punct::BraceOpen)).is_some() {
let span2 = expect!(self, Tok::Punct(Punct::BraceClose));
Ok((
ExternalDecl::FunctionDef(FunctionDef {
declaration,
body: Vec::new(),
}),
span.extend(span2),
))
} else {
Ok((ExternalDecl::Decl(declaration), span))
} }
let decl_spec = self.declaration_specifiers()?;
// TODO: We just assume that it's a function, that's terrible!
self.function_definition(decl_spec)
} }
/// (6.9.1) function-definition: fn function_param_declaration_list(&mut self) -> Result<FunctionParams> {
/// declaration-specifiers declarator declaration-list.opt compound-statement
/// IMPORTANT TODO DO NOT FORGET THIS IS MISSION CRITICAL
/// THERE ARE RULES FOR parameter-type-list
/// WE ARE IN direct-declarator HERE
/// USE THIS
/// DO NOT DO THIS WRONGLY
/// C IS ONLY HALF HAS SHITTY AS IT SOUNDS
/// OK BUT HALF IS STILL A LOT
fn function_definition(
&mut self,
decl_spec: Spanned<DeclSpec>,
) -> Result<Spanned<FunctionDefinition>> {
let _oh_fuck = self.declarator()?;
let declarator = self.ident()?;
let decl_spec_span = decl_spec.1;
expect!(self, Tok::Punct(Punct::ParenOpen));
let declaration_list = self.function_param_declaration_list()?;
expect!(self, Tok::Punct(Punct::ParenClose));
expect!(self, Tok::Punct(Punct::BraceOpen));
let def = FunctionDefinition {
decl_spec,
name: declarator,
parameter_list: declaration_list,
body: Vec::new(),
};
let last = expect!(self, Tok::Punct(Punct::BraceClose));
Ok((def, decl_spec_span.extend(last)))
}
fn function_param_declaration_list(&mut self) -> Result<FunctionParameters> {
// If the declarator includes a parameter type list, the declaration of each parameter shall // If the declarator includes a parameter type list, the declaration of each parameter shall
// include an identifier, except for the special case of a parameter list consisting of a single // include an identifier, except for the special case of a parameter list consisting of a single
// parameter of type void, in which case there shall not be an identifier. No declaration list // parameter of type void, in which case there shall not be an identifier. No declaration list
@ -355,36 +384,11 @@ where
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()?; self.next_t()?;
return Ok(FunctionParameters::Void(span)); return Ok(FunctionParams::Void(span));
} }
} }
let mut params = Vec::new(); todo!()
if self.is_peek_tok_start_of_ty() {
let (decl_spec, span1) = self.declaration_specifiers()?;
let (declarator, span2) = self.declarator()?;
let param = FunctionParamDecl {
decl_spec,
declarator,
};
params.push((param, span1.extend(span2)));
}
while self.is_peek_tok_start_of_ty() {
expect!(self, Tok::Punct(Punct::Comma));
let (decl_spec, span1) = self.declaration_specifiers()?;
let (declarator, span2) = self.declarator()?;
let param = FunctionParamDecl {
decl_spec,
declarator,
};
params.push((param, span1.extend(span2)));
}
Ok(FunctionParameters::List(todo!()))
} }
} }

View file

@ -4,27 +4,41 @@ expression: parsed
--- ---
Ok( Ok(
( (
FunctionDefinition { FunctionDef(
decl_spec: ( FunctionDef {
DeclSpec { declaration: Normal(
ty: Int, NormalDecl {
attrs: DeclAttr { decl_spec: DeclSpec {
is_extern: true, ty: Int,
is_static: false, attrs: DeclAttr {
is_thread_local: true, is_extern: true,
is_static: false,
is_thread_local: true,
},
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: WithParams {
ident: (
"uwu",
35..38,
),
params: [],
},
pointer: false,
},
init: None,
},
35..38,
),
],
}, },
}, ),
1..34, body: [],
), },
declarator: ( ),
"uwu",
35..38,
),
declaration_list: List(
[],
),
body: [],
},
1..43, 1..43,
), ),
) )

View file

@ -4,27 +4,41 @@ expression: parsed
--- ---
Ok( Ok(
( (
FunctionDefinition { FunctionDef(
decl_spec: ( FunctionDef {
DeclSpec { declaration: Normal(
ty: Void, NormalDecl {
attrs: DeclAttr { decl_spec: DeclSpec {
is_extern: false, ty: Void,
is_static: false, attrs: DeclAttr {
is_thread_local: false, is_extern: false,
is_static: false,
is_thread_local: false,
},
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: WithParams {
ident: (
"uwu",
6..9,
),
params: [],
},
pointer: false,
},
init: None,
},
6..9,
),
],
}, },
}, ),
1..5, body: [],
), },
declarator: ( ),
"uwu",
6..9,
),
declaration_list: List(
[],
),
body: [],
},
1..14, 1..14,
), ),
) )