mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-17 01:55:07 +01:00
i declare victory (not)
This commit is contained in:
parent
3576ccef01
commit
908c5c7615
5 changed files with 93 additions and 27 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1 +1,3 @@
|
||||||
/target
|
/target
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
|
@ -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<()>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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!()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue