mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-14 16:45:07 +01:00
lmao what
This commit is contained in:
parent
2e5dfb24e2
commit
eb68c2b207
6 changed files with 221 additions and 4 deletions
25
parser/src/ast.rs
Normal file
25
parser/src/ast.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use dbg_pls::DebugPls;
|
||||
|
||||
use crate::Span;
|
||||
|
||||
pub type Spanned<T> = (T, Span);
|
||||
|
||||
#[derive(Debug, DebugPls)]
|
||||
pub enum TypeSpecifier {
|
||||
Void,
|
||||
Char,
|
||||
Short,
|
||||
Int,
|
||||
Long,
|
||||
Float,
|
||||
Double,
|
||||
Signed,
|
||||
Unsigned,
|
||||
Bool,
|
||||
Complex,
|
||||
// TODO
|
||||
// atomic-type-specifier
|
||||
// struct-or-union-specifier
|
||||
// enum-specifier
|
||||
// typedef-name
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#![allow(dead_code)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod ast;
|
||||
mod parser;
|
||||
mod pre;
|
||||
mod token;
|
||||
|
||||
|
|
|
|||
59
parser/src/parser.rs
Normal file
59
parser/src/parser.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
use peekmore::PeekMoreIterator;
|
||||
|
||||
use crate::{
|
||||
ast::{Spanned, TypeSpecifier},
|
||||
token::{Keyword as Kw, Token as Tok},
|
||||
Span,
|
||||
};
|
||||
|
||||
struct ParserError {
|
||||
span: Span,
|
||||
message: String,
|
||||
}
|
||||
|
||||
impl ParserError {
|
||||
fn new(span: Span, message: String) -> Self {
|
||||
Self { span, message }
|
||||
}
|
||||
|
||||
fn eof() -> Self {
|
||||
Self::new(0..0, "unexpected end of file".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
type Result<T, E = ParserError> = std::result::Result<T, E>;
|
||||
|
||||
struct Parser<'src, I>
|
||||
where
|
||||
I: Iterator<Item = (Tok<'src>, Span)>,
|
||||
{
|
||||
lex: PeekMoreIterator<I>,
|
||||
}
|
||||
|
||||
impl<'src, I> Parser<'src, I>
|
||||
where
|
||||
I: Iterator<Item = (Tok<'src>, Span)>,
|
||||
{
|
||||
fn type_specifier(&mut self) -> Result<Spanned<TypeSpecifier>> {
|
||||
let (token, span) = self.next_t()?;
|
||||
let ty = match token {
|
||||
Tok::Kw(Kw::Void) => TypeSpecifier::Void,
|
||||
Tok::Kw(Kw::Char) => TypeSpecifier::Char,
|
||||
Tok::Kw(Kw::Short) => TypeSpecifier::Short,
|
||||
Tok::Kw(Kw::Int) => TypeSpecifier::Int,
|
||||
Tok::Kw(Kw::Long) => TypeSpecifier::Long,
|
||||
Tok::Kw(Kw::Float) => TypeSpecifier::Float,
|
||||
Tok::Kw(Kw::Double) => TypeSpecifier::Double,
|
||||
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 => 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
//!
|
||||
//! Code might be bad. Possibly.
|
||||
|
||||
use std::ops::Not;
|
||||
use std::{ops::Not, fmt::Display};
|
||||
|
||||
use peekmore::PeekMore;
|
||||
|
||||
|
|
@ -119,6 +119,60 @@ pub enum Punctuator {
|
|||
HashHash,
|
||||
}
|
||||
|
||||
impl Display for Punctuator {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Punctuator::BracketOpen => f.write_str("["),
|
||||
Punctuator::BracketClose => f.write_str("]"),
|
||||
Punctuator::ParenOpen => f.write_str("("),
|
||||
Punctuator::ParenClose => f.write_str(")"),
|
||||
Punctuator::BraceOpen => f.write_str("{"),
|
||||
Punctuator::BraceClose => f.write_str("}"),
|
||||
Punctuator::Dot => f.write_str("."),
|
||||
Punctuator::Arrow => f.write_str("->"),
|
||||
Punctuator::PlusPlus => f.write_str("++"),
|
||||
Punctuator::MinusMinus => f.write_str("--"),
|
||||
Punctuator::Ampersand => f.write_str("&"),
|
||||
Punctuator::Asterisk => f.write_str("*"),
|
||||
Punctuator::Plus => f.write_str("+"),
|
||||
Punctuator::Minus => f.write_str("-"),
|
||||
Punctuator::Tilde => f.write_str("~"),
|
||||
Punctuator::Bang => f.write_str("!"),
|
||||
Punctuator::Percent => f.write_str("%"),
|
||||
Punctuator::LeftLeftChevron => f.write_str("<<"),
|
||||
Punctuator::RightRightChevron => f.write_str(">>"),
|
||||
Punctuator::LeftChevron => f.write_str("<"),
|
||||
Punctuator::RightChevron => f.write_str(">"),
|
||||
Punctuator::LeftChevronEq => f.write_str("<="),
|
||||
Punctuator::RightChevronEq => f.write_str(">="),
|
||||
Punctuator::EqEq => f.write_str("=="),
|
||||
Punctuator::BangEq => f.write_str("!="),
|
||||
Punctuator::Caret => f.write_str("^"),
|
||||
Punctuator::Pipe => f.write_str("|"),
|
||||
Punctuator::AmpersandAmpersand => f.write_str("&&"),
|
||||
Punctuator::PipePipe => f.write_str("||"),
|
||||
Punctuator::QuestionMark => f.write_str("?"),
|
||||
Punctuator::Colon => f.write_str(":"),
|
||||
Punctuator::Semicolon => f.write_str(";"),
|
||||
Punctuator::DotDotDot => f.write_str("..."),
|
||||
Punctuator::Eq => f.write_str("="),
|
||||
Punctuator::AsteriskEq => f.write_str("*="),
|
||||
Punctuator::SlashEq => f.write_str("/="),
|
||||
Punctuator::PercentEq => f.write_str("%="),
|
||||
Punctuator::PlusEq => f.write_str("+="),
|
||||
Punctuator::MinusEq => f.write_str("-="),
|
||||
Punctuator::LeftLeftChevronEq => f.write_str("<<="),
|
||||
Punctuator::RightRightChevronEq => f.write_str(">>="),
|
||||
Punctuator::AmspersandEq => f.write_str("&="),
|
||||
Punctuator::CaretEq => f.write_str("^="),
|
||||
Punctuator::PipeEq => f.write_str("|="),
|
||||
Punctuator::Comma => f.write_str(","),
|
||||
Punctuator::Hash => f.write_str("#"),
|
||||
Punctuator::HashHash => f.write_str("##"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PLexer<'src, I>
|
||||
where
|
||||
I: Iterator<Item = (usize, u8)>,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use crate::{
|
||||
pre::{PToken, Punctuator},
|
||||
Span,
|
||||
|
|
@ -11,7 +13,7 @@ use crate::{
|
|||
/// punctuator
|
||||
#[derive(Debug)]
|
||||
pub enum Token<'src> {
|
||||
Keyword(Keyword),
|
||||
Kw(Keyword),
|
||||
Identifier(&'src str),
|
||||
Constant(Constant),
|
||||
StringLiteral(&'src str),
|
||||
|
|
@ -137,7 +139,7 @@ pub fn pre_tokens_to_tokens<'src>(
|
|||
let token = match token {
|
||||
PToken::HeaderName(_) => todo!("header names aren't real, wake up"),
|
||||
PToken::Identifier(ident) => match ident_to_keyword(ident) {
|
||||
Some(keyword) => Token::Keyword(keyword),
|
||||
Some(keyword) => Token::Kw(keyword),
|
||||
None => Token::Identifier(ident),
|
||||
},
|
||||
PToken::PpNumber(number) => pp_number_to_constant(number)
|
||||
|
|
@ -153,6 +155,80 @@ pub fn pre_tokens_to_tokens<'src>(
|
|||
})
|
||||
}
|
||||
|
||||
impl Display for Token<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Token::Kw(kw) => Display::fmt(kw, f),
|
||||
Token::Identifier(ident) => Display::fmt(ident, f),
|
||||
Token::Constant(c) => Display::fmt(c, f),
|
||||
Token::StringLiteral(str) => write!(f, "\"{}\"", str),
|
||||
Token::Punctuator(p) => Display::fmt(p, f),
|
||||
Token::Error => f.write_str("<invalid token>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Keyword {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Keyword::Auto => f.write_str("auto"),
|
||||
Keyword::Break => f.write_str("break"),
|
||||
Keyword::Case => f.write_str("case"),
|
||||
Keyword::Char => f.write_str("char"),
|
||||
Keyword::Const => f.write_str("const"),
|
||||
Keyword::Continue => f.write_str("continue"),
|
||||
Keyword::Default => f.write_str("default"),
|
||||
Keyword::Do => f.write_str("do"),
|
||||
Keyword::Double => f.write_str("double"),
|
||||
Keyword::Else => f.write_str("else"),
|
||||
Keyword::Enum => f.write_str("enum"),
|
||||
Keyword::Extern => f.write_str("extern"),
|
||||
Keyword::Float => f.write_str("float"),
|
||||
Keyword::For => f.write_str("for"),
|
||||
Keyword::Goto => f.write_str("goto"),
|
||||
Keyword::If => f.write_str("if"),
|
||||
Keyword::Inline => f.write_str("inline"),
|
||||
Keyword::Int => f.write_str("int"),
|
||||
Keyword::Long => f.write_str("long"),
|
||||
Keyword::Register => f.write_str("register"),
|
||||
Keyword::Restrict => f.write_str("restrict"),
|
||||
Keyword::Return => f.write_str("return"),
|
||||
Keyword::Short => f.write_str("short"),
|
||||
Keyword::Signed => f.write_str("signed"),
|
||||
Keyword::Sizeof => f.write_str("sizeof"),
|
||||
Keyword::Static => f.write_str("static"),
|
||||
Keyword::Struct => f.write_str("struct"),
|
||||
Keyword::Switch => f.write_str("switch"),
|
||||
Keyword::Typedef => f.write_str("typedef"),
|
||||
Keyword::Union => f.write_str("union"),
|
||||
Keyword::Unsigned => f.write_str("unsigned"),
|
||||
Keyword::Void => f.write_str("void"),
|
||||
Keyword::Volatile => f.write_str("volatile"),
|
||||
Keyword::While => f.write_str("while"),
|
||||
Keyword::Alignas => f.write_str("_Alignas"),
|
||||
Keyword::Alignof => f.write_str("_Alignof"),
|
||||
Keyword::Atomic => f.write_str("_Atomic"),
|
||||
Keyword::Bool => f.write_str("_Bool"),
|
||||
Keyword::Complex => f.write_str("_Complex"),
|
||||
Keyword::Generic => f.write_str("_Generic"),
|
||||
Keyword::Imaginary => f.write_str("_Imaginary"),
|
||||
Keyword::Noreturn => f.write_str("_Noreturn"),
|
||||
Keyword::StaticAssert => f.write_str("_Static_assert"),
|
||||
Keyword::ThreadLocal => f.write_str("_Thread_local"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Constant {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Constant::Int(int) => Display::fmt(int, f),
|
||||
Constant::Float(float) => Display::fmt(float, f),
|
||||
Constant::Char(c) => write!(f, "'{}'", *c as char),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
macro_rules! lex_test {
|
||||
|
|
@ -173,4 +249,4 @@ int main() {
|
|||
"#;
|
||||
lex_test!(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue